I'm trying to find a way to create an apk file to extract files to certain path while installing to use these files in my main app.
In other words I need to add expansion files to my main app by installing another apk that won't be displayed in the launcher.
And play store expansion files is not an option.
What you need is an Expansion file configured as a patch.
This question has some info about it, but you should go to the official documentation about how to download an expansion file after installing your main application.
Related
I just built an app for Android using Unity3D. The app weighs 200mb. During testing I used to build a single apk which always worked. Now that I uploaded it on PlayStore, I had to use Unity's built in split feature which creates an apk and an obb file.
My problem is that now the app isn't working. It seems like the obb file isn't being loaded properly and the app doesn't find the files.
I have some assets in StreamingAssets folder which are loaded dynamically and the app doesn't seem to be able to find these along with the other scenes.
What I did to try to fix this with no success:
Added READ_EXTERNAL_STORAGE permissions
Added WRITE_EXTERNAL_STORAGE permissions
Added a plugin to force permissions dialog Unity Android Permissions
Set to false unityplayer.SkipPermissionsDialog in the android manifest
Added GooglePlayObbDownloader in my project but it seems to crash the app because of the missing License. (I can't retrieve the license)
What am I doing wrong?
I had a working app, then I enabled Split Application Binary in Player Settings > Publishing Settings and it stopped working. Disabling the feature, the app works but can't upload it on Google Play as it has a 100MB file limit.
You mentioned using UniWebView. The documentation recommends placing your web files in the Assets/Plugins/Android/assets/ folder.
If you are using "Split Application Binary" for Android build (obb files), you should not put your local HTML files under StreamingAssets folder. Instead, you need to put them to Assets/Plugins/Android/assets/ and then you can use the same way as you did for normal streaming assets resource to load it from the new location.
https://docs.uniwebview.com/guide/loading-local-files.html#using-split-application-binary.
Unfortunately this will simply move the files from the .obb to the .apk file, which might push you over the 100mb limit again.
Since it is easy to extract and read an .apk file, I want to understand If I upload a android project .apk file in Google play, and when a user downloads the application, the apk file gets downloaded on this temp folder of the phone memory. Is there a way the user can read the code in the apk file ?
If yes, what should be my considerations to protect/encrypt the apk downloaded on the users phone from Google play ?
To increase security How about applying ProGuard http://developer.android.com/tools/help/proguard.html
I followed this guide for download expansion files. When I checked it, the download worked fine, but when I wanted to uninstall the application from the phone the files stayed there.
How can I cause the files to be deleted with the app?
Downloaded expansion file(s) will be stored in your shared-storage folder (usually this is your sd-card). There is no code that can be triggered when uninstalling your application. This unfortunately means that you cannot remove expansion files from code when uninstalling the application.
However I did find out that on my Nexus 4 but also on a Samsung Galaxy S the expansion file is automatically deleted from the shared-storage folder when uninstalling the application. I tested this using an application that is in the play store.
When the expansion file is not deleted automatically then the only way to get rid of your expansion files after an uninstall would be to manually delete the file(s) from your shared-storage folder. An end-user can be instructed to remove the expansion file manually by letting him/her attach the device to the computer and navigate to:
<shared-storage>/Android/obb
In this folder you should see one or more folders with package names. Pick the folder that will contain your expansion file and delete the package folder or the expansion file depending on what you wish to be deleted. Be aware that deleting the wrong package can affect different apps. So use manual deletion with caution!
Some reasons why an expansion can't be deleted by end-user:
End-user doesn't have drivers for the device so it can't see what's on the shared-storage
End-user uninstalled the application and the expansion file is already gone
Store your app files in the Applications private directory.
This can be obtained with getFilesDir()
When your application is uninstalled, all files in this directory get deleted.
This is a very interesting thing. I have an APK file, com.company.app.apk. When installed to an emulator by using Eclipse, by using the following code to get the apk's file name:
String fileName = activity.getPackageManager().getApplicationInfo(
activity.getPackageName(), PackageManager.GET_META_DATA).publicSourceDir;
I get a pathname like this com.company.app-1.apk. The file size is the same as the apk file I built.
Now when I publish this app to Market, and install it to a real device (Android 2.3), the same code returned a pathname like this: com.company.app-2.zip. Note that the file extension has changed to .zip and, most importantly, the file size is significantly smaller than the original size.
Now if I transfer these two files to my PC and use WinZip to open them, I found one really interesting thing:
The one installed on emulator by Eclipse has exactly the same stuff as I expected. Namely: the code ('com' folder), the resource ('res' folder), the signature ('META-INF' folder), the assets ('assets' folder), and the manifest file (AndroidManifest.xml). However, the one installed on a real device by Market has only two parts: the resource, and the manifest file.
Question: I think when installed from Market, the .apk file is split into two (or more) files. One file is pointed to by ApplicationInfo.publicSourceDir, which contains only the resource. How can I get the pathname to the other file(s)?
ADDED: I have two versions of the same app, one is paid using Google's Vendor Licensing Service, the other is free. The above mentioned phenomenon happens only to the paid version. Why?
Correction: When I said the 'com' folder exists in the installed apk file in the first case, I should be more clear. The code per se, the *.java files, are not in the 'com' folder. As a matter of fact, the 'com' folder contains only a few garbage files that were inadvertently left there during the build process. If not for those garbage files, I don't think the 'com' folder would be there in the first place.
I think you are not right. The market works in the following way: you choose an application and push a button to install it. After that market sends the intent to gtalk service to install the application. This service downloads apk file that you've uploaded to the market and when finishes it installs this apk. Just during the installation can some changes happen. It seems to me that from the application during the installation classes.dex file is extracted and from this file optimized dex (.odex) is produced and put in the separate directory. That's why you see the difference in the files.
Ok, here is what I've found out, in case this helps someone out there:
When Market installs the free version of my app, the apk file is installed to /data/app/com.company.app.apk, the file content is exactly the same as I built it, same file size, same everything.
For the paid version that uses Market Vendor Licensing, the apk file itself is installed to /data/app-private/com.company.app.apk. This is the same file as I released. However, the resources are extracted and installed to another file /data/app/com.company.app.zip, note the file extension. This zip file contains only resources, so it's significantly smaller. But the .apk file in /data/app-private has everything, so the file size is the same as I built it.
ApplicationInfo.publicSourceDir always points to the file in /data/app, so it's /data/app/com.company.app.zip in the paid version's case, and /data/app/com.company.app.apk for the free version. For the paid version, I obtained the pathname from publicSourceDir, then replace.app with app-private, and replace .zip with .apk to get the original file.
If I install the apk directly to an emulator, then there is only one file and is always installed under /data/app.
How the .apk installation process works on device? Is the .apk file just copied to some place and kind of installer application extracts the application information, register somehow the application to environment, extract also the icon and put it on the application launch screen? Or the .apk content is extracted and files are copied to various folders and the .apk file itself is deleted?
I am asking to understand if there is any possibility on device to browse the .apk file structure and its content and access in read-only mode directly the assets, res folders, AndroidManifest.xml, the dex file and also used libraries (.jar or .so)?
The reason I am asking is that I am looking for possibility to read into memory .dex, .jar or .so files like arbitrary binary files (e.g. by using the File class) for the purpose of computing a message digest from its content (i.e. using md5 or other hash method)...
BR
STeN
The APK is copied onto the device, usually into the /system/app directory. The APK is not extracted or unzipped until it is used, so if you want to probe the files you'll need to do the decompression and extraction yourself.