Self updating app, wont overwrite existing app, using Android packagemanager? - android

I know there are plenty of questions about this on here, but I've tried everything (but the correct 'thing', obviously!) and nothing seems to shine any light on the problem I'm having.
I've written an app (for a customer), which is designed to be hosted on their own server. The app references a simple text file with the latest version code in it and checks it against it's own version. If it's out of date it goes off and downloads the update. Everything is working as intended up to this point.
I use the:
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
...code to start the install process of the newly downloaded .apk file. And that all starts as I would expect.
I click on "Install" - when I'm prompted to confirm the overwriting of the current app, with the new. It starts, and then displays:
App not installed. And existing package by the same name with a conflicting signature is already installed.
Now I'm aware that Android can't have multiple applications sharing the same package name, which is fine, but nothing comes up in LogCat and I can only assume that the OS is annoyed at me attempting to 'update' my app, even though I'm going through all the correct channels and using the inbuilt package manager to do it for me!
Can anyone tell me what the OS is moaning about? I'm not attempting to install two apps side by side, I want it to update it, which it starts to do, and then gets really confused.
Is it something to do with me using the same keystore for signing the packages? I highly doubt it as I've used the same keystores previously to handle updates to games and the like, but I just can't figure out what it's complaining about.
Hopefully someone out there has had this issue and solved it, and can point me in the right direction. I'm flying a bit blind with the limited information it's giving me :(
Cheers.

You have built the new and old versions using different signing keys; likely you either built them on different machines, or one is a debug certificate and the other a release one. When this happens, you typically have to manually and explicitly remove the old version before installing a new one with a different certificate - it's basically a safety measure against inadvertently installing a trojanized imposter update.
Note that you can move certificates between build machines (and may have to if you turn the codebase over to the customer), though you will want to be careful when doing so.

Related

Release application with someone's package name

My question may look strange but I'll try to explain somehow. Let's imagine there is an Android device with software that adjusts some settings based on application package name - it's a real-life scenario. This software may provide better performance for listed applications and there is no way to add my application to that list. What I'm capable of doing is to release my application under one of listed package names (not to Google Play, just provide APK on GitHub so that anyone who wants to use it will install it manually). And there comes my question:
is it legal to use some company's existing package name for my own application? Is it protected legally? My app is free & open source application.
Just to be clear: I'm not doing this to impersonate "real" application with bad intentions. I just want my application to use full range of device capabilities... And download page will state it clearly & visibly :)
In other words: can I release app with package name e.g. com.google.android.talk? I know that it won't override existing app if someone has it installed etc. (it's not my goal to override some application). I'm just talking about such possibility and legality.
This is totally legal, as you can use whatever String you want for your app/package name.
However, just doing this will most probably be not enough to "impersonate" the other app, as this would be a serious security flaw. First of all, there can never be two apps with the same package name installed.
If the app you speak about is created by a "serious" developer, say Google or one of the OEMs, it will check both package and signature of the app and will therefore know your app is not the same as the replaced app.
Also, when the user tries to install your app, a package conflict will happen, followed by the signature conflict. There are two scenarios here:
If the app you are replacing is a standard app, the user will be able to install your app from adb, but only after thay accept to completely wipe the data of the original app. You have probably seen this dialog while developing stuff.
If the app is provided by the OEM and has system permissions, the installation will simply fail, with no possibility to "overwrite" the app. This can be dodged by having the devices rooted, replacing the .apk file in the system directory and restarting the phone.
Please mind that none of the above will work by just uploading the .apk to the phone. This needs to be done from adb. On-phone installer will just fail.

Trouble installing .apk after code change, windows upgrade, and IDE reinstall

This is my first questions on SO, but I would first like to thank the community for helping me along the way in creating a few Android apps. I am not a programmer by profession, and most of the stuff I make is just for fun, but one Android app is a real project that I created for a client, and I've run into some real trouble and need some help.
The app I made basically takes in some data, stores it into an SQL database, and when necessary, uses queries to pull various information from the DB, and displays it. If any adjustments need to be made, I make them and just send them another .apk. No problem, until now...
I recently upgraded to Windows 10, doubled my laptop's RAM and replaced my hard drive with an SSD, and did a refresh of the OS. Everything, including Android Studio, runs like a dream now!!! I had a request from my client to make a few adjustments, so I recopied my backed up source code to my projects folder, opened the code, made the modifications, and resent the .apk to my client. They are getting the following message:
"X App not installed.
An existing package by the same name with a conflicting signature is already installed."
The only changes I made to the app were adding a table to the database (and upgrading the DB version number, of course), and modified some layouts and a couple of methods and calculations, etc. Nothing more. I have searched up and down and have even replicated the same error on my tablet and can't find a way around it. My client currently has a few months worth of data input into the app, so they can't just uninstall it and do a new app installation. Is there anything I can do at this point? Also, I never made any custom key signature, just programmed, made .apk, and have sent numerous updates without issue. Any help would be greatly appreciated. (I have all my project folders and .apks backed up for all the different versions that I have sent)
Thank you!
Your best bet at this point, assuming you can't find/get the original key, is to use a backup program (or adb pull worst case) to backup his /data/data/ folder. Then you can uninstall the original app and reinstall the new version. Then you can restore/adb push the old folder's contents to the phone to restore the data files. This may require rooting it.
If possible I would test this on another phone first, to make sure it works, since you only get 1 shot at this. I would also save your key in your source control repo in the future.

