Looks like Android is in, so, here's a quick rundown on how to sign apk files for Android in regards to GLBasic:-
1) First, build you app for Android
2) Create a folder called "keytools" and make a folder in that called "keys" (I create the keytools folder in my root GLBasic project folder)
3) Navigate to your {App_Project_Root}/android/bin directory and copy the file glbasic-debug.apk to your keytools folder
The glbasic-debug.apk file has already been signed with a default key, which is no good when releasing stuff on the Android Market (It wont be accepted), so, we need to remove the debug key and add our own
4) To unsign it, we need to remove a few files from the apk package, the apk file is just a zip file really, so, you need to explore the package using a archive utility, I use 7-zip.
5) When exploring the package, there is a folder in the root of the package called 'META-INF', go into that folder and there should be three files... MANIFEST.MF, CERT.SF and CERT.RSA... Remove these three files and your package will be unsigned.
6) Open command prompt (cmd.exe)
7) Navigate to your keytools folder
8} Type the following (Make sure your Java paths are correct, if not, use whole paths to the Java tools used below):-
9)keytool -genkey -alias mykey.keystore -keyalg RSA -validity 20000 -keystore keys/mykey.keystore
Then following the questions...
10) Type the following: jarsigner -verbose -keystore keys/mykey.keystore -signedjar glbasic-signed.apk glbasic-debug.apk mykey.keystore
11) You apk file should now be correctly signed.
Dabz
Original instructions provided by therevills here: http://www.indiecodez.com/forum/index.php/topic,109.0.html, and I just updated them for GLBasic! :)
you can read the full instuctions on android sdk page.
anyone could write a simple tool for signing in windows?
Well, they could, but you only need one key, it only takes 2 mins to sign an app using the command line too, so no need for additional tools imo!
Even better still you could get Ant to do the grunt when building, but, its horses for courses really.
Dabz
Easiest way would be do put that in a batch file
One thing you did forget to mention is that they signing process will require the following information (hopefully only requested once) :
Password
Full Name
Name of your organisational unit
Name of your organisation
Name of City/Locality
State/Province
Two letter country code
Another thing that should be done (you get warned about when publishing an application on the Market), is to zipalign the APK file (see http://developer.android.com/guide/developing/tools/zipalign.html)
Hope you dont mind if I re-word your post and put it in my book...
Thanks for the post Dabz and the Link MrTAToad
This batch file should work :
copy %1\glbasic-debug.apk glbasic-debug.zip
"C:\Program Files (x86)\7-Zip\7z.exe" d glbasic-debug.zip META-INF\manifest.mf META-INF\CERT.SF META-INF\CERT.RSA
copy glbasic-debug.zip glbasic-debug.apk
keytool -genkey -alias mykey.keystore -keyalg RSA -validity 20000 -keystore keys/mykey.keystore
jarsigner -verbose -keystore keys/mykey.keystore -signedjar glbasic-signed.apk glbasic-debug.apk mykey.keystore
zipalign -v 4 glbasic-signed.apk glbasic-release.apk
You need 7Zip to be installed, of course...
wait - is that a debug version? I mean - could we get speed improvements if the build was triggered for a release?
Check the file compiler/platform/Andoird/bin/glb_build.bat
It'll be worth a try! Does the main_rules.xml file also need to be modified ? At the moment there doesn't seem to any speed increase :(
This is the complete release output :
Quote
_______________________________________
*** Configuration: ANDROID ***
precompiling:
GPC - GLBasic Precompiler V.7.917 SN:47ccc3f7 - 3D, NET
Wordcount:3370 commands
compile+link:
BUILDSRIPT
Buildfile: C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\build.xml
[setup] Android SDK Tools Revision 10
[setup] Project Target: Android 2.2
[setup] API level: 8
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] No library dependencies.
[setup]
[setup] ------------------
[setup]
[setup]
[setup] Importing rules file: tools\ant\main_rules.xml
-set-release-mode:
[echo] *************************************************
[echo] **** Android Manifest has debuggable=true ****
[echo] **** Doing DEBUG packaging with RELEASE keys ****
[echo] *************************************************
-release-obfuscation-check:
-pre-build:
-dirs:
[echo] Creating output directories if needed...
-aidl:
[echo] Compiling aidl files into Java classes...
-renderscript:
[echo] Compiling RenderScript files into Java classes and RenderScript bytecode...
-resource-src:
[echo] Generating R.java / Manifest.java from the resources...
-pre-compile:
compile:
[javac] Q:\Compiler\platform\android\android-sdk-windows\tools\ant\main_rules.xml:384: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 2 source files to C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\bin\classes
-post-compile:
-obfuscate:
-dex:
[echo] Converting compiled files and external libraries into C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\bin\classes.dex...
[apply] ***** GF: SKIP check the parameter *****
-package-resources:
[echo] Packaging resources
[aapt] Creating full resource package...
[aapt.exe] (skipping index file 'C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\assets\Media\Thumbs.db')
[aapt.exe] Warning: AndroidManifest.xml already defines debuggable (in http://schemas.android.com/apk/res/android); using existing value in manifest.
-package-release:
[apkbuilder] Creating glbasic-unsigned.apk for release...
-release-prompt-for-password:
-release-nosign:
[echo] No key.store and key.alias properties found in build.properties.
[echo] Please sign C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\bin\glbasic-unsigned.apk manually
[echo] and run zipalign from the Android SDK tools.
release:
BUILD SUCCESSFUL
Total time: 3 seconds
[echo] Creating output directories if needed...
[echo] Compiling aidl files into Java classes...
[echo] Compiling RenderScript files into Java classes and RenderScript bytecode...
[echo] Generating R.java / Manifest.java from the resources...
[javac] Q:\Compiler\platform\android\android-sdk-windows\tools\ant\main_rules.xml:384: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[echo] Converting compiled files and external libraries into C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\bin\classes.dex...
[echo] Packaging resources
[echo] Running zip align on final apk...
[echo] Debug Package: C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\bin\glbasic-debug.apk
[echo] Installing C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android\bin\glbasic-debug.apk onto default emulator or device...
BUILD FAILED
Q:\Compiler\platform\android\android-sdk-windows\tools\ant\main_rules.xml:639: The following error occurred while executing this line:
Q:\Compiler\platform\android\android-sdk-windows\tools\ant\main_rules.xml:271: exec returned: 1
Total time: 4 seconds
Android=C:\Users\Nicholas\Documents\GLBasic\Utilities\GLBasicCommandSet\distribute\Android
success
_______________________________________
*** Finished ***
Elapsed: 16.8 sec. Time: 15:34
Build: 1 succeeded.
Im having a few issues with signing my android app ;( Not sure if Ive got this all right but here goes. I think ive fianlly got me a dev key. So then I drag my distribute folder onto the glb_code_sign.bat, at which point it asks me for keystore. I assume its the key ive just created so I drag that over to the window, hit enter, and then this happens ;( Any advice/help ?
CODE SIGN - Drag/Drop distribute/Android folder on this
"C:\Users\Windows User\Documents\GLBasic\ARC_Inv\distribute"
Enter Passphrase for keystore:
jarsigner error: java.lang.RuntimeException: keystore load: C:\Program (The syst
em cannot find the file specified)
Unable to open 'bin\glbasic-signed.apk' as zip archive
Press any key to continue . . .
I use this file.bat to sign my android things. I drop the unsigned over it, then a shell opens that ask me about my key. I type it (invisible keytipping!) and it creates 2 files, signed and release.
Quote@ECHO OFF
ECHO CODE SIGN - Drag/Drop distribute/Android folder on this
echo -----------------------------------------
set GLB_PROJ_PATH=%1
ECHO %GLB_PROJ_PATH%
echo -----------------------------------------
set proy=D:\Programas\GLBasic\proyectos\
echo %proy%
echo %proy%glbasic-signed.apk
echo -----------------------------------------
set ANDROIDSDK=D:\Programas\GLBasic\Compiler\platform\android\android-sdk-windows
echo %androidsdk%
echo -----------------------------------------
set JAVA_HOME="C:\Program Files\Java\jdk1.6.0_25"
set KEYSTORE=d:\android_developer.keystore
echo -----------------------------------------
%java_home%\bin\jarsigner.exe -verbose -keystore "%KEYSTORE%" -signedjar %proy%glbasic-signed.apk %glb_proj_path% alias_name
echo -----------------------------------------
"%ANDROIDSDK%\tools\zipalign.exe" -v 4 %proy%glbasic-signed.apk %proy%glbasic-release.apk
//PAUSE
I assume that when it asks for passphrase for the keystore, thats the password you used to setup the key ?
I tried a modified version of your bat file and it still doesnt work ;(
CODE SIGN - Drag/Drop distribute/Android folder on this
-----------------------------------------
"C:\Users\Windows User\Documents\GLBasic\ARC_Inv\distribute\Android\bin\glbasic-
unsigned.apk"
-----------------------------------------
C:\Users\Windows User\Documents\GLBasic\
C:\Users\Windows User\Documents\GLBasic\glbasic-signed.apk
-----------------------------------------
C:\Program Files\GLBasic\Compiler\platform\android\android-sdk-windows\
-----------------------------------------
-----------------------------------------
Enter Passphrase for keystore:
jarsigner: Certificate chain not found for: C:\Users\Windows User\Documents\GLBa
sic\ARC_Inv\distribute\Android\bin\glbasic-unsigned.apk. C:\Users\Windows User\
Documents\GLBasic\ARC_Inv\distribute\Android\bin\glbasic-unsigned.apk must refer
ence a valid KeyStore key entry containing a private key and corresponding publi
c key certificate chain.
-----------------------------------------
Zip alignment utility
Copyright (C) 2009 The Android Open Source Project
Usage: zipalign [-f] [-v] <align> infile.zip outfile.zip
zipalign -c [-v] <align> infile.zip
<align>: alignment in bytes, e.g. '4' provides 32-bit alignment
-c: check alignment only (does not modify file)
-f: overwrite existing outfile.zip
-v: verbose output
Press any key to continue . . .
Might need to use quotes around the % parameter in the batch file as you have spaces in the path name.
Quote
Password
Full Name
Name of your organisational unit
Name of your organisation
Name of City/Locality
State/Province
Two letter country code
What are you suppose to use for the password? Does this password have something to do with the Keytool utility in the SDK?
Thanks.
Password can be anything you want....just remeber it because you`ll need it when signing your app.
This is my batch file (it copies the apk from the passed program directory), and uses 7Zip to delete the CERT files :
copy %1\glbasic-debug.apk glbasic-debug.zip
pause
"C:\Program Files (x86)\7-Zip\7z.exe" d glbasic-debug.zip META-INF\manifest.mf META-INF\CERT.SF META-INF\CERT.RSA
pause
copy glbasic-debug.zip glbasic-debug.apk
keytool -genkey -alias mykey.keystore -keyalg RSA -validity 20000 -keystore keys/mykey.keystore
jarsigner -verbose -keystore keys/mykey.keystore -signedjar glbasic-signed.apk glbasic-debug.apk mykey.keystore
zipalign -v 4 glbasic-signed.apk glbasic-release.apk
pause
make sure you use the release-output in the first place. I have no idea, but the debug build might have overhead.
Ah yes - glbasic-unsigned...
I managed to sign my Android .APK file and it was accepted correctly and everything. However, I still don't understand how this actually works. So you generate a local .keystore file which is based on whatever password you think up. Then you sign your .APK package with that .keystore file and enter the password again, and then send the signed .APK to Google.
But then, how does Google know it is signed correctly if they don't have the keystore file? O_O
Vudu...
=D
I suspect it just checks to make sure it is present, not the demo key and is in the correct format...
It appears that the Java 1.7 SDK key signing system isn't compatible with Android. So giggles all round then...
Fortunately being able to get some information about the problem from the Stack Overflow website, I have changed my code signing batch file to :
erase "%1.zip" /Q
erase "%1_signed.apk" /Q
erase "%1_unsigned.apk" /Q
erase "%1_release.apk" /Q
copy "%1.apk" "%1.zip"
"C:\Program Files (x86)\7-Zip\7z.exe" d "%1.zip" META-INF\manifest.mf META-INF\CERT.SF META-INF\CERT.RSA
copy "%1.zip" "%1_unsigned.apk"
keytool -genkey -alias keys/mykey.keystore -validity 20000 -sigalg MD5withRSA -keyalg RSA -keysize 1024 -keystore keys/mykey.keystore
jarsigner -verbose -keystore keys/mykey.keystore -sigalg MD5withRSA -digestalg SHA1 -signedjar "%1_signed.apk" "%1_unsigned.apk" keys/mykey.keystore
zipalign -v 4 "%1_signed.apk" "%1_release.apk"
move "%1_release.apk" "Release/%1_release.apk"
@echo "Finished"
Could someone try the included APK file (in the ZIP file) onto a real device. It is properly signed, and whilst it works with the emulator, I need to make sure the new changes are correct.
I'm looking to use that convenient script from the post above me, but I'm new to the process, so just to clarify, would I want to use "keytool" to generate a new key every time I go to release an update for my app? Or would I just want to do this once, to generate the key the first time, and then use the same key to run the following commands (ie jarsigner) with on any new binaries being submitted as updates?
Just wondering.. thanks for the script though, I think I'm almost ready to release to android thanks to everyone's help :)
Yes, every new compile would need a newly generated code from keytool which would then be used by jarsigner
property only when you update to the Google Play and various other stores. Here the APK need to been signed each time.
I've finally worked out how to silently get the APK signed :
erase "%1.zip" /Q
erase "%1-signed.apk" /Q
erase "%1-unsigned.apk" /Q
erase "%1-release.apk" /Q
copy "%1.apk" "%1.zip"
7z.exe d "%1.zip" META-INF\manifest.mf META-INF\CERT.SF META-INF\CERT.RSA
copy "%1.zip" "%1-unsigned.apk"
keytool -genkey -alias keys/mykey.keystore -validity 20000 -sigalg MD5withRSA -keyalg RSA -keysize 1024 -keystore keys/mykey.keystore -storepass %2
jarsigner -verbose -keystore keys/mykey.keystore -sigalg MD5withRSA -digestalg SHA1 -signedjar "%1-signed.apk" "%1-unsigned.apk" keys/mykey.keystore -storepass %2
zipalign -v 4 "%1-signed.apk" "%1-release.apk"
move "%1-release.apk" "Release/%1-release.apk"
@echo "Finished"
pause
Just pass the batch file two parameters - the first is the APK filename and the second is the password. Need to make sure that zipalign, jarsigner, 7zip are in %PATH% as usual.
You will be notified that there is no Time Stamp Authority certificate, but as they are expensive to buy ($218 for 1 year), I dont think it will be too much bother to ignore this - after all, you are informed that the certificate with expire in 2068...
The latest versions of Android will no longer accept APK's with the default certificate, so you will have to sign it everytime you want to test on an Android device or emulator.