Overview:
If it were not for a special situation, I think we would rarely be exposed to this demand. In fact, the Java part of Android does not provide the corresponding interface, here need to call C code, that is, to write Jni. For the first knowledge of JNI, you can refer to my blog's article on the classification of JNI.
Thinking Analysis:
In fact, we all know that the Android program can be monitored to hear the system uninstall program this broadcast, but unfortunately, it can not listen to itself is uninstalled, then what can we do in order to do something after its own program is uninstalled? Java didn't say how to do it, what about C?
C is possible. c The idea is to listen to Data/data/[packagenmae] This folder changes.
Source Address:
http://download.csdn.net/detail/u013761665/8853547
implementation process:main implementation code-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> /* Macro definition Begin *///Clear 0 Macro # Mem_zero (pDest, Destsize) memset (pDest, 0, destsize)//LOG Macro Define # define LOG_INFO (tag, msg) __andr Oid_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)/* Within global variable begin */static char c_tag[] = "onEvent"; static Jboolean b_is_copy = Jni_true;jst Ring Java_com_catching_uninstallself_uninstallobserver_startwork (jnienv* env,jobject thiz, jstring path, jstring URL, Jint version) {jstring tag = (*env)->newstringutf (env, c_tag);//Initialize Loglog_debug ((*env)->getstringutfchars (env, Tag, &b_is_copy), (*env)->getstringutfchars (env, (*enV)->newstringutf (env, "init OK"), &b_is_copy));//fork subprocess to perform polling task pid_t pid = fork (), if (PID < 0) {//Error loglog_er ROR (*env)->getstringutfchars (env, tag, &b_is_copy), (*env)->getstringutfchars (env, (*ENV) Newstringutf (env, "fork failed!!!"), &b_is_copy));} else if (PID = = 0) {//Sub-process registered Directory listener int filedescriptor = Inotify_init (); if (FileDescriptor < 0) {Log_debug ((*env)->gets Tringutfchars (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);} Allocates the cache so that the event is read, the cache size = the size of a struct inotify_event, such that one eventvoid *p_buf = malloc (the 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);} Start Monitoring Log_debug ((*env)->getstringutfchars (env, tag, &b_is_copy), (*env)->getstringutfchars (env, (*ENV)- >newstringutf (ENV, "start Observer"), &b_is_copy));//Read blocks the process, size_t readbytes = Read (FileDescriptor, P_buf, sizeof (struct inotify_event));//Go here to indicate the event that the directory was deleted, Logout listener free (P_BUF); Inotify_rm_watch (FileDescriptor, in_delete);// Directory does not exist Loglog_debug ((*env)->getstringutfchars (env, tag, &b_is_copy), (*env)->getstringutfchars (env, (*ENV) ->newstringutf (env, "uninstalled"), &b_is_copy)); if (version >= 17) {//4.2 + systems are more stringent due to user rights management, need to add--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);} Extensions: Can execute other shell commands, am (i.e. Activity Manager), can open a program, service, broadcast intent, etc.} else {//parent process exits directly, so that the child process is adopted by the INIT process to avoid child process zombie} Return (*ENV)->newstringutf (env, "Hello from JNI!");}
Call procedure: Uninstallobserver.java
public class Uninstallobserver {static{system.loadlibrary ("Observer");} public static native string Startwork (string path, string url, int version);}
Call procedure: Mainactivity.java
public class Mainactivity extends Activity { @Override protected 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);} }
effect Show diagram:
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android Listener itself is uninstalled