Android 2024
I'm working on a new template for Android, so we can test projectGenerator building projects like in @tctr fork. Related thread: https://forum.openframeworks.cc/t/android-support/41968/8
First thing:
@tctr is it possible to keep the same folder depth for the cpp files? like emptyExample/src instead of emptyExample/src/main/cpp ?
As I don't have any way of testing the build, it would be great if you could indicate which changes PG should do in the template, like replacing applicationId "cc.openframeworks.androidEmptyExample" in a specific file
I'm not a specialist of gradle so I tried removing the main folder layer... and it works as shown on the branch without_main on my repo.
That being said, it seems that an app/src/main folder structure is very common and it's for a reason that @danoli took it.
There are some explanations in https://www.baeldung.com/gradle-source-sets
Several subfolders are used for different flavours or customisation of the same app :
We find the same folder structure for a gradle project in https://stackoverflow.com/questions/31518622/how-to-use-multiple-res-srcdirs-and-override-some-resources-with-gradle
Last but not least, the oboe android library (Google) follows the same architecture :
So, I'm really convinced we should keep it as it is. It seems that it makes sense for Android projects.
Thank you I'll be adding the template folder now, from this files what we should not add to the project template? I mean if there is something generated locally. gitignore is trying to ignore this two folders
scripts/templates/android2024/gradle
scripts/templates/android2024/local.properties
and here is the entire list
d@zen android2024 % ls -alfR
total 56
drwxr-xr-x 10 d staff 320 May 22 18:19 .
drwxr-xr-x 32 d staff 1024 May 18 19:37 ..
-rw-r--r--@ 1 d staff 6148 May 22 18:19 .DS_Store
-rw-r--r-- 1 d staff 348 May 14 12:15 local.properties
drwxr-xr-x 3 d staff 96 May 14 12:15 gradle
drwxr-xr-x 6 d staff 192 May 14 12:15 ofApp
-rw-r--r-- 1 d staff 404 May 14 12:15 build.gradle
-rw-r--r-- 1 d staff 306 May 14 12:15 gradle.properties
-rw-r--r-- 1 d staff 2234 May 14 12:15 proguard.cfg
-rw-r--r-- 1 d staff 466 May 14 12:15 settings.gradle
./gradle:
total 0
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 10 d staff 320 May 22 18:19 ..
drwxr-xr-x 4 d staff 128 May 14 12:15 wrapper
./gradle/wrapper:
total 120
drwxr-xr-x 4 d staff 128 May 14 12:15 .
drwxr-xr-x 3 d staff 96 May 14 12:15 ..
-rw-r--r-- 1 d staff 53636 May 14 12:15 gradle-wrapper.jar
-rw-r--r-- 1 d staff 231 May 14 12:15 gradle-wrapper.properties
./ofApp:
total 40
drwxr-xr-x 6 d staff 192 May 14 12:15 .
drwxr-xr-x 10 d staff 320 May 22 18:19 ..
-rw-r--r-- 1 d staff 4783 May 14 12:15 proguard-rules.pro
-rw-r--r-- 1 d staff 5787 May 14 12:15 build.gradle
-rw-r--r-- 1 d staff 451 May 14 12:15 gradle.properties
drwxr-xr-x 3 d staff 96 May 14 12:15 src
./ofApp/src:
total 0
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 6 d staff 192 May 14 12:15 ..
drwxr-xr-x 7 d staff 224 May 14 12:15 main
./ofApp/src/main:
total 64
drwxr-xr-x 7 d staff 224 May 14 12:15 .
drwxr-xr-x 3 d staff 96 May 14 12:15 ..
drwxr-xr-x 17 d staff 544 May 14 12:15 res
-rw-r--r-- 1 d staff 3633 May 14 12:15 AndroidManifest.xml
drwxr-xr-x 3 d staff 96 May 14 12:15 java
-rw-r--r-- 1 d staff 25952 May 14 12:15 ic_launcher-playstore.png
drwxr-xr-x 6 d staff 192 May 14 12:15 cpp
./ofApp/src/main/res:
total 0
drwxr-xr-x 17 d staff 544 May 14 12:15 .
drwxr-xr-x 7 d staff 224 May 14 12:15 ..
drwxr-xr-x 5 d staff 160 May 14 12:15 mipmap-mdpi
drwxr-xr-x 4 d staff 128 May 14 12:15 values-v11
drwxr-xr-x 5 d staff 160 May 14 12:15 mipmap-hdpi
drwxr-xr-x 3 d staff 96 May 14 12:15 drawable
drwxr-xr-x 5 d staff 160 May 14 12:15 mipmap-xxxhdpi
drwxr-xr-x 3 d staff 96 May 14 12:15 layout
drwxr-xr-x 5 d staff 160 May 14 12:15 mipmap-xxhdpi
drwxr-xr-x 5 d staff 160 May 14 12:15 values
drwxr-xr-x 3 d staff 96 May 14 12:15 drawable-xhdpi
drwxr-xr-x 4 d staff 128 May 14 12:15 values-v14
drwxr-xr-x 3 d staff 96 May 14 12:15 drawable-hdpi
drwxr-xr-x 3 d staff 96 May 14 12:15 menu
drwxr-xr-x 3 d staff 96 May 14 12:15 drawable-mdpi
drwxr-xr-x 5 d staff 160 May 14 12:15 mipmap-xhdpi
drwxr-xr-x 4 d staff 128 May 14 12:15 mipmap-anydpi-v26
./ofApp/src/main/res/mipmap-mdpi:
total 24
drwxr-xr-x 5 d staff 160 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 1328 May 14 12:15 ic_launcher_foreground.png
-rw-r--r-- 1 d staff 1168 May 14 12:15 ic_launcher.png
-rw-r--r-- 1 d staff 2228 May 14 12:15 ic_launcher_round.png
./ofApp/src/main/res/values-v11:
total 16
drwxr-xr-x 4 d staff 128 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 341 May 14 12:15 styles.xml
-rw-r--r-- 1 d staff 157 May 14 12:15 strings.xml
./ofApp/src/main/res/mipmap-hdpi:
total 24
drwxr-xr-x 5 d staff 160 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 2212 May 14 12:15 ic_launcher_foreground.png
-rw-r--r-- 1 d staff 1650 May 14 12:15 ic_launcher.png
-rw-r--r-- 1 d staff 3557 May 14 12:15 ic_launcher_round.png
./ofApp/src/main/res/drawable:
total 8
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 2587 May 14 12:15 icon.png
./ofApp/src/main/res/mipmap-xxxhdpi:
total 72
drwxr-xr-x 5 d staff 160 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 10038 May 14 12:15 ic_launcher_foreground.png
-rw-r--r-- 1 d staff 5436 May 14 12:15 ic_launcher.png
-rw-r--r-- 1 d staff 12659 May 14 12:15 ic_launcher_round.png
./ofApp/src/main/res/layout:
total 8
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 904 May 14 12:15 main_layout.xml
./ofApp/src/main/res/mipmap-xxhdpi:
total 48
drwxr-xr-x 5 d staff 160 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 6138 May 14 12:15 ic_launcher_foreground.png
-rw-r--r-- 1 d staff 3760 May 14 12:15 ic_launcher.png
-rw-r--r-- 1 d staff 8411 May 14 12:15 ic_launcher_round.png
./ofApp/src/main/res/values:
total 24
drwxr-xr-x 5 d staff 160 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 702 May 14 12:15 styles.xml
-rw-r--r-- 1 d staff 157 May 14 12:15 strings.xml
-rw-r--r-- 1 d staff 120 May 14 12:15 ic_launcher_background.xml
./ofApp/src/main/res/drawable-xhdpi:
total 8
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 2587 May 14 12:15 icon.png
./ofApp/src/main/res/values-v14:
total 16
drwxr-xr-x 4 d staff 128 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 384 May 14 12:15 styles.xml
-rw-r--r-- 1 d staff 157 May 14 12:15 strings.xml
./ofApp/src/main/res/drawable-hdpi:
total 8
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 2587 May 14 12:15 icon.png
./ofApp/src/main/res/menu:
total 8
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 212 May 14 12:15 main_layout.xml
./ofApp/src/main/res/drawable-mdpi:
total 8
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 2587 May 14 12:15 icon.png
./ofApp/src/main/res/mipmap-xhdpi:
total 32
drwxr-xr-x 5 d staff 160 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 3207 May 14 12:15 ic_launcher_foreground.png
-rw-r--r-- 1 d staff 2316 May 14 12:15 ic_launcher.png
-rw-r--r-- 1 d staff 5158 May 14 12:15 ic_launcher_round.png
./ofApp/src/main/res/mipmap-anydpi-v26:
total 16
drwxr-xr-x 4 d staff 128 May 14 12:15 .
drwxr-xr-x 17 d staff 544 May 14 12:15 ..
-rw-r--r-- 1 d staff 265 May 14 12:15 ic_launcher.xml
-rw-r--r-- 1 d staff 265 May 14 12:15 ic_launcher_round.xml
./ofApp/src/main/java:
total 0
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 7 d staff 224 May 14 12:15 ..
drwxr-xr-x 3 d staff 96 May 14 12:15 cc
./ofApp/src/main/java/cc:
total 0
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 3 d staff 96 May 14 12:15 ..
drwxr-xr-x 3 d staff 96 May 14 12:15 openframeworks
./ofApp/src/main/java/cc/openframeworks:
total 0
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 3 d staff 96 May 14 12:15 ..
drwxr-xr-x 3 d staff 96 May 14 12:15 android
./ofApp/src/main/java/cc/openframeworks/android:
total 16
drwxr-xr-x 3 d staff 96 May 14 12:15 .
drwxr-xr-x 3 d staff 96 May 14 12:15 ..
-rw-r--r-- 1 d staff 6380 May 14 12:15 OFActivity.java
./ofApp/src/main/cpp:
total 40
drwxr-xr-x 6 d staff 192 May 14 12:15 .
drwxr-xr-x 7 d staff 224 May 14 12:15 ..
-rw-r--r-- 1 d staff 5364 May 14 12:15 CMakeLists.txt
-rw-r--r--@ 1 d staff 2576 May 22 18:18 ofApp.cpp
-rw-r--r-- 1 d staff 925 May 14 12:15 ofApp.h
-rw-r--r-- 1 d staff 1163 May 14 12:15 main.cpp
Found more information here : https://developer.android.com/build
By default Android Studio creates this structure when creating a new project :
I tried it myself and got this :
There are 3 folders main, Android_test and test corresponding to different versions of the app.
No cpp folders : adding c++ is not your average Android project
Thank you I'll be adding the template folder now, from this files what we should not add to the project template? I mean if there is something generated locally. gitignore is trying to ignore this two folders
scripts/templates/android2024/gradle scripts/templates/android2024/local.properties
Hi Dimitre,
we should definitely keep the gradle folder and exclude local.properties
The .gitignore that is generated by the Android Studio template keeps gradle :
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
3 Points :
1. No need of gradle folder and Bradley under ofApp Working with the Android Studio template, I realised that the project should be opened at the project level (eg : androidEmptyExample) and not at the module level (ofApp).
In this case, there's no gradle folder and gradlew files that are added under ofApp, and it still works.
I have modified on my last commit on Android_fixes_thierry main branch the script that generates the project folder structure accordingly, and I will also modify the other examples that I have committed so far to check that this works correctly.
2. Complexity of CMakeLists.txt vary especially with Adonis I have used the ofxSoundObject and ofxAudioFile addons in the apps/android/ambientApp and I'm currently working on another example with this addon. I have managed to compile them by adding in the CMakeLists.txt and it works. At the moment all the files paths are manually added but that will probably be quicker using GLOB_RECURSE. With that, the modification of the CMakeLists will be more straightforward.
That being said for ofxSoundObject I also had to change the OpenGL lib that is linked (going from GLES2 to GLES1 to get a definition for glPointSize).
=> it seems the modifications of the CMakeList.txt may be difficult to fully automate.
3. Checking differences in of v11.2 Android examples
-
AndroidManifest.xml :
- the permissions may change for the camera, the audio input and outputs, and the vibrator
- it's possible to have several activities declared as in androidJavaOnlyActivityExample
-
Java Sources => generally only the name changes but there are some differences in :
- androidJavaOnlyActivityExample with two java activities
- androidMultiOFActivitiesExample with two java activities
-
Res => generally only the name changes but there are some differences in :
- androidJavaOnlyActivityExample : 2 layouts because of 2 java activities
-
bin : different kind of font, audio & video files
For each example it's probably better to store for each example the files in :
- Java
- Res
- CPP with both the .cpp .h files AND CMakeLists.txt
- bin
And automate from there ?
Thierry
Great. My suggestion is you make a PR similar to this one https://github.com/openframeworks/openFrameworks/pull/7991 with the needed files for projectgenerator. in this PR I've did two things: removed the code from ofApp.cpp to start with a blank setup, draw etc. and replaced identifier to cc.openFrameworks.emptyExample
Ok, I've just merged the first versino of PG android2024 template it can be used now like this (Backup your project files before trying):
../../../apps/pgd/commandLine/bin/projectGenerator.app/Contents/MacOS/projectGenerator -o"../../.." -p"android2024" .
For now it is only changing cc.openframeworks.emptyExample. maybe there is more stuff to change in .java files or in other places, let me know.
Added the missing files to the template and merged in openFrameworks master https://github.com/openframeworks/openFrameworks/pull/7991
Great ! I will check this in the next few days
Hi Dimitre,
I had troubles to generate the projectGenerator apps straight with the instructions given (with setup_environment and build_command, so I moved to the legacy instructions which include downloading the OSX libs. That works and I can use a command similar to yours ./../../apps/projectGenerator/commandLine/bin/commandLine.app/Contents/MacOS/commandLine -o"../../.." -p"android2024" .
Then the result I get is the following :
[notice ] PG v.35
[ error ] there is no src folder in this project path to update, maybe use create instead? (or use force to force updating)
[notice ] in 0.00129003 seconds
With the legacy way of creating the PG app, it is necessary to download the OSX libs bc otherwise some libs are lacking like Glew. The problem is that doing that changes a lot of the includes which differ between the android and osx libs (see the attached file). So finally the folder hierarchy is different for he libs and the OF libs is just built for OSX.
So I ended to download the packaged version for macosx and I use android2024 in templates and Iget an empty project for OSX.
Thierry
OK I think you need to update PG, it was changed internally to handle android template files.
you can clone and compile, it should display PG v.38
OK I think you need to update PG, it was changed internally to handle android template files. you can clone and compile, it should display
PG v.38
Indeed I had forgotten to checkout to the last commits.
This time, I've managed to go through the process to build PG and it seems I've got the right version.
It seems that it's the Android template folder that is used though, and not the Android2024 ?
Here is my output :
[notice ] PG v.38
[notice ] -----------------------------------------------
[notice ] target platform is: android
[notice ] setting OF path to: "../../.."
[notice ] from -o option
[notice ] project path is: "/Users/thierry/Dev/openframeWorksNew/examples/android/androidCameraExample"
[notice ] using additional template android2024
[notice ] setting up new project "/Users/thierry/Dev/openframeWorksNew/examples/android/androidCameraExample"
[notice ] updating project "/Users/thierry/Dev/openframeWorksNew/examples/android/androidCameraExample"
[warning] Cannot find android2024 using platform template only
[notice ] saving addons.make
[notice ] project updated!
[notice ] -----------------------------------------------
1 project created [notice ] in 0.0116348 seconds
(command used: /Users/thierry/Dev/openframeWorksNew/apps/projectGenerator/frontend/dist/mac/projectGenerator.app/Contents/Resources/app/app/projectGenerator -v -o"/Users/thierry/Dev/openframeWorksNew" -a" " -p"android" -t"android2024" "/Users/thierry/Dev/openframeWorksNew/examples/android/androidCameraExample")
and my PG :
Maybe I don't use PG in the right way ?
Thierry
Ah ok. you will have to use only the commandLine for now, because the way it is programmed now you will have to pass "android2024" as a platform and not template. This is provisory, try it out
ok done ! There are a few things lacking and one thing (config.cmake) not belonging to the project. The original src can probably be erased too (or it's making too much hassle with git) ?
IO've highlighted them in the following figure.
Otherwise, great job ! It's a good starting point.
Nice. I'll be updating PG. I've inspected the folder example/androidEmptyExample and there is this difference: examples there have the folder "src" immediatly inside the project folder, your template it is inside ofApp/src/main/cpp I wonder if PG should copy from different depths. cc: @danoli3
Not sure I understand what you mean.
It makes sense for me to have a standard initial example project with cpp and .h source files under projectFolder/src then having the hierarchy ofApp/src/main/cpp after project generation. This hierarchy just complies to a standard Android Studio project. Here is what you get when you create the Android Studio Cpp Native App :
This is exactly this hierarchy.
what you see in my repo is this hierarchy that I recreated manually for the examples that I have treated.
Now there are still questions arising for examples which are a little bit more tricky than the emptyExample and don't use the standard :
- CMakeLists.txt
- Java sources
- AndroidManifest.xml
- res
- addons
If you have a look at the current version of OF you will see that when there differences between a project and the emptyExample, the corresponding files are present in the initial sources. Here is a comparison of emptyExample and JavaOnlyActivityExample (2 java activities instead of 1, each with their own layout + 1 data file) :
Does it make sense ?
cc:@danoli3
It does. I will still rather wait to hear more opinions on this. As it complies to a standard Android project it doesn't to OF standard, so there is a dilemma there. and androidExamples (not only template) uses a OF standard "src" folder.
Design wise I think we should not move the user "src" folder using PG. User personal code is a delicate thing and we should not move or touch this folder.
if we decide it is better to follow Android Standard, my suggestion would be moving "src" files from all examples to the final src folder.
OK, hoping that these opinions will be completed by actual testing !
The Depths of folders goes deep, but it need not worry too much as whatever file structure as long as its linked in the cmakelist correctly via the projectGenerator
The main issue I was having was the Build Gradle and Sub Gradle projects Th was solved with project structure main/sub
def CPP_SOURCE = './src/main/cpp'
externalNativeBuild {
if (!project.hasProperty("ndkBuild")) {
cmake {
path "${CPP_SOURCE}/CMakeLists.txt"
version '3.22.1'
}
} else {
ndkBuild {
path "${CPP_SOURCE}/Android.mk"
}
}
}
```
The java side is definitely going to need to folder structure as defined however could be good idea test if we can get it to /src/ dir.
Yeah might be a projectGenerator thing, but I think then PG is going to need to be able to call scripts
it need not worry too much as whatever file structure as long as its linked in the cmakelist correctly via the projectGenerator
ok
The java side is definitely going to need to folder structure
Actually it's already like in the previous version of OF for the androidJavaOnlyActivity example for instance :
(base) Thierrys-MBP:openframeWorksNew thierry$ tree examples/android/androidJavaOnlyActivityExample/
examples/android/androidJavaOnlyActivityExample/
├── addons.make
├── bin
│ └── data
│ └── frabk.ttf
├── res
│ └── layout
│ ├── first_activity.xml
│ └── main_layout.xml
├── src
│ ├── main.cpp
│ ├── ofApp.cpp
│ └── ofApp.h
└── srcJava
└── cc
└── openframeworks
└── androidNativeActivityExample
├── FirstActivity.java
└── OFActivity.java
10 directories, 9 files
but I think then PG is going to need to be able to call scripts
I know nothing about PG tbh.
That's great. for me the other files doens't matter as long as "src" folder is directly inside project folder. one more advantage is you can be working in the same software for android and linux using the same folder and some simple ifdefs.
Sweet okay finally lets get this one working