I want to install the apk from internal/external memory after uninstalling the same apk.?(actually i want to update my apk,if i directly(don't uninstall the current apk) install my updated apk then there comes signature issue.)
final Intent installIntent = new Intent(Intent.ACTION_VIEW);
if (isSDPresent) {
installIntent.setDataAndType(Uri.fromFile(new File("/storage/sdcard1/Download/" + "Life.apk")), "application/vnd.android.package-archive");
}else {
installIntent.setDataAndType(Uri.fromFile(new File("/storage/emulated/0/Download/" + "Life.apk")), "application/vnd.android.package-archive");
}
installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(installIntent);
The behaviour you are seeing is by design.
Android does not allow any code within an APK to be run once the user chooses to remove it - there are no notifications and no pre-uninstall actions that you can use. It's designed that way to prevent developers from writing Apps that can never be uninstalled by the user.
Having two apps with the same package name but signed with different keys is also not allowed, and can only be resolved by the user manually removing the first app before installing the second. This is to prevent developers from writing Apps to imitate other Apps (like Facebook for example) without the user knowing about it.
You can update your apk using below command that will upgrade application that is exactly same as when you perform Update from google play store.
adb install -r foo.apk
Related
I'm going to develop an android app for a museum, which will handle a tablet with the app installed on it to the visitors.
The app will be on foreground full time and visitor will only be able to use this app.
Since there will be many tablets, and they are all under our control, I would like a way to update all the tablets remotly with the last version of the app.
Is there a way to achive this?
Is there a way to achive this?
Answer is : Yes but with one exception lets have a look.
Step 1 : Create a local server for your museum. I guess it is already in the museum.
Step 2 : Now In your android application whenever you start your app check that whether new version of APK is available. For checking APK new version you can use this code.
PackageInfo packageInfo = getPackageManager().getPackageInfo(context.getPackageName(), 0);
int apkVersion = packageInfo.versionCode;
You should set your APK name like "yourAppname_version" so whenever you upload the new app to your local server just change the name so you can easily identify that new version of APK is available or not.
Step 3 : If new version is available then start downloading APK from the local server and save it to your storage directory.
Step 4 : When downloading completed you can call this set of code to install the new APK.
Intent intentApkInstall = new Intent(Intent.ACTION_VIEW);
intentApkInstall.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/"+"yourAppname_version.apk")), "application/vnd.android.package-archive");
intentApkInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intentApkInstall);
Now the Exception part is here the above code will prompt user to install APK. So in this case you have to install it manually.
Once an update to app is submitted in Google play developer console and the app is visible to all users, how much time would it take for any device to pick the update? (Assuming active internet wifi connection is throughout the day and auto-update is on for this app)
Can I programmatically initiate a request to Google play store regarding the update WITHOUT ANY USER PROMPT OR ANY INTERACTION? (Assuming no new permissions are requested while updating). If so, please suggest how.
Other information: My app is designed for digital signage using android boxes. App is launched on startup, occupies the screen. There will not be any sort of user interaction directly with the app during its lifetime.
Usually update is installed within 24 hours, provided the user maintains active connection with internet and sufficient battery. Android boxes do not have any battery, so automatic updates via google play (without any user interaction) are not reliable.
Use this code for issuing auto update without playstore.
Add this permission: <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
Use the following function:
public static void installAPK(String filename) {
File file = new File(filename);
if (file.exists()) {
Runtime.getRuntime().exec("chmod 777 " + filename);
String command;
command = "pm install -r " + filename;
Process proc = Runtime.getRuntime().exec(new String[]{"su", "-c", command});
proc.waitFor();
}
}
Note: This would work only if you are not requesting any extra permissions for the app since last install.
It depends on Google's back end replicating your new update, usually within 8-24 hours.
No, that would be a security vulnerability. Apps are not permitted to install or update themselves without user interaction.
I have been through this many times.
1> It usually took me for about 2 - 4hrs to get my app updated on google play.
2> I think you are talking about force update. What I did for this was that
I made an api for checking the version of app. And according to it I redirected to update screen in google play . I hope it helps.
// Here min_supported_version is generated from api
if (min_supported_version <= BuildConfig.VERSION_CODE) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=yourpackagename")));
}
I'm trying to find a solution to do a remote update of an APK to 80 tablets. This should preferably be as automated as possible and if this can happen completely in the background without any user input that would be great. Basically what the Playstore currently do which I unfortunately can't use.
Is something like this possible without rooting the device? Any suggestion on libraries/ services that does this?
I'm running Android 4.1.1 and they will all be connected to a Wi-Fi.
You can download the new APK file to SD card, then call this to install it:
Intent shareIntent = new Intent(Intent.ACTION_VIEW);
shareIntent.setDataAndType(Uri.fromFile(new File("path-to-APK-file")),
"application/vnd.android.package-archive");
try {
context.startActivity(shareIntent);
} catch (Throwable t) {
// handle the exception here
}
There is only one thing not automatic: the final step. The system will ask the user to confirm installation.
About the MIME type of APK files, here's the wiki page.
No, in the background isn't possible without rooting or having the device's signing key at least as a standard Android APK update. The only semi-reasonable way I can envision something similar to this working is for your app to always check for/download code to run which you load using a class loader. This would be a significant amount of work and not easy.
However, if you're willing to live with some user interaction, it really shouldn't be that hard (though it'll still take some building of infrastructure). Keep a web service that returns the latest version number, compare with the current version number and download the new APK as necessary. Installing an APK programmatically has been covered in many SO questions.
I'm developing a non-public Android app, i.e. the app won't be available in the global Android Market. The app will be installed on a limited number of clients, e.g. by using an apk file.
How can I enable an auto-update functionality in this app?
I see different potential options (I do not know if those are technically hard or even impossible to implement or if there are any existing functionalities that can be reused):
On each launch the app tests if a new version exists (by requesting a server), if so downloads the new apk and replaces itself with the new version.
Use (or develop?) a separated app or service that undertakes the update-check and replacement-process.
Use (or develop?) a private market app which has an auto-update option. This option is similar to the second one, but more generic: The market app would be connected to a repository, i.e. it would handle an arbitrary number of (private) apps.
I would prefer option one since the auto-update functionality is included in the app which needs less development efforts.
janjonas, in the company I work we had a similar problem with Windows Mobile 6.x, and we use pretty much the same solution pointed by EboMike:
The main app check if it's updated, against a WebService. It receives the current version & the URL from where download the new version, if necessary. The main app then start the Updater app, passing the URL, and quit.
The Updater do the download of the new program, via HTTP, showing to the user the % downloaded. The user can cancel the download anytime, in a controlled way, and the Updater can registry this cancellation.
Since the new app is downloaded, the Updater run the new app, and quit.
I think option one is the least amount of work for you, and actually the cleanest one too since it will go through the proper channel of using Android's built-in package installer which includes user notification and the option for the user to abort the installation if desired.
You already have it all outlined - check for a new version on a server (would be nice to give the user the option to turn that off), and if there is a new version, you could either just link to the URL with the APK (which will, IIRC, use the browser's download manager to download it), or you could download it with your app and then point the intent to your local file. Using the HTTP link is technically less work and cleaner - the more you let the operating system do, the better - unless there's a reason not to.
Enabling "Install non-market app" is still needed for any application outside the Google Play. If it not enabled, the installation process is going to ask for it and redirect the user to the Application Settings, and after that, the user can install the app.
Depending on your needs, you can delegate to a third part lib.
Some of the permissions we'll use to get this done are the following:
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Let me explain a bit... The last, WRITE_EXTERNAL_STORAGE, is self-explanatory. With ACCESS_SUPERUSER we'll tell the system that we intend to use root privileges. READ_EXTERNAL_STORAGE will be needed in the future in order for your app to read files on SD card.
Assuming that you have downloaded the file and that all those devices can be rooted (limited number of clients, not on Play, etc.), you could do this:
String filePath = Environment.getExternalStorageDirectory().toString() + "/your_app_directory/your_app_filename.apk";
Process installProcess = null;
int installResult = -1337;
try {
installProcess = Runtime.getRuntime().exec("su -c pm install -r " + filePath);
} catch (IOException e) {
// Handle IOException the way you like.
}
if (installProcess != null) {
try {
installResult = installProcess.waitFor();
} catch(InterruptedException e) {
// Handle InterruptedException the way you like.
}
if (installResult == 0) {
// Success!
} else {
// Failure. :-/
}
} else {
// Failure 2. :-(
}
Here might be a very lame method but for some companies, if you believe its applicable, this might be very easy to implement.
Create an password screen (passwordActivity) that asks a password to access the application.
Once the password is entered, raise a flag (set a boolean value from false to true using sharedpreferences)
Place the .apk file on Google Store.
Change the password once everyone installs the app, and release a new update on Google Play Store.
Since the software is going to cache the flag value, the password screen won`t show up even the password is change. It will only show up for new installations so might need to repeat the process.
Note: This method might better fit if there is not hundreds of users using the application. And don`t forget this method is also not secure. To sum up, if you are looking a way to keep the application private and have no security concerns, this is what I recommend.
Update app
Make sure that you already have your new apk download on location
void installNewVersion(String location) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(location + "app-debug.apk")),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Can a package uninstall itself? Can a package uninstall another package if they share the same userId and signature?
Uri packageURI = Uri.parse("package:"+"your.packagename.here");
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
A 3rd party app cannot install or uninstall any other packages programmatically, that would be a security risk for Android. However a 3rd party app can ask the Android OS to install or uninstall a package using intents, this question should provide more complete information:
install / uninstall APKs programmatically (PackageManager vs Intents)
In Kotlin, using API 14+, you can just call the following:
startActivity(Intent(Intent.ACTION_UNINSTALL_PACKAGE).apply {
data = Uri.parse("package:$packageName")
})
Or with Android KTX:
startActivity(Intent(Intent.ACTION_UNINSTALL_PACKAGE).apply {
data = "package:$packageName".toUri()
})
It will show the uninstall prompt for your app. You can change packageName to any package name of another app if needed.
Third Party app cannot Uninstall App Silently!
Either you need to become System App to get DELETE_PACKAGES Permission else you need to show Uninstall Popup (User Confirmation)
Alternatively, you can take Accessibility permission and then by showing an Accessibility Overlay you can tell your service to click on Uninstall button! But that will be privacy violation.