2014-02-13 54 views
5

首先,我已经研究了很多关于我的问题,但找不到合适的解决方案,因此我在此处发布我的查询。希望能够得到更好的解决方案:在卸载应用程序之前询问密码

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

现在,我的问题是,这个活动apppears每个应用程序用户试图卸载。我需要的是我调用的活动,应该只在用户尝试卸载我的应用程序时出现在我的应用程序中。

这里是我的代码:

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); 
+8

我不确定你背后的意图,但从用户的角度来看,我不会喜欢一个应用程序,当我卸载它的时候会问这个应用程序。事实上,我卸载应用程序意味着要么我不满意,要么我有更好的选择,或者可能是别的。不管是什么原因,在这个时候要求一些东西可能会让我更加烦恼。所以要小心。我希望你的意图是好的。 –

+0

@AtolOHolic我认为他们正在试图制造病毒? :) – Deeps

+0

是否记录了软件包名称,并确定您获取软件包名称的方式是否正确? –

回答

1

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

在删除你的应用程序之前,如果它作为设备管理员启用,用户必须首先以管理员身份禁用该应用程序,并且该应用程序收到此广播。

在你的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> 

在接收端,你至少有两个方法值得注意:

@Override 
public CharSequence onDisableRequested(Context context, Intent intent) { 
    … 
} 

@Override 
public void onDisabled(Context context, Intent intent) { 
    … 
} 

你知道这种方式,用户可能会删除你的应用程序。

在设备管理完整的指南是在https://developer.android.com/guide/topics/admin/device-admin.html

+0

感谢您分享设备管理员的代码。如果您安装MyAppSharer并单击将启用设备管理员的应用程序,它将自动打开设备管理员以取消激活,如果用户停用,您可以卸载应用程序。我需要该用户不能卸载,直到他们的密码被记住并输入。 – iMOBDEV

1

如果你有root权限让你的应用系统(从/data/system目录删除您的APK文件)。然后重启设备。重新启动后,您的应用程序无法由用户(而非超级用户)删除。

1

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

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

但是可能会有一些非常脏的可能性,我没有测试到最后:您可以使用隐藏的三个参数版本ActivityManager.getRunningTasks [2]注册隐藏接口IThumbnailReceiver [1]。看起来只需要GET_TASKS权限来获取缩略图(参见[3])。应该有可能找出哪些应用程序将从应用程序缩略图中删除... - 但由于此解决方案使用隐藏的API,因此不能保证它可以与较旧/较新/适用的Android版本兼容。

  1. https://github.com/omnirom/android_frameworks_base/blob/android-4.4/core/java/android/app/IThumbnailReceiver.aidl
  2. https://github.com/omnirom/android_frameworks_base/blob/android-4.4/core/java/android/app/ActivityManager.java#L766
  3. https://github.com/omnirom/android_frameworks_base/blob/android-4.4/services/java/com/android/server/am/ActivityManagerService.java#L6725
5

你应该尝试类似以下内容:

月1日 - 宣布你的广播recevier该清单文件中,将听取QUERY_PACKAGE_RESTART:

<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> 

2日 - 您UnunstallIntentReceiver Java类像下面这样:

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 
       } 
      } 
     } 
    } 

    } 

,并请给我一些反馈

希望帮助。

+0

这个可以正常使用2.3,但不能与4.x一起使用 – Nizam

+0

如何在输入密码后继续卸载? – 2014-08-08 20:30:21

+0

6.0或以上版本无法正常工作,是否需要任何权限? –

相关问题