I'm having trouble exporting my project to an apk

Hello. So, first of all, I’m running Processing 4.2 on Linux Mint (Ubuntu), using Processing’s Android mode. I want to export my project as an unsigned apk, since I don’t want it on the Google Play store or any third party app store, and just want to install it to my phone and maybe to a few friends’ phone if they need it.

So, from Processing, I selected File → Export Android Project. I then entered the android directory from the sketch folder via the terminal, and typed ./gradlew assembleDebug into the terminal. Then, I got the error message

Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
Caused by: java.lang.ClassNotFoundException: org.gradle.wrapper.GradleWrapperMain

I looked this up, apparently the most likely cause for this is broken gradle files. So I tried regenerating them by running gradle wrapper. And it gave me the error

FAILURE: Build failed with an exception.

* Where:
Build file '/home/chris/sketchbook/Calculator_5_App/android/app/build.gradle' line: 1

* What went wrong:
A problem occurred evaluating project ':app'.
> Failed to apply plugin [id 'com.android.internal.version-check']
   > Minimum supported Gradle version is 7.2. Current version is 4.4.1. If using the gradle wrapper, try editing the distributionUrl in /home/chris/sketchbook/Calculator_5_App/android/gradle/wrapper/gradle-wrapper.properties to gradle-7.2-all.zip

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org


So, to make a long story short, this error message just means I’m expected to be using gradle version 7.2 or higher, even though I only have version 4.4.1. However, no matter how many times I use sudo apt update or sudo apt upgrade (which are commands that tell your system to update all packages that are installed, including gradle), gradle will never upgrade to a version past 4.4.1. So…that’s unfortunate. I read online that you can try manually downloading the newest version of gradle (which is currently 8.1.1) and then do some complicated root user magickery to use that to update it, but it seems very very difficult and I’m not even sure if that’d work because I’m not completely sure that it’s the gradle file that’s broken or something else.

Um, so yeah. I don’t really know what to do here. I’m not sure if it’s broken because it’s Processing for Android and that’s not as well maintained as the main java mode, or if it’s because I’m running it on Linux and the devs mainly focus on the Windows version (which is fair, I’m just glad they have a Linux version at all), or if it’s because I’m just stupid. It’s probably the last one. I couldn’t even figure out I was supposed to use gradlew until I asked ChatGPT for help, despite taking an entire semester of a course where we repeatedly used gradle over and over and over again.

Anyways, if you need any more information, please don’t hesitate to ask. Also, because I’m sure it’ll be helpful, the android folder where I’m typing these commands from contains the files:


and the folders:


The app folder contains files build.gradle and proguard-rules.pro, and folders libs and src.
The wrapper folder contains the single file gradle-wrapper.properties
app/libs contains the files ComplexNumbers.jar and processing-core.jar
app/src contains the folder main, and there’s a big long directory tree structure from there.

If you want more information on said big long directory tree structure, I can give you the output of ls -R, which for those unfamiliar with Linux is a command which recursively shows all files, folders, and files and folders within those folders. Again, sorry if this is a bit of a more complicated issue than you’re used to. I’d post it to stack overflow, except the people on stack overflow are usually pretty mean to me and it gives me anxiety.

Thank you!

1 Like

Not sure that I can help you but I am willing to try. I do have experience using Processing 4 in the Android mode with MacOS operating system. Usually it works ok except that the last version of AndroidMode (version 4.5 ) did not run on my system and required a modified version that I downloaded from here: https://github.com/ajavamind/processing-android-410-api-15

The modification seems to work for both Mac and Windows 11. I have not tried it on a Linux system. There is a gradle warning about not having the correct version, but I have yet to figure out how to update my system and no one seems to be able to offer a solution. Basically I ignore the warning and the Android app runs ok without making any changes.

As far as getting a copy of the app on your Android device this is done automatically every time you run the source code, at least on my tablet and smart phone. I have no experience passing a copy of one of my apps to another device. Some time ago there was a discussion about how to create an apk, but I’m not sure I can dig it out of the archives. You might try a search on this forum.

Just to make sure you are aware, the AndroidMode code is found in the ‘modes’ folder of your Processing app (usually in the Documents folder on a Mac). I have an old Linux box that I rarely use but could also try to reproduce your problem on that system if necessary.

1 Like

Thank you for helping me, trying is really all you can ask of somebody :slight_smile: For the newset version of AndroidMode, android mode still seems to work on my system. But if you think it’d help, just tell me which files to download from that github link as well as what folders to put them in after everything’s unzipped.

As for the gradle version, I could try updating it to version 8, but it seems very very difficult so I wanted to make sure that was actually necessary before attempting it.

I know a copy of the app is put in my android every time I run the code, but when I exit the app, I have to plug my phone back in and recompile it. I personally would like to have my app on the home screen. I’d also like it to have a very specific icon, but one problem at a time. As for passing your app from one device to another, this is done by obtaining it as an apk. That’s really about it, there are probably other ways, but this is the most practical way of doing it. The only discussion I found about doing it on the forums is right here:

