我们知道在Android中要监听自身App被卸载是没有办法实现的,只能监听第三方的App卸载,而且只能监听系统广播才能实现监听第三方App的卸载。那么我们要监听自身的卸载情况,只能用NDK来实现了。
首先用NDK来监听App的卸载有很多种方法,在这里我只介绍最简单的方法来实现,通过在C中开一个独立线程来监听我的App有没有被卸载,用一个定时器每隔1秒钟就去查询一下当前的App在data/data下还存在不,来实现该功能:
据体代码实现如下:
void java_com_example_appuninstall_MainActivity_UninstallListener(JNIEnv* env,
jobject obj, jstring packageName, jstring url) {
int code = fork(); //开启子线程监听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已经被卸载,要弹出一个网页
execlp("am", "am", "start", "-a", "android.intent.action.VIEW",
"-d", url, (char*) NULL);
}
}
}
}
上面的方法中packageName是指App安装所在的全路径,url是卸载后要跳转的网页链接
在此附上JNI中很有用的jstring 与 const char* 转换函数
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;
}
好了,上面的功能就全部实现了,如果你有更容易或更好的方法可以留言。
需要demo的也可以联系我。
网友评论