我們知道在Android中要監(jiān)聽自身App被卸載是沒有辦法實(shí)現(xiàn)的,只能監(jiān)聽第三方的App卸載,而且只能監(jiān)聽系統(tǒng)廣播才能實(shí)現(xiàn)監(jiān)聽第三方App的卸載。那么我們要監(jiān)聽自身的卸載情況,只能用NDK來實(shí)現(xiàn)了。
首先用NDK來監(jiān)聽App的卸載有很多種方法,在這里我只介紹最簡單的方法來實(shí)現(xiàn),通過在C中開一個(gè)獨(dú)立線程來監(jiān)聽我的App有沒有被卸載,用一個(gè)定時(shí)器每隔1秒鐘就去查詢一下當(dāng)前的App在data/data下還存在不,來實(shí)現(xiàn)該功能:
據(jù)體代碼實(shí)現(xiàn)如下:

void java_com_example_appuninstall_MainActivity_UninstallListener(JNIEnv* env,
jobject obj, jstring packageName, jstring url) {
int code = fork(); //開啟子線程監(jiān)聽App目錄
int isStop = 1;
if (code > 0) {
} else if (code == 0) {
while (isStop) {
sleep(1);
char* packagename = Jstring2CStr(env, packageName);
char* url = Jstring2CStr(env, url);
//FILE *fopen(const char *, const char *);
FILE *fileName = fopen(packagename, "r");
if (fileName == NULL) {
//說明此App已經(jīng)被卸載,要彈出一個(gè)網(wǎng)頁
execlp("am", "am", "start", "-a", "android.intent.action.VIEW",
"-d", url, (char*) NULL);
}
}
}
}
上面的方法中packageName是指App安裝所在的全路徑,url是卸載后要跳轉(zhuǎn)的網(wǎng)頁鏈接
在此附上JNI中很有用的jstring 與 const char* 轉(zhuǎn)換函數(shù)
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "GB2312");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
"(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray) (*env)->CallObjectMethod(env, jstr, mid,
strencode); // String .getByte("GB2312");
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0) {
rtn = (char*) malloc(alen + 1); //"\0"
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0); //
return rtn;
}
好了,上面的功能就全部實(shí)現(xiàn)了,如果你有更容易或更好的方法可以留言。
需要demo的也可以聯(lián)系我。