We have a great build system, so we're not looking to use gradle. Right now, we use appt to build an APK and it works great and the APK runs well. I see that aapt2 is the future, though, and so we'd like to move to it before we're forced to.
What we currently do:
We have a simple icon in res/mipmap/our_icon.png
We have our ./AndroidManifest.xml file
We have our libMyApp.so stored in apk/lib/armeabi-v7a/libMyApp.so
We build using the following command: aapt package -f -M AndroidManifest.xml -S ./res -I /opt/android-sdk/platforms/android-28/android.jar -F my app-unsigned.apk apk/
We then zipalign and sign using apksigner and the app loads just fine. As you can see, all very simple and gives us just what we need.
I've tried the following with aapt2, but of course it is incorrect:
aapt2 compile ./res/mipmap/our_icon.png -o ./compiled
aapt2 link -v -I /opt/android-sdk/platforms/android-28/android.jar -I compiled/mipmap_our_icon.png.flat --manifest AndroidManifest.xml -o MyApp-unsigned.apk
note: including compiled/minmap_our_icon.png.flat.
error: failed to open APK: Invalid file.
You're trying to provide the resources the way you'd provide an APK (e.g. android.jar):
-I compiled/mipmap_our_icon.png.flat
To pass compiled resources use the -R flag (per each resource or use the wildcard * if you want to pass the whole directory, e.g. compiled/*).
You can find more info on differences between aapt and aapt2 in my old answer here.
Related
I am currently compiling a custom recovery for an android phone. Sources are synced, device tree etc. all set up correctly. Now I am facing a rather banal-looking error during build. cp refuses to copy a directory, because -r is not specified in the build file.
I obviously tried to find the build file (rw_recovery/out/build_omni_daisy.ninja) and add the -r argument, but it seems to be regenerated at the beginning of every build process, as the process still fails and the previously changed line appears unchanged when opening the file after the attempted build.
These are the build steps:
. build/envsetup.sh
lunch omni_daisy-eng #config for the device
mka bootimage #device uses boot.img as recovery
This command leaves me with the following error:
[ 99% 6883/6884] Prebuilt (rw_recovery/out/target/product/daisy/kernel)
FAILED: rw_recovery/out/target/product/daisy/kernel
/bin/bash -c "(rm -f /home/luca/rw_recovery/out/target/product/daisy/kernel) && (cp rw_recovery/out/target/product/daisy/obj/KERNEL_OBJ/arch/arm64/boot/ rw_recovery/out/target/product/daisy/kernel )"
cp: -r not specified; omitting directory 'rw_recovery/out/target/product/daisy/obj/KERNEL_OBJ/arch/arm64/boot/'
ninja: build stopped: subcommand failed.
17:13:06 ninja failed with: exit status 1
I would love to hear any suggestions about how to force ninja to execute the command with -r. Alternatively, suggestions about where to find the file from which the above mentioned build file is recreated after executing mka command are much welcomed as well.
I have a simple android project.
This commands compile resources and build apk without dex:
aapt2 compile project/res/values/strings.xml project/res/layout/activity_main.xml -o project/compiled_res
aapt2 link -o project/apk/unsigned_app.apk -I sdk/platforms/android-28/android.jar --manifest project/src/AndroidManifest.xml -R project/compiled_res/*.flat --java project/src --auto-add-overlay
Quote from documentation:
However, the generated APK does not contain DEX bytecode and is
unsigned
...
you can use other command line tools, such as d8 to
compile Java bytecode into DEX bytecode and apksigner to sign your
APK.
Ok. I can:
d8 project/compiled_classes/com/illuzor/buildtest/*.class --output project/dex
But how to pack this dex to apk? aapt2 can`t recognize classes.dex:
I can just add classes.dex to my apk by zipping:
zip -uj project/apk/unsigned_app.apk project/dex/classes.dex
And it works after aligning and signing. But must be another way, more proper.
I'm looking for a proper way too. But I have no luck even it is 2019 now, and I searched everywhere, for days.
I guess aapt add will get the job done, but your solution with zip is not bad.
Hope aapt won't be deprecated soon, or aapt2 should get enhanced before that happens.
In native android development I could check whether my minifyEnabled had taken effect.
I used this script (in linux) which allows me to extract the apk and view the java files to see if my code is readable, or has been obfuscated :
#! /bin/bash
d2j=/work/installs/dex2jar-2.0
jdgui=/work/installs/jd-gui-1.4.0.jar
apk_loc=/work/projects/my_app/build/app/outputs/app-release.apk
mkdir -p /work/tmp/dex
rm -rf /work/tmp/dex/*
cd /work/tmp
cp $apk_loc ./app-release.zip
unzip app-release.zip -d dex
cd dex
chmod +x $d2j/*.sh
$d2j/d2j-dex2jar.sh classes.dex
java -jar $jdgui classes-dex2jar.jar
If I use this script on a flutter apk, I don't see any files containing anything related to my original code.
Flutter's dart code is compiled to native and embedded to flutter.so runtime, so decompiling flutter is not as easy as byte code of java/kotlin
However decompiling .so file is possible. You can use the toolchains inside the android ndk to perform the type of disassembling you want to
./android-ndk-r15b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-objdump -T "flutter.so | less
but this is just give you an objdump.
from this link i had use multi language support in my Android Project, Yesterday i decided to switch to Intellij Idea gradle, when i remove value files in different language, app run normally with default language
but with multi string value file get this error
Error:Gradle: Execution failed for task ':...:processDebugResources'.
com.android.ide.common.internal.LoggedErrorException: Failed to run command:
/home/.../sdk/build-tools/android-4.4.2/aapt package -f --no-crunch -I
/home/.../sdk/platforms/android-19/android.jar -M
/home/.../.../build/manifests/debug/AndroidManifest.xml -S
/home/.../.../build/res/all/debug -A
/home/.../.../build/assets/debug -m -J /home/.../.../build/source/r/debug -F
/home/.../.../build/libs/...-debug.ap_ --debug-mode --custom-package ... --output-text-symbols /home/.../build/symbols/debug
Error Code:
1
Output:
/home/.../build/res/all/debug/values-Ar/values.xml: error: Duplicate file.
/home/.../build/res/all/debug/values/values.xml: Original is here.
Your problem seems to be with naming conventions.
The main problem with the structure you're using is that you used a capital letter.
In android file structure in res folder should always be in lowercase.
instead of
values-Ar
you should use
values-ar
for your values folder if you want an arabic locale to find your strings,values ...
I have a kind of strange issue. In my bash script or Makefile, using aapt with absolute path does not work but if I am in the local directory it does.
If I do the following, it does not work:
aapt add $OUT/device.jar $OUT/classes.dex
The command does run and print this output:
'/homes/rsevile/CS307/bin/Device/classes.dex'...
But when trying to load the jar, the class that I am trying to load end up being not found.
The following does work though:
cd $OUT
aapt add device.jar classes.dex
Printing:
'classes.dex'...
This is the whole code being executed in the script (which works):
javac -d $(OUT)/classes -classpath ./layoutlib.jar src/com/device/client/*.java
jar cf $(OUT)/device.jar $(OUT)/classes $(OUT)/layoutlib
dx --dex --no-strict --output=$OUT/classes.dex $OUT/device.jar
cd $OUT
aapt add device.jar classes.dex
cd $ROOT
adb push $OUT/device.jar $ANDROID_OUT_DIR
I am confused why my class ends up being not found when using an absolute path with aapt.
Could anyone please explain to me why it is not working and how I could fix it to use a proper absolute path please?
Thank you.
I realized that aapt actually keeps the absolute path, there is no way around it.
I fixed the problem by reusing jar and using the -C option that lets me specify a directory.