At first, it explains how to do it on the Processing app. Which is fine, but it hasn’t been well maintained, and also uses an older version of java and is thus missing certain features (for instance, the ability to use a switch statement on a String). I actually have successfully been able to create an app on there, it’s on my home screen now, but it doesn’t actually put the apk file in my accessible storage, and (promise you won’t laugh at me) my parents won’t let me root my phone. Anyways, later in the post, they explain how to export it on PC. What I took away from it is that you export as Android project, then convert it to an apk “the way you would any other Android application”. I didn’t know how to do that, and all the web sources told me to either use gradlew without telling me what the option I should use was, or to install Android Studio and do it that way. My traumatic experience with Android Studio is the reason I’m using Processing for Android INSTEAD of Android Studio. Please, please do not make me deal with android studio anymore. My little heart can’t take it. Anyways, I asked ChatGPT (which in many ways is like Google, but it talks to you and is probably wrong slightly more often), it told me to enter ./gradlew assembleDebug. I then looked that up and sure enough that seems to be what it’s used for, making an unsigned apk.

As for the last thing…yeah, that’s a problem I noticed recently, the only thing that shows up in the modes folder for me is java. Even though I have Android, Python, and p5 modes supposedly downloaded. I can’t figure out why, but it also doesn’t seem to affect how functional those modes are.

I just tried installing Android mode on Processing 4.1.1 on my Linux System76 box. I did this by using Tools/Manage Tools…/Modes tab. It automatically downloaded AndroidMode 4.5.1 and subsequently the requisite SDK without me doing anything. I then wrote a simple Android app in the Processing editor and ran it in Android mode. I attempted to run the demo on an old Nexus 4 phone. However, I received the same error message that I saw on my Mac and Windows boxes. The error message is shown here:https://github.com/processing/processing-android/issues/729#issuecomment-1578967148

I will next try to use the modified AndroidMode code at the link shown above to see if this will fix the problem.

If you are able to run code in the Android mode on your system I wouldn’t recommend using this fix. Keep what you have. It is unusual that you don’t see the AndroidMode folder in your Documents/Processing/modes folder, but it must be somewhere else on your system.

I don’t think you should have to plug your Android device back into the Linux box and re-run the source code every time you want to use it. Once you run the code a copy should automatically be on your phone and all that is required is a double click to activate it. You should be able to see every app on your device and every Processing demo that you have ever run.

If you know how to extract one of those .tgz files into a location of my choosing please tell me. I presume it’s similar to unzipping a zip file on Windows. On a Mac I don’t have to do any of that. There are Linux users in this forum that we can go to for help if we need to. I’m trying to get my system working so that I can try and reproduce your problem areas. The following link is to a more recent ‘apk’ discussion: https://discourse.processing.org/t/android-2-issues-1-is-it-possible-to-release-aab-2-apk-release-error/33295

There is also a way to get the icon of your choice which we can discuss later.

1 Like

First of all, hats off to you for pulling out the virtual machine to help me out with this. :blush:

Second of all…you know, it’s the weirdest thing. I am an absolute dummy, for some reason I had just assumed if a new app was downloaded, it would appear on my home screen. But after going to my home screen, swiping up, and searching for calculator, that app appeared. Both the one I had made through the Processing app and the one made through USB debugging. So, yeah, I’m happy about that :slight_smile:

I should also note that, while in my Processing 4 sketchbook, the only folder in modes is java, in my Processing 3 sketchbook, the only folders are AndroidMode and PythonMode. I’m not sure if that’s related, however, because I don’t see a folder anywhere for p5 mode.

Also, while waiting for a response, I decided to look into updating gradle. I figured it certainly couldn’t hurt, especially if/when I plan on using gradle again later down the line. I did so by downloading sdkman and using that to update gradle to the version of my choice (8.1.1). So, because I did it that way, it wasn’t too hard. I then used the newer version of gradle to recompile my gradle wrapper files, and it did it in 61 seconds with no errors. I then used ./gradlew assembleDebug, and it failed again, but this time with a different error message:

Downloading https://services.gradle.org/distributions/gradle-8.1.1-bin.zip

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:packageDebug'.
> Could not create task ':app:processDebugResources'.
   > Cannot use @TaskAction annotation on method IncrementalTask.taskAction$gradle_core() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org


Which…I honestly have no idea what any of that means. But hey, at least now it has a main file, right?

I am also curious about how to add an icon of my choice. I saw some info about how to do that on the Processing for Android website, but it didn’t really make much sense.

You should use your own icons for release by creating the files icon-36, 48, 72, 96, 144, and 192 in .PNG format, and placing them in the sketch’s folder before exporting the signed package.

