Android
Creating Apk
Signing Apk
Whenever you're using a jarsigner, don't rely on its default setting to sign the apk properly. Check google Sign apk page and use the suggested settings by default.
My original script looked like this:
"%jdkbindir%\jarsigner" -verbose ^ -keystore bin\LCLDebugBKKey.keystore -keypass 123456 -storepass 123456 ^ -signedjar bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%-unsigned.apk LCLDebugBKKey
It worked fine on my Android device, but failed on others. What I was missing (per Google's page) is "sigalg" and "digestalg" modifiers:
"%jdkbindir%\jarsigner" -verbose ^ -sigalg SHA1withRSA ^ -digestalg SHA1 ^ -keystore bin\LCLDebugBKKey.keystore -keypass 123456 -storepass 123456 ^ -signedjar bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%-unsigned.apk LCLDebugBKKey
Debugging such issues could be tricky. Since the only thing that a user sees is a message "App Not Installed". A savvy person will not be able to give you log to see packager error. I had to use one of the online Android test services (testdroid) to get the log
Running Apk
C:\android\sdk-windows\platform-tools\adb.exe shell am start -W -n %packagename%/%package activityname%
AdMobs
Admobs come with Google Play Services package. However, .jar file is not easy to find in revisions after 30.
The later revisions come with .aar files (specific to Google Android Studio?) under m2repository directory
androidsdk\extras\google\m2repository\com\google\android\gms\play-services-ads
Why do we have to have so many build systems?!
- The .aar contains "classes.jar" file. The file must be extracted and renamed to "ads.jar" (the name can be different from "ads.jar" but at least not "classes.jar" to prevent name conflicts. Or at least put into a separate directory (to avoid naming conflict as well)
- "play-services-ads" depends on "play-services-base" package. Classes file of ""play-services-base" should also be extracted (and renamed to "base.jar")
- during an Android project compilation from, the step converting Java Jar files are converted to Dex (dalvik format), should also take the both extracted .jar files (Ads and base) into account. The must be included in the final .dex file.
- todo:: there should be a way to avoid that. These .jar file never change, thus, there must be a way to convert them only once. However, .apk file expects "classes.dex" by default (would it be able to use more?)
- .. modify activity to include AdView
- modify AndroidManifest.xml and include ads version meta-data tag. For version 6.5.78 it looks like this:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ... <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> ... <application ... <meta-data android:name="com.google.android.gms.version" android:value="6587000" /> ... </application> </manifest>
JNI
Whenever you want to keep an object reference in Native code, use GetGlobalRef from the object. By default Java passes Local reference. Local reference is INVALID right after the native method ends! GlobalReference however, MUST BE RELEASED! or it leaks. Read more here