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); // 初始化log
LOG_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) {
// 出错log
LOG_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的大小,这样一次处理一个event
void *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); // 文件夹不存在log
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY),
(*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "uninstalled"), &b_IS_COPY)); if (version >= 17) {
// 4.2以上的系统因为用户权限管理更严格,须要加上 --user 0
execlp("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 {
@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);
}
}
效果展示图:
Android监听程序自身被卸载的更多相关文章
- 【Android】Android 监听apk安装替换卸载广播
[Android]Android 监听apk安装替换卸载广播 首先是要获取应用的安装状态,通过广播的形式 以下是和应用程序相关的Broadcast Action ACTION_PACKAGE_ADDE ...
- Android 监听apk安装替换卸载广播
首先是要获取应用的安装状态,通过广播的形式 以下是和应用程序相关的Broadcast Action ACTION_PACKAGE_ADDED 一个新应用包已经安装在设备上,数据包括包名(最新安装的包程 ...
- Android监听应用程序安装和卸载
Android监听应用程序安装和卸载 第一. 新建监听类:BootReceiver继承BroadcastReceiver package com.rongfzh.yc; import android. ...
- Android监听自身卸载,弹出用户反馈调查
1,情景分析 在上上篇博客中我写了一下NDK开发实践项目,使用开源的LAME库转码MP3,作为前面几篇基础博客的加深理解使用的,但是这样的项目用处不大,除了练练NDK功底.这篇博客,我将讲述一下一个各 ...
- Android应用如何监听自己是否被卸载及卸载反馈功能的实现
一个应用被用户卸载肯定是有理由的,而开发者却未必能得知这一重要的理由,毕竟用户很少会主动反馈建议,多半就是用得不爽就卸,如果能在被卸载后获取到用户的一些反馈,那对开发者进一步改进应用是非常有利的.目前 ...
- Android监听消息通知栏点击事件
Android监听消息通知栏点击事件 使用BroadCastReceiver 1 新建一个NotificationClickReceiver 类,并且在清单文件中注册!! public class N ...
- (转)ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
早上同事用PL/SQL连接虚拟机中的Oracle数据库,发现又报了"ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务"错误,帮其解决后,发现很多人遇到过这样的问 ...
- (转)解决 ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
下面操作默认在安装Oralce数据库的服务器上运行. 1)确保Oracle 基本服务都已启动 OracleDBConsoleorcl OracleOraDb11g_home1TNSListener O ...
- Android监听系统短信数据库变化-提取短信内容
由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...
随机推荐
- BZOJ-4706 B君的多边形 OEIS
题面 题意:有一个正n多边形,我们要连接一些对角线,把这个多边形分成若干个区域,要求连接的对角线不能相交,每个点可以连出也可以不连出对角线,即最终不要求所有区域均为三角形,问总方案数mod (10^9 ...
- SNMP简单概述
一.SNMP简单概述 1.1.什么是Snmp SNMP是英文"Simple Network Management Protocol"的缩写,中文意思是"简单网络管理协议& ...
- TensorFlow-LSTM序列预测
问题情境:已知某一天内到目前为止股票各个时刻的价格,预测接下来短时间内的价格变化. import tushare as ts import time from collections import n ...
- 使用纯 CSS 实现 Google Photos 照片列表布局
文章太长,因为介绍了如何一步一步进化到最后接近完美的效果的,不想读的同学可以直接跳到最后一个大标题之后看代码.demo及原理就好,或者也可以直接看下面这个链接的源代码. 不过还是建议顺序读下去,因为后 ...
- WPF自定义动画控件 风机
一:创建WPF项目 二:在项目下添加文件Themes,在此文件下添加新项 ”资源词典“取名为 Generic.xaml 注意大小写,之前遇到因为大小写不对应,导致出错的情况Generic.xam ...
- 2017-4-18 关于小组APP
演讲: 各位合作伙伴:我们的产品:图书鉴赏是为了解决18岁到28岁青年的痛苦,他们需要更好的图书推荐,更多的好书,但是现有的方案并没有能很好的解决这些需求,我们有独特的办法制作一个图书鉴赏的APP,它 ...
- 在YII2中使用memcached
一.在本地安装Memcached服务器和安装memcached扩展 http://www.cnblogs.com/songziqing/p/5896742.html http://www.cnblog ...
- python第三方库 pip 豆瓣源
pip install xxx -i http://pypi.douban.com/simple/ xxx 为包名
- box-shadow 阴影剖析
box-shadow的四个值分别是左右偏移,上下偏移,向四周模糊扩算,距离四周边缘的距离,最后一个是阴影的颜色值,如图示例: 上代码,复制代码,就可以看到上图的效果 <!DOCTYPE html ...
- 【转】Oracle基础结构认知—初识oracle 礼记八目 2017-12-12 21:19:30
Oracle服务器(oracle server)由实例和数据库组成.其中,实例就是所谓的关系型数据库管理系统(Relational Database Management System,RDBMS), ...