2016년 12월 29일 목요일

Unzipping .apk & changing AndroidManifest.xml & SDK Level for Higher Resolution.


I've never posted here before, and I wanted to extend my understanding of MIT App Inventor (AI) and I was wondering if anyone here could help...

I understand there is an AppToMarket tool that can help me accomplish this, but I would like to know how to do this without those tools so I can use this understanding to create and modify programs in the future using other Android development tools such as Eclipse / PhoneGap (Cordova)...

The major roadblock that I'm running into involves the resolution restrictions built in to AI, making my projects look pixelated and fuzzy.  The same is true with the recommended 48x48 pixel icon.  I wanted to create a drawable folder in my .apk so my icons can support more resolutions... I already know how to create the folder structure and the appropriate icons (and will do a writeup in the future about it, if there's any requests)...

Here's what I tried: Unzipped my project .apk with 7zip, and the AndroidManifest.xml file is corrupted.  I'm guessing it's either caused by the .apk being zipaligned or the signing of the .apk in AI.  Some other issues I have is once I do make the appropriate changes, then I'll need to resign and rezip my project...  I'm totally unsure if I'll have to change my SDK when I do make these changes.

So here's what I'm asking:
  #1 - How to properly unzip an .apk made by AI
  #2 - Do I need to resign the app and how? (do I use the keystore one made from AI to resign?)
  #3 - How to zipalign when done? (which I'm guessing is zipalign -c -v 4 example.apk ... -c to confirm the zipalignment, -v is for verbose output, 4 is for 32-bit alignment)
  #4 - Does changing my app to use large, xlarge, or fullscreen of the android device - does that change the SDK level of the App?
  #5 - If it does change the SDK level, which levels would I choose?

If anyone can give me hints or point me into the right direction, I'll make a nice writeup for people using AI so they can get the most out of this MIT project and post it wherever this group needs it to go (Websites, PDF, whatever).

Thank you for reading, I tried searching for these issues on this Google group, but I found nothing.  If there's reposts to any of these issues, I'll be more than willing to look at links.  Again, I'd like to learn how to do this manually...  

--
You can't simply unzip the. Apk
The manifest is not corrupted.  It's just compiled version that you see.
When compiled and being repackaged,  it has to be reSigned with same key.

--
How to make internal changes to your App Inventor Project
Q: Why would you want to do this?
A: Major reasons would be the following: If you want support for making minor changes to the AndroidManifest.xml file and add higher resolution icons to your project to support higher resolution screens.  Supporting higher resolutions allows AI users to create a more professional "Production" application that is more usable by the public.  Another reason would be to not use the insecure android.keystore.  There are even more advanced things you can do, but it's really outside the scope of this document...

Q: android.keystore? What's that?
A: A keystore is a encryption key that follows the X.509 standard and it uses encryption to make a type of public/private key combination.  The keystore is a way to sign your application to show ownership of the application.  This is as legal binding as signing a document, and if you use the default android.keystore, it has more potential of being unlocked. (storepass & keypassword are known variables)  Google will NOT allow an application to be submitted to the Google Play store without your application being signed and zipaligned. android.keystore is the file that you can import and export within MIT App Inventor 2 under the Projects Menu on the top of the screen.

Q: Why not use the original android.keystore?
a: AI's keystore is insecure because the storepassword, keypassword and alias is the same for ALL AI users. (alias = androidkey; keystore password = android; key password = android)  Your keystore is the way you sign your application, saying that you are the developer for that application.  If you have already submitted an app you have developed into production with AI2, you unfortunately have to use the same android.keystore.  If that is the case, Google Play will force that app to use that same keystore given in AI. Fortunately, you can secure your keystore somewhat by changing the storepassword and keypassword to something new.  

Please Note: AppToMarket is a much easier method to create and maintain keystores and is recommended by me for newcomers to Android Development.

Tools needed:
APKTool - for all platforms (Install Instructions) - Needed to decompile & recompile your .apk file
Java SDK or OpenJDK (I used version 7) - Needed to run APKTool, keytool & jarsigner
Android Build Tools from Google - needed for zipalign

Need to do before starting (Windows / very similar steps are probably required in Linux):

⦁ All the commands mentioned above should have their directories linked to the PATH environmental variable, so you can work on your APKs in whatever directories you wish to develop in. (Instructions for most Windows flavors)
⦁ Choose a development folder/directory and copy your AI2 completed folder into it.
⦁ If you haven't already, open your command prompt (either by typing cmd on the search bar or Start -> All Programs -> Accessories -> Command Prompt)
⦁ Move through your directory tree until you get to your development directory.  In this case, your tab button is your friend, hitting tab will help you auto complete the names of directories and placing quotes around directories that have spaces. Simple Commands to know: CD (Change Directory: CD .. to go back a directory and CD . for current directory), COPY (COPY file), DEL (DELete file).  (Wikipedia Article for DOS commands)

