Android研究之监听自身应用被卸载代码实现
1.通过jni实现函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
//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_example_uninstallself_Observer_register(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 !"); }
|
2.定义UninstallObserver
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
class UninstallObserver { static{
System.loadLibrary("observer");
}
/***
*
* @param path 须要监听的文件路径。可用 getApplicationContext().getFilesDir().getPath()
* @param url 卸载调转http
* @param version android.os.Build.VERSION.SDK_INT
* @return
*/
public
static native String register(String path, String url, int version);
}
|
3.简单使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@Override
protected void
onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(getApplicationContext(),
getApplicationContext().getFilesDir().getPath()
+ "," + Build.VERSION.SDK_INT, 1).show();
long
a = System.currentTimeMillis(); String
str = UninstallObserver.register(getApplicationContext().getFilesDir().getPath(), "http://www.baidu.com",
android.os.Build.VERSION.SDK_INT);
long
b = System.currentTimeMillis();
Toast.makeText(getApplicationContext(),
str+","+(b-a), 1).show();
}
|
Android研究之监听自身应用被卸载代码实现的更多相关文章
- Android应用如何监听自己是否被卸载及卸载反馈功能的实现
一个应用被用户卸载肯定是有理由的,而开发者却未必能得知这一重要的理由,毕竟用户很少会主动反馈建议,多半就是用得不爽就卸,如果能在被卸载后获取到用户的一些反馈,那对开发者进一步改进应用是非常有利的.目前 ...
- Android 短信监听及用途分析
监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求 但是作为程序员呢,多了解一下也是好的. Android 监听系统短信有什么用? 1.对系统 ...
- Android 手势水平监听判断
package com.zihao.ui; import com.zihao.R; import android.os.Bundle; import android.app.Activity; imp ...
- Android中如何监听GPS开启和关闭
转自 chenming 原文 Android中如何监听GPS开启和关闭 摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...
- Android手机上监听短信的两种方式
Android手机上监听短信有两种方式: 1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. AndroidManifest.xml: ...
- 【Android】Android 监听apk安装替换卸载广播
[Android]Android 监听apk安装替换卸载广播 首先是要获取应用的安装状态,通过广播的形式 以下是和应用程序相关的Broadcast Action ACTION_PACKAGE_ADDE ...
- android的电话监听
android的电话监听 新建一个项目,结构图如下: PhoneService: package com.demo.tingdianhua; import android.app.Service; i ...
- Android零基础入门第34节:Android中基于监听的事件处理
原文:Android零基础入门第34节:Android中基于监听的事件处理 上一期我们学习了Android中的事件处理,也详细学习了Android中基于监听的事件处理,同时学会了匿名内部类形式,那么本 ...
- Android实现网络监听
一.Android Wifi常用广播 网络开发中主体会使用到的action: ConnectivityManager.CONNECTIVITY_ACTION WifiManager.WIFI_STAT ...
随机推荐
- C# linq对分组操作执行子查询
本主题演示创建查询的两种不同方式,此查询将源数据排序成组,然后分别对每个组执行子查询. 每个示例中的基本方法是使用名为 newGroup 的"接续块"对源元素进行分组,然后针对 n ...
- sublime text全程指南【转载】
前言(Prologue) Sublime Text是一款跨平台代码编辑器(Code Editor),从最初的Sublime Text 1.0,到现在的Sublime Text 3.0,Sublime ...
- 北京地铁换乘算法(二维坐标系,图的深度搜索)开源下载Android源码、性能最优解
距离2012年11月2日下午2:05:31 已经过去158751270这么多秒了,不小心暴露了我的当前时间. java代码贴出来. private static long gettimelong() ...
- 深入理解java虚拟机_第二章_读书笔记
1.本章内容目录: 概述 运行时数据区域 程序计数器 java虚拟机栈 本地方法栈 java堆 方法区 运行时常量池 直接内存 HotSpot虚拟机对象探秘 对象的创建 对象的内存布局 对象的访问定位 ...
- 线程UI同步
只用一次: this.Invoke(new MethodInvoker(() => { this.btnGo.Enabled = true; MessageBox.Show("Yeah ...
- 重新绘制TabControl的Tabpage标签,添加图片及关闭按钮
1 }
- jquery.tagsinput的使用例子,包括模糊查询后端代码
<link rel="stylesheet" type="text/css" href="~/lib/jquery.tagsinput.jurg ...
- 最全Jenkins+SVN+iOS+cocoapods环境搭建及其错误汇总
前言 持续集成是敏捷开发中重要的一部分,为保证新功能的开发,又保证旧功能的维护,从一个冲刺到下个冲刺.持续集成工具是我们保证开发和维护并行的护航者,现在流行的集成工具有很多,例如: 1.Jenkins ...
- ERP中文档权限设置:只能浏览不能下载?如何实现
文档中心的文件夹授权只能是对岗位或者用户授权(这个跟我们的[[url=]用户及权限[/url]]下面的授权方式还不太一样)比如:要将文档中心的文件夹[公司文档]授权给用户A和用户B 授权逻辑: 软件界 ...
- jquery 三级关联选择效果
在网页制作中,三级关联选择经常遇到,于是归纳了一个进行参考 代码如下: <!DOCTYPE html> <html lang="en"> <head& ...