Why updating an android app can make it appear twice? - android

I made a lot of changes to my app : databases scheme, graphics, code, etc. The biggest is the package name that I renamed to a total different one. The applicatgio got the same name and Id in the manifeste.xml file and the apk got the same name, with the same digital signature.
Nevertheless, when using ./adb install -r myapp.apk, myapp appears twice in the menu. Of course since the DB is stored in a directory using the package name as name, the user feel like its data is lost.
How can I prevent this from happening, and if I can't, how can I automate he migration ?
I have several clues : prompting the user for uninstalling the old app, copying the database from the old file to the new one, etc.

The direct answer is the application appear twice because Android Market and Android OS view two different packages as two different applications. The code can be same, but if the packages are different the applications are completely different
Android Market identifies applications by their package name. I suspect this is because the OS tracks programs by package...makes sense that you wouldn't want two packages with the exact same name installed, how would the OS know which one to call? Therefore, if you install a package with the same name as a package that's already installed the OS will view it as a package upgrade and let the new program access the old user data.
You state that the packages share the same ID, I assume this is user ID. This enables you to share data between the packages. More information is here:
http://developer.android.com/guide/topics/security/security.html#userid
Recommendation: Release a small upgrade to your old package providing whatever glue is needed to let it share it's data with your new package. Then release your new package with the code to import the user data from the old package (need same UserId and signature). The transition would be seamless to the user (no manual backup and import).

The application signature must be the same. If you imported the project in another Eclipse, build it and upload it to market you will see 2 separate apps.

Related

Is it possible to check if 2 APK files are the same, without comparing byte-by-byte (or use algorithms that do it)?

