Android监听程序自身被卸载
生活随笔
收集整理的這篇文章主要介紹了
Android监听程序自身被卸载
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
概述:
? 如果不是一些特殊的情況,我想大家很少會接觸到這個需求。其實Android的Java部分沒有提供相應的接口,這里需要去調用C的代碼,也就是說要寫JNI了。關于JNI的初識,大家可以去參考我博客中關于JNI這個分類里的文章。
思路分析:
? 其實我們都知道,Android程序是可以監聽到系統卸載程序這個廣播的,不過可惜的是,它不能監聽到自身被卸載,那么我們要怎么做才能在自身程序被卸載之后做一些事情呢?Java沒有說怎么做,那C呢?
? C是可以的。C的思路是去監聽data/data/[packageNmae]這個文件夾的變動情況。
源碼地址:
http://download.csdn.net/detail/u013761665/8853547
實現過程:
主要實現代碼—C:
#include <string.h> #include <jni.h>#include <jni.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <android/log.h> #include <unistd.h> #include <sys/inotify.h>/* 宏定義begin */ // 清0宏 #define MEM_ZERO(pDest, destSize) memset(pDest, 0, destSize)// LOG宏定義 #define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg) #define LOG_DEBUG(tag, msg) __android_log_write(ANDROID_LOG_DEBUG, tag, msg) #define LOG_WARN(tag, msg) __android_log_write(ANDROID_LOG_WARN, tag, msg) #define LOG_ERROR(tag, msg) __android_log_write(ANDROID_LOG_ERROR, tag, msg)/* 內全局變量begin */ static char c_TAG[] = "onEvent"; static jboolean b_IS_COPY = JNI_TRUE;jstring Java_com_catching_uninstallself_UninstallObserver_startWork(JNIEnv* env,jobject thiz, jstring path, jstring url, jint version) {jstring tag = (*env)->NewStringUTF(env, c_TAG);// 初始化logLOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "init OK"), &b_IS_COPY));// fork子進程,以執行輪詢任務pid_t pid = fork();if (pid < 0) {// 出錯logLOG_ERROR((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "fork failed !!!"), &b_IS_COPY));} else if (pid == 0) {// 子進程注冊目錄監聽器int fileDescriptor = inotify_init();if (fileDescriptor < 0) {LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_init failed !!!"), &b_IS_COPY));exit(1);}int watchDescriptor;watchDescriptor = inotify_add_watch(fileDescriptor,(*env)->GetStringUTFChars(env, path, NULL), IN_DELETE);if (watchDescriptor < 0) {LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_add_watch failed !!!"), &b_IS_COPY));exit(1);}// 分配緩存,以便讀取event,緩存大小=一個struct inotify_event的大小,這樣一次處理一個eventvoid *p_buf = malloc(sizeof(struct inotify_event));if (p_buf == NULL) {LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "malloc failed !!!"), &b_IS_COPY));exit(1);}// 開始監聽LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "start observer"), &b_IS_COPY));// read會阻塞進程,size_t readBytes = read(fileDescriptor, p_buf,sizeof(struct inotify_event));// 走到這里說明收到目錄被刪除的事件,注銷監聽器free(p_buf);inotify_rm_watch(fileDescriptor, IN_DELETE);// 目錄不存在logLOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "uninstalled"), &b_IS_COPY));if (version >= 17) {// 4.2以上的系統由于用戶權限管理更嚴格,需要加上 --user 0execlp("am", "am", "start", "--user", "0", "-a","android.intent.action.VIEW", "-d",(*env)->GetStringUTFChars(env, url, NULL), (char *) NULL);} else {execlp("am", "am", "start", "-a", "android.intent.action.VIEW","-d", (*env)->GetStringUTFChars(env, url, NULL),(char *) NULL);}// 擴展:可以執行其他shell命令,am(即activity manager),可以打開某程序、服務,broadcast intent,等等} else {// 父進程直接退出,使子進程被init進程領養,以避免子進程僵死}return (*env)->NewStringUTF(env, "Hello from JNI !"); }調用過程:UninstallObserver.java
public class UninstallObserver {static{System.loadLibrary("observer");}public static native String startWork(String path, String url, int version); }調用過程:MainActivity.java
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listening();}private void listening() {UninstallObserver.startWork("/data/data/" + getPackageName(), "https://www.baidu.com", android.os.Build.VERSION.SDK_INT);} }
效果展示圖:
總結
以上是生活随笔為你收集整理的Android监听程序自身被卸载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修正Android基于ZXing的二维码
- 下一篇: Android仿IOS的Assistiv