Decompile .APK:
(From this point on, we will call the apk that your working with example.apk... The words in bold with the greater than symbols are the commands your running at your command prompt; don't type in the greater than symbols ;) )

> apktool d -s example.apk

This decompiles your example.apk into a folder named example. (the folder name is always the name of your file minus the extension) the d command is to tell apk tool to decompile your apk, I believe that the -s has to do with the permissions of your app, but to be honest, I'm unsure, I just know I've made good installs using this technique.

AndroidManifest.xml and Icon Changes:

Here's the changes I've made in my own AI2 application to improve the production level of my work, if you have other suggestions to improve AndroidManifest.xml or other files, please share...

Icons: Here's an example of the folder structure if the program that you uncompiled was called example.apk:

example\res\drawable (deleted)
example\res\drawable-ldpi\ya.png   (Transparent PNG - 36x36px)
example\res\drawable-mdpi\ya.png   (Transparent PNG - 48x48px)
example\res\drawable-hdpi\ya.png   (Transparent PNG - 72x72px)
example\res\drawable-xhdpi\ya.png   (Transparent PNG - 96x96px)
example\res\drawable-xxhdpi\ya.png   (Transparent PNG - 144x144px)

 I named all of the files ya.png because that is the default name in AndroidManifest.xml and the name of the PNG didn't really matter to me.  Pick icon images that scale well when designing this.

AndroidManifest.xml: This thread posted by Gareth Haylings was exactly the changes I wanted to make to my application.  In short, this is what Gareth wrote (with a small addition by me)...

Between the application Tag and the last uses-permission Tag (my decompile didn't have a uses-sdk tag), I added:

<supports-screens android:resizeable="false" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="false" /> 
android:resizeable is set to false, as android:resizable="true" 
has depreciated...  I added the support to xlarge screens in this listing...

And in the same thread above, Gareth tells us the technique to remove the title bar, by adding this to your application tag...

android:theme="@android:style/Theme.NoTitleBar"

I used Notepad++ for the changes made.  Now that you've made these changes, you'll most likely have to make changes to your program to improve the layout for tablets and high resolution smartphones.  The way in which you do this depends entirely on your design philosophy.

Build (Recompile) .APK
Here's if your folder was named example...

> apktool b example example-output.apk

APKTool is experimental and there is no promise that this will work... In fact, this is the point where your program breaks 90% of the time. If you have errors and warnings, it's because of the changes you made in your AndroidManifest.xml or your version of aapt is outdated.  (I think sometimes this also can be caused by the framework, each decompile will make a 1.apk on your computer...  At the time of this writing, I didn't have a chance to confirm this fact... If you think this is giving you bad builds, delete 1.apk, decompile, make changes, build)  Keep in mind, we are making changes to the apk file in ways which were never intended by the MIT team.  The only words I can give you is good luck and read the errors very carefully that your program produces.  It will be near impossible for people in this forum to help you.  I used Notepad++ because the notation of your AndroidManifest.xml file will be colored and you'll see the line numbers of your AndroidManifest.xml files, in case you run into a build error.

Now we are going in two directions, the first is if you already posted your App Inventor 2 app on the Play Store or if you haven't...

If you have already posted your App Inventor 2 app on the Google Play Store:
If that is the case, then you'll should change your keystore password and key password for added protection.  You'll also need to Import your android.keystore... (Remember: default keystore password = android, default key password = android, CN=MIT App Inventor email address, O=AppInventor for Android, C=<country that you live in>)

To change your keystore password:
> keytool -storepasswd -keystore android.keystore

To change your key password:
> keytool -alias androidkey -keypasswd -keystore android.keystore

(Note: Pick passwords that are secure, and you only need to do these commands once...  You don't need to do this again after this time... keep your keystore password and your key password somewhere secure and your android.keystore secure when done.  This is your DIGITAL SIGNATURE!)

If you have HAVE NOT posted your App Inventor 2 app on the Google Play Store:
This is to make a unique keystore for appinventor and also for any other development, like Windows.  If you do make other applications, you'll want to have your keystore signed by a CA.

Here is some recommendations to you...

⦁ Your private key should be generated on a SECURE PRIVATE computer!
⦁ Use a keysize of at least 2048 bits (I use 4096 bits).
⦁ Must have a lifespan of at least October 22, 2033, calculating the number of days from April 18th to that day came out to 7128 days.
⦁ Only first 8 characters are used in the alias.
⦁ Use RSA.

Here's Google's recommendations: Signing Your Application

To make a self-signed keystore (named example.keystore with an alias named examplealias, using RSA, 4096 bits, and valid for 7200 days):

> keytool -genkey -keystore example.keystore -alias examplealias -keyalg RSA -keysize 4096 -validity 7200

It will ask for your keystore password, your key password (never use the same!!!), your CN (email address of company), your OU (Department or leave blank), your O (Company Name or leave blank), your L (Town of Company or leave blank), your S (State of Company or leave blank), your L (City of Company or leave blank), your C (Country of your Origin)

More information about keytool by Oracle.  You only need to make a keystore once for your application.  YOU SHOULD NOT EVER LOOSE YOUR KEYSTORE or FORGET YOUR PASSWORDS, same as above, you've been warned...

---
Signing your Application
Now, use the appropriate keystore to sign your app...  In this example, we are using android.keystore, but if you haven't already published your AI2 App, I'd recommend a new keystore....

> jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore android.keystore example-output.apk aliasname

(android.keystore = rename with whatever your keystore file is (it might be the same), and aliasname is whatever your keys alias is...)  It's going to complain about time stamping when executing, but that's not important for creating an Android App for Google Play.

Verify your signature:

> jarsigner -verify - verbose example-output.apk

ZipAlign your App

> zipalign -v 4 example-output.apk finished.apk

This makes your file easy to access on the android platform.  

Test your APK and Upload to Google Play Store when done!

Resources: Links above + wikiHow + Stefan Diener

Please share your experiences and things that you've learned by decompiling and building your APKs on App Inventor 2, I wouldn't mind learning something new!

--

댓글 없음:

댓글 쓰기