Background
I want to check if 2 APK files are identical (or have a very high chance of being identical) in the minimal work on the device.
The reason for this, is that I have an app (here) that allows to install apps using APK files, so I want to check if the installed app is already the same as the APK file. This includes using root privilege for background install. So far, what I did was to check the package name and the version code, but I want to know if there is a little better way to perform this check.
The problem
By "minimal work", I mean minimal reads of the APK file itself. This means that going through all of the bytes of each of the APK files is the most correct way to check if files are identical, but if there is a signature for the APK, that identifies it relatively uniquely, that would be much better.
For example, I know you can do MD5 check on both files, and if it's the same for both, it's a really good chance both are the same, but such an algorithm, along with other similar algorithms (sha1 etc...), go over the entire file, so this is about the same as what I wrote before. It could take a while for large APK files.
What I've found
What I do know is that comparing the package name and the version number gives a clue about whether the APK files are of the same app and version, but I think that Android-Studio knows more about the APK files, because sometimes it asks if we want to uninstall the installed app even though they have the same version, and it doesn't seem like it takes it a lot of time to ask this.
I could add a file size check too, which should be relatively as fast as the package name and the version number, but maybe there is more ...
Here's a sample code of what I did:
public static boolean areApksMostProbablyIdentical(PackageInfo packageInfo, PackageInfo packageInfo2) {
if (packageInfo == null || packageInfo2 == null)
return packageInfo == packageInfo2;
if (!packageInfo.packageName.equals(packageInfo2.packageName))
return false;
if (packageInfo.versionCode != packageInfo2.versionCode)
return false;
final File file = new File(packageInfo.applicationInfo.publicSourceDir);
final File file2 = new File(packageInfo2.applicationInfo.publicSourceDir);
if (file.exists() && file2.exists())
return file.length() == file2.length();
return true;
}
The question
My question is:
Is it possible to perform a "good-enough" check on both files, avoiding comparing all bytes, to see if 2 APK files are the same?
What I do know is that comparing the package name and the version number gives a clue about whether the APK files are of the same app and version,
No it does not. All it tells that both packages used the same values. Anything but that is just pure assumption.
but I think that Android-Studio knows more about the APK files, because sometimes it asks if we want to uninstall the installed app even though they have the same version, and it doesn't seem like it takes it a lot of time to ask this.
Wow :) All AS knows about APK is in APK. There's no magic. Yet, not sure how you managed to reach your 50K (mostly android based) reputation score and still act like you never heard about the APK signing and all the certificate system used on Android. What usually triggers such uninstallation request dialog to popup is ordinary certificate mismatch, usually release vs debug one.
Is it possible to perform a "good-enough" check on both files, avoiding comparing all bytes, to see if 2 APK files are the same?
Once you define what good-enough and the same really means for you in this then perhaps, but by using common means of phrases I'd say no.
EDIT
The reason for this, is that I have an app (here) that allows to install apps using APK files, so I want to check if the installed app is already the same as the APK file
Then all you need to check if your installed app and the APK files are signed using the same certificate and are using the same packageId. If not, this is different app. If this matches, then I'd compare versionCode - if the same -> this is the same app. If higler/lower it's downgrade/upgrade. Sure, one can still release different APKs with the same versionCode and try to sideload it but I'd say it's not your problem to solve (that's the reason Google Play Store enforects versionCode bump on each update). Optionally, if you really got too much spare time you could compare APK file sizes.

Re-branding an iOS Application (as compared to Android)

We purchased the source code to a certain Android and iOS application and now need to re-brand it before releasing it on the app stores. I'm quite familiar with Android, so that side wasn't an issue. However, I've never touched iOS apps before, so I have a few questions.
On the Android side, we changed the application name by changing several string resources. Then we changed the package name in the manifest.xml file (to make this a unique application in the eyes of Google Play) along with changing the package names in the affected class files. And compile.
Would iOS applications require something similar? Is there an equivalent to the Android string resources where I can change strings in one place and they are reused throughout the application? Also do iOS applications have some sort of unique ID, the equivalent of the Android's package name in the manifest.xml file? If I change this unique ID, does it impact the code in any way (in Android the package name corresponds to the main application Java package that starts the application).
The package name you referred is called Bundle Identifier in iOS world.
It can be changed in Project settings, or directly in the project property list (.plist) in the Xcode project.
The original value may look like:
com.example.${PRODUCT_NAME:rfc1034identifier}
You can change it to whatever valid values you want (highly suggest you use reversed FQDN format).
Remember to clean & rebuild to project after changing this value, and all App ID, Provisioning Profiles and probably certificates have to be re-configured.

Building two different Android apps that differ only by manifest

I need to create two different Android apps using the same code. The user should be able to install both the apps on the same device.
The differences between the two apps are just a few strings, including the application name. These strings have been isolated to a string resource file called Custom.xml.
My plan to achieve two versions is rather simple. In the nightly build script:
1. Run Ant to create the first application .apk file.
2. Rename the generated .apk file
3. Replace Custom.xml with a different one
4. Run Ant once again
This may work except for one thing that I am not sure about. It is the package name in AndroidManifest.xml->manifest->package attribute. I guess this has to be different if the apps have to coexist. Does changing the package name have any impact on the rest of the code? I hope this package name is not tied to the package name used in java files.
Also, does anyone see any problem with my overall strategy? Thank you in advance for your help.
No, it does not have any impact, unless you use your hardcoded package name in the code.
There is an official example of renaming the package to build a debuggable version of the app.

How can change name of project and package?

I am developing an Android application named "English SMS Collection" in Google Play store, and now I want to upload this app in Hindi language also. So what changes are required to previous APK?
How to add another language to an Android application? And also what image size icons are required for uploading the app to market?
Any help would be appreciated.
Generally, splitting the same app into two functionally equivalent versions with different languages is a bad idea.
If you absolutely must do that, the only thing you need to change is the package name (package="com.example.project") in your AndroidManifest.xml (no need to rename actual packages, just that one string in manifest).
Also, if your Activities are declared relatively to app's package (e.g. .MyActivity as opposed to com.mypackage.activities.MyActivity) - and they most likely are - changing app's package name will obviously cause FCs because you effectively rename the activities. So to be able to switch the package name back and forth you'll have to detach Activity names from app's package by declaring them absolutely (e.g. com.mypackage.activities.MyActivity)
Here's a comprehensive guide on icons from Google, next time please do more research before asking such simple questions: Iconography
Also, judging by the question, you'll probably want to also read into this: Publishing Checklist for Google Play
Please DO NOT split your app up into two apks just because of the language. This is very bad style.
According to the android devleoper's guide, it's best practice to create ressource-folders with so called "configuration qualifiers". Your strings (e.g. text) should all be stored in the file /res/values/strings.xml . This is the default setup (without a configuration qualifier), when adding localized translations you have to create a new folder and strings.xml file /res/values-cc/strings.xml where cc has to be the standardized country/language code (e.g. "en" for english, "de" for german, "cs" for czech...).
For more (essential) informations on this, visit developer.android.com/guide/topics/resources/localization.html .
You need to change the package name because it should be unique while uploading in market. It can be signed with the same keystore file you have done for other two apps. Obviously, you have to change the Application name and its icon.
For more Information on Publishing Checklist for Android Apps, check this documentation.
In a Package Explorer, click on the package name (e.g: com.example.android), right-click and go to Refactor. Choose the Rename... option there.

Building Android project to different packages

I'm trying to find the best way to build/package an Android app for 6+ different customers. I could use different branches in SVN for all of the customers, but the only difference between the apps are some values in the resource folder (drawables, strings, etc).
I wrote an ant script that imports the standard Android build.xml. This script does the following:
Reads the customer names from a properties file.
For each customer the following is done:
The package name in AndroidManifest.xml is changed (by hooking into the -pre-build target).
The custom resources are copied into the res directory in the build (by hooking into the -pre-compile target).
The package name is changed back to the default value (by hooking into the -post-compile target).
The APK is copied to a specific location an named something like customer-versionno.apk.
This seemed to work well until I just now wrote the part that changes the package name. Because of the package name change the location of the R class is also changed, meaning that the build fails as the Java classes import the R class from the standard package.
I don't want to have a build script that changes code. I want to be able to do this with minimum changes to any files.
Soo..the questions are really:
Are there any good/simple solutions for my problem?
Am I approaching this problem in the wrong way? Are there better ways to easily package the same app to 6+ different customers?
Do you really need to change the package name? Changing the package name is a pain to do automatically. That being said, here is my solution to the problem:
My scenario is that I have one app that gets deployed to 30-200 different signed APK files where the only difference between the files are some resources (drawables, strings, values etc), and the package name.
I do this by working on a generic version of the app that serves as the template project. Once this works and I am ready to deploy I invoke a bash script that loops through the following steps for each target:
Clean the project completely
Swap out res dir and package name using sed.
Builds and signs the APK
This balances the horrific deply time with fast developemnt time. I really don't see another more elegant/robust solution than this.
And finally a small tip: In android manifest use relative package names like ".Application" instead of "com.mycompany.myproject.Application". This way you only need to change the package name in ONE location.
Is it possible to solve this with making 6+ different projects that includes your main projekt. This way you are able to override resources and make different apk's

Categories

Resources