Android signing conflict

I am developing 2 android applications, which are clients for my server. I cannot install both applications on my android phone. I install the first app to phone, everything is ok. Then when I try to install the second app on the phone, I get the message that the application will replace another application (the first one), and then I get following error:
Application not installed: an existing package by the same name with a conflicting signature is already installed.
I mention that I have created one separate keystore file for every application, export them as in the android official signing application guide, then zipaligned them.
So the OS thinks that it is a single application? But in fact there are 2 different apps.
What am I doing wrong?
I think you are using the same package, which is not allowed for two different apps.
But for anyone who have the same error for installing another version on top of previously installed app:
I wanted to test released version of my app when the problem occured. I've had the app previously installed using eclipse, and than I wanted to install the same app but with released signature. I have even uninstalled the app using apps gallery, but the problem persisted.
The solution for me was to unistall the app using Settings->Apps->"the app"->top right corner menu->Uninstall for all users
I had the same error message, but these answers did not help. On a 4.3 nexus 7, I was using a user who was NOT the owner. I had uninstalled the older version but I kept getting the same message.
Solution: I had to login as the owner and go to the settings->apps... Scroll down to the end of the list where my old version was listed with a mark 'not installed'. Select it and press the 'settings' button in the top right corner and finally 'uninstall for all users'
Not sure what happens when you use the same signing key, because in all honesty, I never really tried it.
That being said, as Anand Tiwari, in his comment, has already simplified the answer, you cannot install two different applications with the same package name on one device. They, logically speaking, may be different to you, but for the OS, they are in fact, the same.
The problem also manifests itself when you try to upload the applications to the Android Market (Google Play). Google Play will simply not accept the second application. There is a short and simple explanation by Warren Faith here: https://stackoverflow.com/a/5788664/450534
As an example of how similar applications with a few changes are published to the Google Play store:
The free version of FriendCaster is: https://play.google.com/store/apps/details?id=uk.co.senab.blueNotifyFree
The paid version if the same app is: https://play.google.com/store/apps/details?id=uk.co.senab.blueNotify
Notice the ending of the package names. In this case, you will be able to install both the apps simultaneously on one device.
I think your problem is that both your files have the same package name. You can name both apps with similar packages, but they can't be identical. In fact, using the same package base can be used to communicate between applications ie. App1: com.mypkg.app1 and App2: com.mypkg.app2. However, they both can't be called com.mypkg.app - the package name is how Android identifies apps, and can't be identical.
You should be able to sign as many different apps (assuming their package is different) with the same key.
Make sure not to lose your signing certificate, if you lose it, you will not be able to upload a new app with the same package name. If you lose your signing certificate, you will be in big trouble.
Good luck.

How do I ensure that I run the code I've just installed?

Developing on Android, very often the following happens:
I export a release build of my application, I install it on the device and I run it.
I do some changes. I export it again
I reinstall it on the device
I kill EVERYTHING from the Task Manager
I run the installation again
So I would expect the newly installed version of the application to be run. But instead, I'm still running the old code. I can tell it for sure because I've added some Log.d() traces and they don't show up in the logs.
So, I guess the old version of the classes are still somewhere in memory and the new ones are not loaded until.......... until something.
So what do I have to do (except reboot, please) in order to make sure that when I run the application, I run the newly installed one?
Isn't killing the application enough?
I'd hate to have to uninstall it before reinstall, for several reasons. Or is that the only way?
My suggestion is to keep it in debug mode.
If you are swapping, then yes you need to keep uninstalling.
From what Ive seen, Debug version is exactly the same as the release version, and I only put the release version on at the very end to ensure its all ok, and then to actually release it.
Uninstalling the app, then reinstalling should 100% run the new code. Even things like stored app data would be lost, due to unassociation - different signature (For the exact reason you need to uninstall first).
You can always try increasing the version number, and see if that installs over the top, without the need to uninstall. Something I've not tested, but something that would be quite useful.
Make sure you are building it successfully. And ensure you are taking the correct APK, aka not an old one. (I overwrite my old APK when I build). As long as it was successful, you will have the new code. Maybe your build fails, and so you are mistakingly taking a non-updated APK.
I still recommend Debug mode however. It makes deployment for testing more efficient, and I have not noticed any difference.
Hope some of this helps.

sharedUserId: safe to change when app is already in market?

For the next version of our application, I want to change the sharedUserId since we now use an internal control dashboard app which must write to the other app's settings files.
But since the app is already installed on many phones, will this be a problem? I ran a little test on the emulator, and I'm seeing exceptions in the device logs that *.bak versions of the preference files cannot be written. Not sure how critical that is. Curiously, safing settings still seems to work, even though the shared_prefs folder had been created using another Linux user ID.
Did anyone try this before?
And to answer my own question again:
No, it's not safe. Since updating an app via Android Market will not remove the database and preference files, the new version will not be able to read or write these files (since they were created under a different Linux user ID), and the app will crash after the update. You would have to ask your users to completely uninstall and reinstall the app, which is certainly not recommended.
As a general rule I conclude from this:
Whenever you start out developing a new app, make sure to set a manual android:process and android:sharedUserId attribute! It doesn't hurt in case you don't need it, but it gives you full control over which apps have access to this app's private resources.
No solution as of now, but starring at registered issues might get Google to fix this:
http://code.google.com/p/android/issues/detail?id=1227
http://code.google.com/p/android/issues/detail?id=14074

Categories

Resources