2014-02-13 56 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或以上版本無法正常工作,是否需要任何權限? –

相關問題