android - How can an app detect that it's going to be uninstalled? -
this question has answer here:
all know usual (in practice any) antivirus application before uninstall used fire simple dialog like: "you're going uninstall app, sure?" - "yes/no".
yes, know can intercept package delete intent using intent-filter like:
<activity android:name=".uninstallintentactivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.view" /> <action android:name="android.intent.action.delete" /> <category android:name="android.intent.category.default" /> <data android:scheme="package" /> </intent-filter> </activity>
but problem in simple fact intercepts any delete requests , fire chooser dialog between app , stock installer. if user select stock installer - won't able anything.
my goal not prevent user uninstalling of app, rollback changes made app.
learning antivirus apps see kind of operation possible, please me , explain how possible?
update
since there guys doesn't believe it's real - refer avast mobile security:
anti-theft protects uninstall disguising components various self-preservation techniques.
another example: kaspersky internet security android - here's special procedure uninstalling it, requires entering of secret code.
anyway means there's way intercept uninstallation procedure in order either prevent uninstall or finalizing job.
okay. have been investigating lot on problem since 2 days , found "wild way" solve without rooting device :)
first, here highlights achieve solution:
1. whenever user goes settings -> manage apps -> selects particular application receive broadcast android.intent.action.query_package_restart name of application's package extras.
2. after when click on uninstall button (with package installer), opens activity named - com.android.packageinstaller.uninstalleractivity
control flow like:
under app settings user clicks on uninstall button ---> control show dialogue / start activity / etc ---> finish our pre-uninstallation task ---> user returned uninstallation confirmation screen ---> user confirms , uninstalls app
used method:
we implement broadcastreceiver in our application listening action "android.intent.action.query_package_restart" , match our package name inside onreceive() method. if broadcast received selection of our desired application package, we'll initiate background thread keep monitoring foreground running activities using activitymanager.
once find foreground activity "com.android.packageinstaller.uninstalleractivity", it'll confirm user wants uninstall our application. @ point we'll perform desired tasks (either display dialogue, or start activity overlapping uninstallation window, etc..) performed before uninstallation. after performing our task, we'll allow user continue confirming uninstallation process.
implementation / source code:
in manifest.xml
add permission:
<uses-permission android:name="android.permission.get_tasks"/>
and broadcast receiver:
<receiver android:name=".uninstallintentreceiver"> <intent-filter android:priority="0"> <action android:name="android.intent.action.query_package_restart" /> <data android:scheme="package" /> </intent-filter> </receiver>
uninstallintentreceiver.java (broadcast receiver class)
public class uninstallintentreceiver extends broadcastreceiver{ @override public void onreceive(context context, intent intent) { // fetching package names extras string[] packagenames = intent.getstringarrayextra("android.intent.extra.packages"); if(packagenames!=null){ for(string packagename: packagenames){ if(packagename!=null && packagename.equals("your_application_package_name")){ // user has selected our application under manage apps settings // initiating background thread watch activity new listenactivities(context).start(); } } } } }
listenactivities class - monitoring foreground activities
class listenactivities extends thread{ boolean exit = false; activitymanager = null; context context = null; public listenactivities(context con){ context = con; = (activitymanager) context.getsystemservice(context.activity_service); } public void run(){ looper.prepare(); while(!exit){ // info running task list< activitymanager.runningtaskinfo > taskinfo = am.getrunningtasks(max_priority); string activityname = taskinfo.get(0).topactivity.getclassname(); log.d("topactivity", "current activity ::" + activityname); if (activityname.equals("com.android.packageinstaller.uninstalleractivity")) { // user has clicked on uninstall button under manage apps settings //do whatever pre-uninstallation task want perform here // show dialogue or start activity or database operations etc..etc.. // context.startactivity(new intent(context, mypreuninstallationmsgactivity.class).setflags(intent.flag_activity_new_task)); exit = true; toast.maketext(context, "done preuninstallation tasks... exiting now", toast.length_short).show(); } else if(activityname.equals("com.android.settings.manageapplications")) { // button pressed , user has been taken manage applications window // should close activity monitoring exit=true; } } looper.loop(); } }
known limitations:
when user clicks on uninstall button under manage apps settings, we'll perform our pre-uninstallation tasks , promt user confirmation window user can either confirm uninstall or can cancel operation.
the approach described above of not covering case if user clicks on cancel button after have performed our task. tackled ammendments.
e.g.: can implement logic revert changes made if broadcast "android.intent.action.package_removed" not received in end.
i hope approach helpful :) way in opinion can solve problem without rooting device!
[update 1]: suggested approach check if uninstallation task canceled:
its kind of funny had entirely different , complex idea earlier(involving broadcasts, activitymanager, etc.. etc..), while writing here idea struck mind comparatively simple :)
when user clicks on uninstall button under manage apps settings , after have performed pre-uninstallation tasks, set sharedpreference in app have performed pre-uninstall tasks , ready uninstallation. after need not care anything.
if user continues uninstall -> , have performed required tasks.
while if user clicks on cancel button , goes away -> don't bother. until user goes , run application again. inside "onstart()" / "onresume()" of application's main activity, can check sharedpreference's value , if set uninstallation, mean user didn't proceeded uninstallation. , revert changes made earlier(reversing pre-uninstall tasks performed) ensure application runs perfectly!
Comments
Post a Comment