앱이 제거 될 것임을 어떻게 감지 할 수 있습니까?
이 질문에 이미 답변이 있습니다.
- Android 앱 제거를 감지 할 수 있습니까? 7 답변
- Android 4 답변 에서 제거 작업 수행
제거하기 전에 일반적인 (실제로 모든) 바이러스 백신 응용 프로그램은 "앱을 제거 할 것입니다. 확실합니까?"와 같은 간단한 대화 상자를 실행하는 데 사용되었습니다. - "예 아니오".
예, 다음과 같은 인 텐트 필터를 사용하여 패키지 삭제 인 텐트를 가로 챌 수 있다는 것을 알고 있습니다.
<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>
그러나 문제는 이것이 모든 삭제 요청을 가로 채고 내 앱과 스톡 설치 프로그램간에 선택기 대화 상자를 실행 한다는 단순한 사실입니다 . 따라서 사용자가 재고 설치 프로그램을 선택하면 아무것도 할 수 없습니다.
내 목표는 사용자가 내 앱을 제거하지 못하도록하는 것이 아니라 내 앱에서 변경 한 사항을 롤백하는 것입니다.
이러한 바이러스 백신 앱을 통해 배우는 것은 이런 종류의 작업이 가능하다는 것을 알았으므로 어떻게 가능한지 설명하고 도와주세요.
최신 정보
그것이 진짜라고 믿지 않는 사람들이 있기 때문에 Avast Mobile Security를 언급하겠습니다 .
Anti-Theft는 다양한자가 보존 기술로 구성 요소를 위장하여 제거로부터 스스로를 보호합니다.
또 다른 예 : Android 용 Kaspersky Internet Security- 여기 에 비밀 코드를 입력해야하는 제거를위한 특별한 절차가 있습니다.
어쨌든 그것은 제거를 방지하거나 일부 마무리 작업을 수행하기 위해 제거 절차를 가로 챌 수있는 방법이 있음을 의미합니다.
괜찮아. 2 일부터이 문제에 대해 많은 조사를 해왔고 마침내 장치를 루팅하지 않고 해결할 수있는 "야생적인 방법"을 찾았습니다. :)
먼저 솔루션을 달성하기위한 주요 사항은 다음과 같습니다.
1. 사용자가 설정-> 앱 관리-> 특정 애플리케이션을 선택할 때마다 애플리케이션 패키지 이름과 함께 브로드 캐스트 android.intent.action.QUERY_PACKAGE_RESTART 를 추가로 수신합니다.
2. 그런 다음 제거 버튼 (패키지 설치 프로그램 포함) 을 클릭하면 com.android.packageinstaller.UninstallerActivity 라는 활동이 열립니다.
제어 흐름은 다음과 같습니다.
앱 설정에서 사용자가 제거 버튼을 클릭합니다 ---> 대화를 표시하거나 다른 활동을 시작하는 등의 제어권을 얻습니다 ---> 사전 제거 작업을 완료합니다 ---> 사용자가 제거 확인 화면으로 돌아갑니다- -> 사용자가 앱을 확인하고 제거합니다.
사용 된 방법 :
" android.intent.action.QUERY_PACKAGE_RESTART " 작업을 수신하기 위해 애플리케이션에서 BroadcastReceiver를 구현하고 onReceive () 메서드 내에서 패키지 이름을 일치시킵니다. 원하는 애플리케이션 패키지를 선택하기 위해 브로드 캐스트가 수신 된 경우 ActivityManager를 사용하여 포 그라운드 실행 활동을 계속 모니터링하는 백그라운드 스레드를 시작합니다.
포 그라운드 활동이 " com.android.packageinstaller.UninstallerActivity "인 것을 확인하면 사용자가 애플리케이션을 제거 할 것인지 확인합니다. 이 시점에서 제거 전에 수행 할 원하는 작업 (대화 상자 표시 또는 제거 창과 겹치는 다른 작업 시작 등)을 수행합니다. 작업을 수행 한 후 사용자가 제거 프로세스를 계속 확인할 수 있습니다.
구현 / 소스 코드 :
manifest.xml에서
권한 추가 :
<uses-permission android:name="android.permission.GET_TASKS"/>
및 방송 수신기 :
<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 (브로드 캐스트 수신자 클래스)
public class UninstallIntentReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// fetching package names from 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 the Manage Apps settings
// now initiating background thread to watch for activity
new ListenActivities(context).start();
}
}
}
}
}
ListenActivities 클래스 -포 그라운드 활동 모니터링 용
class ListenActivities extends Thread{
boolean exit = false;
ActivityManager am = null;
Context context = null;
public ListenActivities(Context con){
context = con;
am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
}
public void run(){
Looper.prepare();
while(!exit){
// get the info from the currently 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 the Uninstall button under the Manage Apps settings
//do whatever pre-uninstallation task you want to perform here
// show dialogue or start another 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 with preuninstallation tasks... Exiting Now", Toast.LENGTH_SHORT).show();
} else if(activityName.equals("com.android.settings.ManageApplications")) {
// back button was pressed and the user has been taken back to Manage Applications window
// we should close the activity monitoring now
exit=true;
}
}
Looper.loop();
}
}
알려진 제한 :
When the user clicks on the Uninstall button under Manage Apps settings, we'll perform our pre-uninstallation tasks and then promt the user to the Confirmation window where user can either confirm to uninstall or can Cancel the operation.
The approach described above is as of now not covering the case if user clicks on Cancel button after we have performed our task. But this could be tackled easily with some ammendments.
E.g.: We can implement a logic to revert the changes we made if the broadcast "android.intent.action.PACKAGE_REMOVED" was not received in the end.
I hope this approach will be helpful to you :) As this is the only way in my opinion we can solve your problem without rooting the device!
[Update 1]: Suggested Approach to check if the Uninstallation task was Canceled:
Its kind of funny that I had entirely different and much complex idea earlier(involving broadcasts, ActivityManager, etc.. etc..), but while writing it here just another idea struck into my mind which is comparatively very simple :)
When the User clicks on Uninstall button under Manage Apps settings and after you have performed your pre-uninstallation tasks, you just set some SharedPreference in your app that you have performed the pre-uninstall tasks and are ready for uninstallation. After this you need not to care about anything.
If the user continues to uninstall -> its well and good as you have already performed required tasks.
While if user finally clicks on Cancel button and goes away -> don't bother. Until the user goes and run your application again. Now inside "onStart()" / "onResume()" of your application's main activity, you can check the SharedPreference's value and if it was set for uninstallation, that will mean that user didn't finally proceeded with the uninstallation. And now you could revert the changes made earlier(reversing the pre-uninstall tasks performed) to ensure that your application runs perfectly!
It is simply not possible in Android
There's no way for your application to know that it is being uninstalled (without modifying the kernel). All files created in the data/data/your.app.package is deleted automatically upon install.
Another approach could be to have another application that checks whether this application is installed or not. If not, it can do the clean-up work.
UPDATE
The ACTION_PACKAGE_REMOVED intent will be sent out to all receivers except for your own. This is confirmed HERE.
UPDATE 2
Just Another thought.
as I searched for this on I found that, this can be done by monitoring logcat for your application here is a sample logcat monitor
Good thing is that to monitor logcat for same application we need not have a rooted device
and as we read each entry in logcat we can search for following string
Received broadcast Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.package.name flg=0x8000010 (has extras) }
as this event is received we know that our app is now going to be un installed
Did not try though
Again monitoring logcat is not allowed from Android Jellybean
Up to Android 5.0 there was option for detecting app uninstall is using native code:
You need to monitor for Your directory using inotify
framework in forked process. When it's deleted You can run some system command eg. am
command that starts Intent
PoC of such solution: https://github.com/pelotasplus/ActionAfterUninstall/blob/master/app/src/main/jni/hello-jni.c
In order to make your app persist you'll need to have a rooted device and be able to install it to the system partition. Once it's on there you can uninstall the updates, since they are saved along side non-system apps, but it's not as cut and dry to uninstall it from the system.
I know some of them will also save a little bit of data on the system partition just in case the devices is factory reset, but there are also ways to get the package manager to leave behind your saved data in the event that it is just uninstalled.
Another option would be to register it as a device administrator. Once you do that they will be unable to uninstall it unless they manually remove it's admin status.
<item name="android.permission.ACCESS_SUPERUSER" />
Here it looks like they're using root as well as other methods. Short of making some crazy elaborate service, which it appears they may have, there is no legitimate way to do this any other way.
Taking advantage of root is almost standard practice for AV/security apps like this, without it they don't have any real authority over any other apps so they're very limited. I think the SuperUser permission isn't shown unless you have it installed either, so many people are still unaware it's an option.
<perms>
<item name="android.permission.READ_EXTERNAL_STORAGE" />
<item name="android.permission.GET_TASKS" />
<item name="android.permission.PROCESS_OUTGOING_CALLS" />
<item name="android.permission.WRITE_EXTERNAL_STORAGE" />
<item name="android.permission.WRITE_CALL_LOG" />
<item name="com.avast.android.generic.CENTRAL_SERVICE_PERMISSION" />
<item name="android.permission.WRITE_SMS" />
<item name="android.permission.ACCESS_WIFI_STATE" />
<item name="android.permission.RECEIVE_SMS" />
<item name="android.permission.GET_ACCOUNTS" />
<item name="android.permission.READ_CONTACTS" />
<item name="android.permission.CALL_PHONE" />
<item name="android.permission.WRITE_CONTACTS" />
<item name="android.permission.READ_PHONE_STATE" />
<item name="android.permission.READ_SMS" />
<item name="android.permission.RECEIVE_BOOT_COMPLETED" />
<item name="android.permission.ACCESS_SUPERUSER" />
<item name="com.avast.android.mobilesecurity.permission.C2D_MESSAGE" />
<item name="android.permission.GET_PACKAGE_SIZE" />
<item name="android.permission.WAKE_LOCK" />
<item name="android.permission.ACCESS_NETWORK_STATE" />
<item name="android.permission.USE_CREDENTIALS" />
<item name="android.permission.SEND_SMS" />
<item name="android.permission.RECEIVE_MMS" />
<item name="com.google.android.c2dm.permission.RECEIVE" />
<item name="android.permission.KILL_BACKGROUND_PROCESSES" />
<item name="com.android.vending.BILLING" />
<item name="android.permission.WRITE_SETTINGS" />
<item name="android.permission.INTERNET" />
<item name="android.permission.VIBRATE" />
<item name="android.permission.READ_CALL_LOG" />
<item name="com.avast.android.generic.COMM_PERMISSION" />
<item name="com.dolphin.browser.permission.ACCESS_PROVIDER" />
<item name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
</perms>
참고URL : https://stackoverflow.com/questions/18692571/how-can-an-app-detect-that-its-going-to-be-uninstalled
'Programing' 카테고리의 다른 글
SQL의 삭제 문이 매우 느립니다. (0) | 2020.11.14 |
---|---|
Git : 오류 : RPC가 실패했습니다. (0) | 2020.11.14 |
iOS 7 UISearchDisplayController 검색 표시 줄이 검색하는 동안 상태 표시 줄과 겹칩니다. (0) | 2020.11.14 |
언제 StringBuilder를 사용합니까? (0) | 2020.11.14 |
Java로 XSLT 처리? (0) | 2020.11.14 |