I was so so so very confused by this, I had to read it over several times to even understand what they meant. So like…do they want me to create a different file for each possible screen resolution a phone could have and each possible way the phone could have its home screen laid out, and each number is supposed to represent the width and height of the icon? Because, like, it certainly wouldn’t have hurt to explain that a little. Also, does this only work for signed packages? Because if so, that doesn’t really help me out much :confused:

But yeah, thanks for all the help so far.

The following source code will automatically create the icon set for you. Simply run the code and drag and drop an image file onto the window (I use a .png but others might work) and a folder will appear on your desktop. Inside that folder are all the icon sizes that you need. Copy/paste these into your sketch folder and it will use them for your app. You also need to edit a line of code in the manifest.xml file to give your app a unique name, described here: https://android.processing.org/tutorials/distributing/index.html
The following code hasn’t been published yet so let me know how it works. Don’t forget to set the folder url to your system (replace ‘yourName’ with the correct name for your system). This was written to run on a Mac; it has not been tested on the Linux or Windows operating systems.

import java.awt.*;
import java.awt.dnd.*;
import java.util.List;
import javax.swing.TransferHandler;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;

PFont font;
PImage img;
PImage myimg;
String imgPath = "";
String savePath = "";
String fileName = "";

void setup() {
  size(520, 520);
  surface.setTitle("Icon Maker Android");
  textAlign(CENTER, CENTER);
  text("Drag and drop image here", 0, 100, width, 160);
  Canvas canvas = (Canvas) surface.getNative();
  canvas.setDropTarget(new DropTarget(canvas, DnDConstants.ACTION_COPY_OR_MOVE, new DropTargetListener() {

      public void dragEnter(DropTargetDragEvent dtde) {

      public void dragOver(DropTargetDragEvent dtde) {

      public void dropActionChanged(DropTargetDragEvent dtde) {
      public void dragExit(DropTargetEvent dte) {

      public void drop(DropTargetDropEvent evt) {
      // Accept copy drops
      Transferable transferable = evt.getTransferable();
      // Get the data formats of the dropped item
      DataFlavor[] flavors = transferable.getTransferDataFlavors();
      for (DataFlavor flavor : flavors) {
        try {
          if (flavor.isFlavorJavaFileListType()) {
            // Get all of the dropped files
            List<File> files = new ArrayList<>();
            files = (List)transferable.getTransferData(flavor);
            for (File file : files) {
              imgPath = file.getPath();
              fileName = file.getName();
              // Strip extension if there is one
              if (fileName.indexOf(".") > 0) {
                fileName = fileName.substring(0, fileName.lastIndexOf("."));
              savePath = "/Users/yourName/Desktop/AndroidIcons" + "_" + fileName + "/";
              println("imgPath: " + imgPath);
              img = loadImage(imgPath);
              img.resize(0, 512);
              img.save(savePath + "myimg.png"); // used for display
              img.resize(0, 192);
              img.save(savePath + "icon-192.png");
              img.resize(0, 144);
              img.save(savePath + "icon-144.png");
              img.resize(0, 96);
              img.save(savePath + "icon-96.png");
              img.resize(0, 72);
              img.save(savePath + "icon-72.png");
              img.resize(0, 48);
              img.save(savePath + "icon-48.png");
              img.resize(0, 36);
              img.save(savePath + "icon-36.png");
              myimg = loadImage(savePath + "myimg.png");
        catch (Exception e) {
      evt.dropComplete(true);  // Inform that the drop is complete

void draw() {
  if (myimg != null) {
    image(myimg, 0, 0, width, height);

On Linux savePath needs to be savePath = "/home/yourName/Desktop/AndroidIcons" + "_" + fileName + "/"; if you haven’t already figured that out. Code will run on Linux.

1 Like

I finally got Android mode to work on my Linux system. I had lots of different versions of Processing on my system which complicated matters. I finally wound up trashing most of them in favor of the latest version. There is a feature on System76 to have it automatically install the app for you, however, the outdated gradle warning persisted. I did have to manually point Processing to the Sdk folder which on my system was in an Android folder in the Home directory. Unfortunately the Android mode that was installed (4.5.1) did not work, similar to Mac and Windows. I wound up using the revised version that I alluded to previously. The installation on Linux insisted on placing a folder called ‘sketchbook’ in my Home directory. Inside this folder is a folder called ‘modes’. I downloaded the revised version and copy/pasted it into the modes folder and had it merge/replace all the files. From that point on everything worked correctly and I was able to run an android app without error complete with a custom icon.

This is actually amazing. I love this. I never knew Processing was compatible with drag and drop functionality, I never even considered it as an option! Plus, you didn’t even have to do it that way, you could’ve just told me to put the file in the sketch folder and have it read from there, but you chose to do it this way and I applaud you for it :smiley:

Also, yes, I also had to use the sketchbook/android/sdk trick, I pretty much have to use that every time I reopen Processing in Android mode. I wish I had known you were having the same issue, or I would’ve told you about it. :P

Now upgrade the gradle, find the original gradle, delete the lower version of the gradle, and move the upgraded gradle over.