日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android监听程序自身被卸载

發布時間:2025/3/20 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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监听程序自身被卸载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。