Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在卸载应用程序之前请求密码_Android_Service_Uninstallation - Fatal编程技术网

Android 在卸载应用程序之前请求密码

Android 在卸载应用程序之前请求密码,android,service,uninstallation,Android,Service,Uninstallation,首先,我已经研究了很多关于我的问题,但我找不到一个合适的解决方案,所以我把我的疑问发布在这里。希望得到更好的解决方案: 我有一个要求,在用户从设置或任何其他应用程序(如MyAppSharer)中删除我的应用程序之前,我需要向用户请求密码。我找到了一个解决方案,当用户单击卸载按钮时,我可以成功地调用我的活动。我在这里应用了这个技巧,并呼叫服务。在服务中,我运行计时器,它每1秒运行一次,在这1秒中,它检查运行任务的最顶层活动。这正按照预期完美运行 现在,我的问题是,每个用户尝试卸载的应用程序上都会出

首先,我已经研究了很多关于我的问题,但我找不到一个合适的解决方案,所以我把我的疑问发布在这里。希望得到更好的解决方案:

我有一个要求,在用户从设置或任何其他应用程序(如MyAppSharer)中删除我的应用程序之前,我需要向用户请求密码。我找到了一个解决方案,当用户单击卸载按钮时,我可以成功地调用我的活动。我在这里应用了这个技巧,并呼叫服务。在服务中,我运行计时器,它每1秒运行一次,在这1秒中,它检查运行任务的最顶层活动。这正按照预期完美运行

现在,我的问题是,每个用户尝试卸载的应用程序上都会出现此活动。我需要的活动,我调用,应该只出现在我的应用程序,当用户试图卸载我的应用程序

这是我的密码:

public static final String PACKAGE_INSTALLER = "com.android.packageinstaller";
public static final String PACKAGE_INSTALLER_UNINSTALL_ACTIVITY = "com.android.packageinstaller.UninstallerActivity";


alarmTimer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);;
            ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;

            final String packageName = topActivity.getPackageName();
            String className = topActivity.getClassName();

            Log.v(TAG, "packageName:" + packageName);
            Log.v(TAG, "className:" + className);

            if (PACKAGE_INSTALLER.equals(packageName)
                && PACKAGE_INSTALLER_UNINSTALL_ACTIVITY.equals(className)) {

                //Here I need to apply one condition where package name received to be matched with my package name. But I am not sure how to fetch package name of selected application for uninstalling 
                //To Cancel Existing UninstallerActivity and redirect user to home.
                Intent homeIntent = new Intent();
                homeIntent.setAction(Intent.ACTION_MAIN);
                homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                homeIntent.addCategory(Intent.CATEGORY_HOME);
                startActivity(homeIntent);

                //To open my activity
                    Intent loginActivity = new Intent(UninstallService.this, Act_Login.class);
                    loginActivity.putExtra(Constants.KEY_IS_FROM_SERVICE, true);
                    loginActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(loginActivity); 

            }
        }
    }, 0, 1000);

如果这是公司的要求(如果你想阻止普通用户卸载你的应用程序,没有机会,感谢谷歌保护我们免受不良开发者的攻击),你应该创建一个设备管理员应用程序。这样,虽然用户仍然可以删除该应用程序,但如果你想防止意外删除,这只是额外的一步

在删除应用程序之前,如果以设备管理员身份启用应用程序,则用户必须首先以管理员身份禁用应用程序,应用程序将接收此广播

在XML中,将

<activity android:name=".app.DeviceAdminSample"
            android:label="@string/activity_sample_device_admin">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.SAMPLE_CODE" />
    </intent-filter>
</activity>
<receiver android:name=".app.DeviceAdminSample$DeviceAdminSampleReceiver"
        android:label="@string/sample_device_admin"
        android:description="@string/sample_device_admin_description"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin"
            android:resource="@xml/device_admin_sample" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>
这样你就知道用户可能会删除你的应用程序


如果您有根权限使您的应用程序成为系统(将apk文件从
/data
目录删除到
/system
目录),则完整的设备管理指南位于。然后重新启动设备。重新启动后,用户(不是超级用户)无法删除您的应用程序。

我看到的唯一方法是提供您自己的卸载程序作为应用程序的一部分(=列出所有应用程序并允许卸载它们的活动)。然后,您的服务可以检查您的应用程序是否是启动packageinstaller的应用程序,如果不是,则重定向用户

如果没有根用户或系统应用程序,就无法获取卸载程序活动数据(至少在我测试的Android 4.4上是如此)。这是因为卸载程序不是作为独立任务调用的,而是作为启动任务堆栈上的活动调用的(从设置等卸载时是设置应用程序)。您只能看到调用任务的任务详细信息

然而,可能还有一些非常糟糕的可能性,我没有测试到底:您可以使用隐藏的三参数版本的
ActivityManager.getRunningTasks
[2]注册隐藏接口
IThumbnailReceiver
[1]。抓取缩略图似乎只需要GET_TASKS权限(参见[3])。应该可以从应用程序缩略图中找出要删除的应用程序…-但由于该解决方案使用隐藏的API,因此无法保证它能与较旧/较新/供应商提供的Android版本一起使用


  • 您应该尝试以下方法:

    public class UninstallReceiver 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("application_package")){
                       // start your activity here and ask the user for the password 
                    }
                }
            }
        }
    
        }
    
    1-在清单文件中声明您的广播接收器,它将侦听查询\u包\u重新启动:

      <receiver android:name=".UninstallReceiver">
              <intent-filter android:priority="999999">
                    <action android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
                    <data android:scheme="package" />
              </intent-filter>
         </receiver>
    
    请给我一些反馈


    希望有帮助

    我不知道你的意图背后,但从用户的角度来看,我不会喜欢一个应用程序,将要求的东西,当我卸载它。事实上,我正在卸载该应用程序,这意味着要么我对它不满意,要么我有更好的选择,要么可能是其他原因。不管是什么原因,在这个时候要求一些东西可能会让我更加恼火。所以要小心。我希望你的意图是好的。@AtulOHolic我想他们想制造一种病毒?:)您是否记录了软件包名称,并查看您获取软件包名称的方式是否正确?我只想从设备中删除apk文件,以避开您的奇怪检查。或者我只需在您的服务上运行
    pm disable
    ,然后卸载。在卸载应用程序之前询问密码是一种糟糕的做法感谢为设备管理员共享代码。如果安装MyAppSharer并单击将启用设备管理的应用程序,它将自动打开设备管理以停用,如果用户停用,则可以卸载应用程序。我需要该用户在记住并输入密码之前无法卸载。此版本适用于2.3,但不适用于4。xIt不适用于6.0或更高版本,是否需要任何权限?
    public class UninstallReceiver 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("application_package")){
                       // start your activity here and ask the user for the password 
                    }
                }
            }
        }
    
        }