I'm creating a software that will guide the user through a few steps, to publish an android application (APK file).
The way I am doing this, is that the APK file is already compiled, and all I need to do is replace an XML file in the package, and that will change the behaviour of the application. My big problem now, is that unpacking the apk file, and doing any tiny text edit, and then packing it again, breaks the signature and prevents the application from running on any device, giving a message that the signature is incorrect.
How can I solve this? I want to safely open the APK, write something in a text file, and close it again. Note that this operation will be done on the user's computer (after he purchases our application) so we're look for a command-line tool with no special requirements like JDK.
Any help?
Ok I reached the best "tested" solution - I'm posting it here to save other developers hours of googling. The only downside is that I will require the customer to install JDK on his machine, unfortunately. The reason is because I did not find any apk-signing tool that works purely on windows, without relying on JDK.
I have my android application created using Air, so this makes things easy for me - all of the air files are treated as resource assets. So have your APK archive file ready.
Once you have your modifications ready, put them inside a temporary folder named "assets". You will use the 7-zip command line tool (free: http://sourceforge.net/projects/sevenzip/) to update the contents of your apk. To have it working with your apk you will have to rename your apk's extension to zip - don't worry, you'll change it back later.
Now from a .bat file (or directly in the command prompt) from the location containing both your apk file (zip extensioned) and your assets folder, you'll call: 7za u APK-file.zip assets
Now your apk file is updated. Rename it back to .apk extension
Now you'll use the signAPK tool from here https://code.google.com/p/signapk/ and note that this is the only step requiring JDK installed. It also assumes that you have your key files ready (replace the dummy ones included in the package). Extract the file contents and call: java -jar signapk.jar key.x509.pem key.pk8 [android_app].apk [signed_android_app].apk
At the very end, you may find your signed apk file size drammatically increased. So you need to use the android's zipAlign tool: (darn, can't post the link since new users can only post a maximum of two hyperlinks)
you will be calling the command: zipAlign -c 4 [signed_android_app].apk
And voila! That's the route I'm taking.
If someone finds a way to do the signing process without relying on JDK (assuming the key files are ready) please share.
How can I solve this?
You don't. If you modify an APK file, by any means, it must be re-signed.
Android apk files must be signed. That signature proves that the contents of the apk have NOT BEEN MODIFIED from what was initially published. (Which is exactly what you are doing.) The signature at the same time, also proves who the author is.
So in a normal signed apk file:
You know who the author is. (Even if it's not something you as a human can understand.)
You know the contents were put there by the author, and not modified since.
This is a key security measure built into Android, is there for very good reason, and cannot be overcome. It prevents things like viruses from being embedded inside innocent apk files.
Related
I'm building phonegap app using phonegap-build.
I need to make some changes to the manifest of the android apk.
After i download the apk of my phonegap build, i rename it to .zip file to see the contents of the file.
When i open it, there i see the xml file there, and when i open that one, it has encoding problem.
This is what i see:
I understand it's a binary, but i need to see the content in plain english, if possible.
1) How can i encode it to see what is the content of this file properly?
2) After a change that i do on it, can i "decode" it back to binary?
So from what you wrote you wrote, you want to edit the AndroidManifest.xml from an APK file AFTER you built it, which is quite complicated. I suggest you editing the source AndroidManifest.xml and then re-building the APK. If you can't do this then please do the following.
(1) First, download and install Apktool. It is a free Android tool for decompiling and recompiling apps quickly. It provides access to .class files, resources and XML's. Here's a tutorial on how to install Apktool.
(2) Then you want to decompile your APK file (tutorial).
(3) Edit the AndroidManifest.xml file.
(4) Re-build the application (tutorial).
(5) Finally, you will have your APK file but it will be mostly useless as it is un-signed. You can't install un-signed apps as you will get an error (it may be possible to force-install it using root or adb tho) and you can't publish them. To sign it you can check out this link.
IMPORTANT INFORMATION: Your app will have to be signed with the same certificate with which it was signed the first time, otherwise it will be considered a different app. Not completely tho, you will have to un-install previous versions in order to install this one.
And yes, I know it's a very long and time-taking process but it is supposed to be, only if you have the source you should be able to edit the app.
As mentioned above, the tool you are looking for is Apktool.
You need to use --force-manifest flag when you decompile to decode AndroidmManifest.xml.
Is there a way to manually repackage an apk (that will successfully run on a real device). While we can use any zip tool to unpack our apk files, the reverse is not possible (due to some app signing issues and such ) so I'm wondering how to go about doing this. I don't want to build an apk (which would involve compling Java classes , resources etc). I just want to be able to create an apk file ( that will run on a device) manually (command line is ok), provided that I already have all the necessary files.
Thank you
I use construct 2 to build my apps and then I export them to CocoonJS which then compiles them as a native app. I download an unsigned .apk file, sign it then upload it Google Play. The apps work great, just like they were natively written.
When I compile my app with CocoonJS it requires all of these permissions that my app doesn't need. How can I remove the unneeded permissions?
Until Ludei implement an optional permissions on their cloud compiler, we have to do a bit of "hacking" to fix the problem ourselves.
Get the attached apktool.zip, extract it to a folder C:\Android (to make it easier later).
https://static3.scirra.net/uploads/articles/1071/apktool.zip
Copy your release CJS compiled game.apk (from herein, referring to that APK file as game.apk) into C:\Android so its in the same folder as the extracted apktool files.
Open command prompt in C:\Android by right clicking somewhere in that folder while holding SHIFT key.
First, we need to install the framework of our CJS compiled game.apk, type this in:
apktool if game.apk
Its instant, with a feedback that it installed in location 127 or thereabouts. Now we have to decompile the APK, type this in:
apktool d game.apk game
It take awhile depending the size of your game & speed of your PC, but all the contents of your game.apk will be decompiled and stored in a subfolder with the same name as your game.apk, ie. game. Note, if you use different versions of apktool, you may need to change the flag to: apktool d game.apk -o game so it decompiles properly.
Browse the new game subfolder, you will see all the contents. What we are after is the AndroidManifest.xml, open it with Notepad++
Hi-res version: halfgeekstudios.files.wordpress.com/2014/07/androidmanifest.jpg
Remove the permissions by deleting the grey highlighted lines!
The permissions ACCESS_NETWORK_STATE & INTERNET are required, if you remove it, your game is likely to crash on startup. This is true even if you have no Ads or IAPs or Social plugins. CJS needs these since its got some built in analytics that require it. BILLING is also required if you implement IAPs. Interestingly, Google has decided that these three aforementioned permissions will now be considered normal and they do not warn users when games have these three only, only if it contains the other permissions!
Here, I'd like to point out this line:
You can edit your game to be on phones or tablets by setting them to false. If you set smallScreens & normalScreens ="false", the game is only compatible with tablets or vice versa (I've tested this with my own games). This is handy if you design your target to tablets and don't want to manually filter over 6,400 devices, one at a time. :D
Once the changes are done, save it. Go back to the command prompt, type this in to recompile it into a new APK:
apktool b game game_new.apk
Takes awhile, but you will get your game_new.apk that is modified. Now you need to proceed with normal signing and zip aligning prior to uploading to Google Play.
https://www.scirra.com/tutorials/1071/removing-permissions-from-cocoonjs-compiled-apk
You cannot remove it. Try other tools like Phonegap. phonegap
I'm trying to modify the Androidmanifest.xml for the browser on my device so that I can execute an app by loading a URI in the browser.
I've been running around the file system in ADB SHELL all day, but can't seem to find it. Plus there is no FIND, nor LOCATE command on the system.
You can theoretically find the Androidmanifest.xml file in the APK.
Every APK contains the compiled source code of the application. There is no useable decompiler for APKs at the moment so it is not possible to change the content of one.
In addition to the compiled code and the other resources of the application, an APK also contains a signature from the developer, which will become invalid when the content is changed to verify the source of an APK. An Android system won't install an APK with an invalid signature, so even if you could change the content of the APK, you still couldn't use it.
The conclusion: You cannot do what you are trying to do.
Android Studio on Windows 10/11, it’s in: app/src/main.
How can I store a normal tree of files inside an Android .apk without all the weirdness of the Ressource or Asset concepts? It seems I have to do some akward thing to use Files from current path like any non-Android Java application do?
"use Files from current path" and "store... inside an Android .apk file" have nothing to do with each other.
Since, statistically speaking, you are likely familiar with Windows, let's draw some analogies.
"store... inside an Android .apk file" on Windows would be "store... inside a Windows .exe file". This is reasonably uncommon on Windows, at least the last I checked.
"use Files from current path" on Windows would refer to files that perhaps exist in the app's Program Files directory or the equivalent. On Android, this works fairly conventionally -- use getFilesDir() and Java file I/O.
What exists in Windows and does not exist in Android is the concept of packaging files to be installed at install time via an installer package, such as a .msi file.
Since you declined to tell us what the "normal tree of files" is and why you think it should be "inside an Android .apk", it is impossible to give you advice on how to avoid whatever "weirdness" you think exist in the "Ressource [sic] or Asset concepts". All I can tell you is that the equivalent on other OSes to bake files into the executable would likely be similarly "weird".
Okay, I haven't tested this, but a solution could be to add extra files to the APK before signing. You could automate this from the command line:
$ ant release
$ zip -r bin/MyApp-unsigned.apk <custom_folder>
$ jarsigner -verbose -keystore <keystore> -storepass <password> bin/MyApp-unsigned.apk <alias>
$ zipalign -v 4 bin/MyApp-unsigned.apk bin/MyApp-signed.apk
And then, in your activity, open the APK with ZipFile to access your custom folder:
ZipFile apk = new ZipFile(getApplicationInfo().sourceDir);
I'm not sure how the Android Market would react to this non-standard APK though.
With assets you can have a file tree in an APK, which can be accessed by using the AssetManager returned by getAssets().
The whole point of this mechanism is saving space. The files are not extracted to the file system when the app gets installed. When you read the content of an asset, it is uncompressed (unzipped) on the fly from the APK. It does make sense. Saving space is important on Android devices.
But nothing forbids you to extract the assets tree into the file system when your application is first launched, if you need that.
One approach that might work for you is to open the APK using ZipFile and ZipEntry, as this gives you access very similar to a conventional read-only directory structure.
Alternatively, you may be able to use getResourceAsStream to work with a traditional file structure - you might find this bug report useful if you go with this approach - it shows some perils of working with getResourceAsStream on android.
I should add that you shouldn't think of an APK as something gets extracted - files inside the APK are not on the filesystem, they're like resources inside a JAR file in a J2ME or J2SE environment (or the WAR/EAR for J2EE).
Hope this helps,
Phil Lello