Android應用如何監聽本身是否被卸載及卸載反饋功能的實現

一個應用被用戶卸載確定是有理由的,而開發者卻未必能得知這一重要的理由,畢竟用戶不多會主動反饋建議,多半就是用得不爽就卸,若是能在被卸載後獲取到用戶的一些反饋,那對開發者進一步改進應用是很是有利的。目前據我所知,國內的Android應用中實現這一功能的只有360手機衛士、360平板衛士,那麼如何實現這一功能的?html

  咱們能夠把實現卸載反饋的問題轉化爲監聽本身是否被卸載,只有得知本身被卸載,才能夠設計相應的反饋處理流程。如下的列表是我在研究這一問題的思路:android

  1,註冊BroadcastReceiver,監聽"android.intent.action.PACKAGE_REMOVED"系統廣播git

  結果:NO。未寫代碼,直接分析,卸載的第一步就是退出當前應用的主進程,而此廣播是在已經卸載完成後才發出的,此時主進程都沒有了,去哪onReceive()呢?安全

  2,若能收到"將要卸載XX包"的系統廣播,在主進程被退出以前就搶先進行反饋處理就行了,惋惜沒有這樣的系統廣播,不過通過調研,卻是發現了一個辦法,讀取系統log,當日志中包含"android.intent.action.DELETE"和本身的包名時,意味着本身將要被卸載。學習

  結果:NO。調試時發現此方法有兩個缺陷,(1)點擊設置中的卸載按鈕即發出此Intent,此時用戶還沒有在彈框中確認卸載;(2)pm命令卸載不出發此Intent,意味着被諸如手機安全管家,豌豆莢等軟件卸載時,沒法提早得知卸載意圖。測試

  3,因爲時間點不容易把控,因此乾脆不依賴系統廣播或log,考慮到卸載過程會刪除"/data/data/包名"目錄,咱們能夠用線程直接輪詢這個目錄是否存在,以此爲依據判斷本身是否被卸載。spa

  結果:NO。同方法1,主進程退出,相應的線程一定退出,線程還沒等到判斷目錄是否存在就已經被銷燬了。線程

  4,改用C端進程輪詢"/data/data/包名"目錄是否存在設計

  結果:YES。藉助Java端進程fork出來的C端進程在應用被卸載後不會被銷燬。調試

  OK,上代碼!

Activity啓動時fork出C端進程輪詢目錄:

複製代碼
                 UninstalledMoniterActivity               String TAG = "UninstalledMoniterActivity"                                     Log.d(TAG, "load libuninstalled_moniter"         System.loadLibrary("uninstalled_moniter"                                Log.d(TAG, "onCreate"                           }
複製代碼

核心——native方法頭文件:

複製代碼
  #include <jni.h> #include <stdio.h> #include <.h> #include <android/log.h> #include <unistd.h>      MEM_ZERO(pDest, destSize) memset(pDest, 0, destSize)    LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg)  LOG_DEBUG(tag, msg) __android_log_write(ANDROID_LOG_DEBUG, tag, msg)  LOG_WARN(tag, msg) __android_log_write(ANDROID_LOG_WARN, tag, msg)  LOG_ERROR(tag, msg) __android_log_write(ANDROID_LOG_ERROR, tag, msg)     _Included_main_activity_UninstalledMoniterActivity       main_activity_UninstalledMoniterActivity_MODE_PRIVATE  main_activity_UninstalledMoniterActivity_MODE_PRIVATE 0L  main_activity_UninstalledMoniterActivity_MODE_WORLD_READABLE  main_activity_UninstalledMoniterActivity_MODE_WORLD_READABLE 1L  main_activity_UninstalledMoniterActivity_MODE_WORLD_WRITEABLE  main_activity_UninstalledMoniterActivity_MODE_WORLD_WRITEABLE 2L  main_activity_UninstalledMoniterActivity_MODE_APPEND  main_activity_UninstalledMoniterActivity_MODE_APPEND 32768L  main_activity_UninstalledMoniterActivity_MODE_MULTI_PROCESS  main_activity_UninstalledMoniterActivity_MODE_MULTI_PROCESS 4L  main_activity_UninstalledMoniterActivity_BIND_AUTO_CREATE  main_activity_UninstalledMoniterActivity_BIND_AUTO_CREATE 1L  main_activity_UninstalledMoniterActivity_BIND_DEBUG_UNBIND  main_activity_UninstalledMoniterActivity_BIND_DEBUG_UNBIND 2L  main_activity_UninstalledMoniterActivity_BIND_NOT_FOREGROUND  main_activity_UninstalledMoniterActivity_BIND_NOT_FOREGROUND 4L  main_activity_UninstalledMoniterActivity_BIND_ABOVE_CLIENT  main_activity_UninstalledMoniterActivity_BIND_ABOVE_CLIENT 8L  main_activity_UninstalledMoniterActivity_BIND_ALLOW_OOM_MANAGEMENT  main_activity_UninstalledMoniterActivity_BIND_ALLOW_OOM_MANAGEMENT 16L  main_activity_UninstalledMoniterActivity_BIND_WAIVE_PRIORITY  main_activity_UninstalledMoniterActivity_BIND_WAIVE_PRIORITY 32L  main_activity_UninstalledMoniterActivity_BIND_IMPORTANT  main_activity_UninstalledMoniterActivity_BIND_IMPORTANT 64L  main_activity_UninstalledMoniterActivity_BIND_ADJUST_WITH_ACTIVITY  main_activity_UninstalledMoniterActivity_BIND_ADJUST_WITH_ACTIVITY 128L  main_activity_UninstalledMoniterActivity_CONTEXT_INCLUDE_CODE  main_activity_UninstalledMoniterActivity_CONTEXT_INCLUDE_CODE 1L  main_activity_UninstalledMoniterActivity_CONTEXT_IGNORE_SECURITY  main_activity_UninstalledMoniterActivity_CONTEXT_IGNORE_SECURITY 2L  main_activity_UninstalledMoniterActivity_CONTEXT_RESTRICTED  main_activity_UninstalledMoniterActivity_CONTEXT_RESTRICTED 4L  main_activity_UninstalledMoniterActivity_RESULT_CANCELED  main_activity_UninstalledMoniterActivity_RESULT_CANCELED 0L  main_activity_UninstalledMoniterActivity_RESULT_OK  main_activity_UninstalledMoniterActivity_RESULT_OK -1L  main_activity_UninstalledMoniterActivity_RESULT_FIRST_USER  main_activity_UninstalledMoniterActivity_RESULT_FIRST_USER 1L  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DISABLE  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DISABLE 0L  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DIALER  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DIALER 1L  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SHORTCUT  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SHORTCUT 2L  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_LOCAL  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_GLOBAL  main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L        JNIEXPORT  JNICALL Java_main_activity_UninstalledMoniterActivity_init(JNIEnv *
複製代碼

核心——native方法實現:

複製代碼
  #include            c_TAG[] =   jboolean b_IS_COPY =         JNIEXPORT  JNICALL Java_main_activity_UninstalledMoniterActivity_init(JNIEnv *      jstring tag = (*env)->           LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &             , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, ), &           pid_t pid =      (pid <                    LOG_ERROR((*env)->GetStringUTFChars(env, tag, &                 , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, ), &        (pid ==                     (              FILE *p_file = fopen(,               (p_file !=                                     LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &                             , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, ), &                  sleep(                                                 LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &                             , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, ), &                                   execlp(, , , , , , , ( *
複製代碼

注1:爲了調試方便,包含<android/log.h>,使得so在執行過程當中也能夠像Java端同樣方便得打出log。相應的mk文件須要加上如下兩句聲明

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog

注2:代碼中引用了360手機衛士的反饋地址,僅供你們學習、測試使用~~~

相關文章
相關標籤/搜索