首先给你的程序注册读取log权限,
<uses-permission android:name="android.permission.READ_LOGS" />
然后在你的程序里开一个后台线程,不停的读取log,当你的应用(包括其他任何应用)被卸载时,系统的ActivityManager会打印出一行log,大概是removing:你的包名。这个时机是在卸载界面点击确定后的一瞬间触发的,如下图
之后你的程序不管是进程还是线程都会被杀死。这一瞬间很短,但足够你捕获到,能不能通过网络发送出去你要发的信息就不敢保证了,我反正是没发出去就被杀死了。
还有个时机是在程序管理界面点击卸载按钮跳转卸载界面时会打印一行log,如图:
但是不能保证用户就会点确定真把你的卸载了。。所以自己权衡吧。
这是我在网上找到的唯一方法
代码如下:
private void ListenLog(){
Thread t = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
Log.v("Fuck","Start listening log");
String[] cmds = { "logcat", "-c" };
String shellCmd = "logcat";
Process process = null;
InputStream is = null;
DataInputStream dis = null;
String line = "";
Runtime runtime = Runtime.getRuntime();
try {
int waitValue;
waitValue = runtime.exec(cmds).waitFor();
process = runtime.exec(shellCmd);
is = process.getInputStream();
dis = new DataInputStream(is);
while ((line = dis.readLine()) != null && mKeepListenFlag) {
if (!line.contains("Fuck")) {
Log.v("Fuck", line);
//这里只是把每个log都打印了一遍,可以再此判断line里是否有removing字样,然后做些处理
}
}
Log.v("Fuck","finished listen");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
} finally {
try {
if (dis != null) {
dis.close();
}
if (is != null) {
is.close();
}
if (process != null) {
process.destroy();
}
} catch (Exception e) {
e.print.....
StackTrace();
}
}
}
});
//mKeepListenFlag是个成员变量,是为了让程序结束时终止线程的,否则可能产生程序多次启动,然后这个线程就启动了多个。Android线程可不会因为Activity的退出而终止。
mKeepListenFlag = true;
t.start();
}