android JNI调用 execlp函数
execlp()函数
execlp函数简单的来说就是C语言中执行系统命令的函数
execlp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名, 找到后便执行该文件, 然后将第二个以后的参数当做该文件的argv[0], argv[1], ..., 最后一个参数必须用空指针(NULL)作结束.
android开发中,execlp函数对应android的path路径为system/bin/目录下
调用格式:
execlp("am","am","start","--user","0","-a","android.intent.action.VIEW","-d","http://www.google.com.hk",(char*)NULL);
监听APP被卸载后打开浏览器跳到指定网址实例源码如下:
.h代码:
/*
* MonitorUnistall.h
*
*/
#include <jni.h>
#ifndef MONITORUNISTALL_H_
#define MONITORUNISTALL_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com.vkex.vkmonitoruninstall.MainActivity
* Method: uninstall
* Signature: (Ljava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_com_vkex_vkmonitoruninstall_MainActivity_uninstall
(JNIEnv *, jobject, jstring, jint);
#ifdef __cplusplus
}
#endif
#endif /* MONITORUNISTALL_H_ */
.cpp代码:
#include<MonitorUnistall.h>
#include <stdio.h>
#include <jni.h>
#include <malloc.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <stdint.h>
#include <android/log.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
/**
* 返回值 char* 这个代表char数组的首地址
* Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串
*/
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String"); //String
jstring strencode = env->NewStringUTF("GB2312"); // 得到一个java字符串 "GB2312"
jmethodID mid = env->GetMethodID(clsstring, "getBytes",
"(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");
jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode); // String .getByte("GB2312");
jsize alen = env->GetArrayLength(barr); // byte数组的长度
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0) {
rtn = (char*) malloc(alen + 1); //"\0"
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0); //
return rtn;
}
JNIEXPORT void JNICALL Java_com_vkex_vkmonitoruninstall_MainActivity_uninstall(
JNIEnv * env, jobject obj, jstring packageDir, jint sdkVersion) {
// 1,将传递过来的java的包名转为c的字符串
char * pd = Jstring2CStr(env, packageDir);
// 2,创建当前进程的克隆进程
pid_t pid = fork();
// 3,根据返回值的不同做不同的操作,<0,>0,=0
if (pid < 0) {
// 说明克隆进程失败
LOGD("current crate process failure");
} else if (pid > 0) {
// 说明克隆进程成功,而且该代码运行在父进程中
LOGD("crate process success,current parent pid = %d", pid);
} else {
// 说明克隆进程成功,而且代码运行在子进程中
LOGD("crate process success,current child pid = %d", pid);
// 4,在子进程中监视/data/data/包名这个目录
//初始化inotify进程
int fd = inotify_init();
if (fd < 0) {
LOGD("inotify_init failed !!!");
exit(1);
}
//添加inotify监听器
int wd = inotify_add_watch(fd, pd, IN_DELETE);
if (wd < 0) {
LOGD("inotify_add_watch failed !!!");
exit(1);
}
//分配缓存,以便读取event,缓存大小=一个struct inotify_event的大小,这样一次处理一个event
void *p_buf = malloc(sizeof(struct inotify_event));
if (p_buf == NULL) {
LOGD("malloc failed !!!");
exit(1);
}
//开始监听
LOGD("start observer");
ssize_t readBytes = read(fd, p_buf, sizeof(struct inotify_event));
//read会阻塞进程,走到这里说明收到目录被删除的事件,注销监听器
free(p_buf);
inotify_rm_watch(fd, IN_DELETE);
// 应用被卸载了,通知系统打开用户反馈的网页
LOGD("app uninstall,current sdkversion = %d", sdkVersion);
if (sdkVersion >= 17) {
// Android4.2系统之后支持多用户操作,所以得指定用户
execlp("am", "am", "start", "--user", "0", "-a",
"android.intent.action.VIEW", "-d", "http://www.baidu.com",
(char*) NULL);
} else {
// Android4.2以前的版本无需指定用户
execlp("am", "am", "start", "-a", "android.intent.action.VIEW",
"-d", "http://www.baidu.com", (char*) NULL);
}
}
}
android.mk 代码:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MonitorUninstall
LOCAL_SRC_FILES := MonitorUninstall.cpp
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
MainActivity代码:
public class MainActivity extends Activity {
static {
System.loadLibrary("MonitorUninstall");
}
public native void uninstall(String packageDir, int sdkVersion);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String packageDir = "/data/data/" + getPackageName();
int sdkVersion = android.os.Build.VERSION.SDK_INT;
uninstall(packageDir, sdkVersion);
}
}
android JNI调用 execlp函数的更多相关文章
- android JNI调用(转)
Android jni开发资料--NDK环境搭建 android开发人员注意了 谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwi ...
- Android中调用C++函数的一个简单Demo
这里我不想多解释什么,对于什么JNI和NDK的相关内容大家自己去百度或谷歌.我对Android的学习也只是个新手.废话少说直接进入正题. 一.在Eclipse中创建一个Android Applicat ...
- android JNI调用机制
JNI的出现使得开发者既可以利用Java语言跨平台.类库丰 富.开发便捷等特点,又可以利用Native语言的高效. JNI是JVM实现中的一部分,因此Native语言和Java代码都运行在JVM的宿主 ...
- android JNI调用(Android Studio 3.0.1)(转)
最近回头复习了一下android 的jni调用,却发现按以前的方法调用失败,一怒之下就重新摸索,碰了几次壁,发现网上好多教程都不能成功调用,于是记录一下现在AS版本成功好用的调用方法. 这里设定你的n ...
- Android Jni调用浅述
声明:欢迎转载,转载时请注明出处!http://blog.csdn.net/flydream0/article/details/7371692 1 简述 JNI是Java Native Interfa ...
- Android Jni 调用
Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap5:j ...
- android JNI 调用NDK方法
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- Android jni helloworld
新建Android项目,设置布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android& ...
- [置顶] Android JNI必须掌握的五点
1:JNI是什么? Java NativeInterface(JNI)是Java提供的一个很重要的特性.它使得用诸如C/C++等语言编写的代码可以与运行于Java虚拟机(JVM)中的 Java代码 ...
随机推荐
- 关于C++中覆盖,重载,隐藏的一点说明
C++覆盖 重载 隐藏是三个经常容易混淆的概念 这里我们简单总结下: 1.重载的条件(编译时多态) a.同一个类中 b.函数名相同,参数不同(返回值不能作为重载的条件) c.与函数是否为虚函数无关 2 ...
- (史上最全的ios源码汇总)
按钮类 按钮 Drop Down Control http://www.apkbus.com/android-106661-1-1.html 按钮-Circular M ...
- 跨服务器查询sql语句样例
若2个数据库在同一台机器上:insert into DataBase_A..Table1(col1,col2,col3----)select col11,col22,col33-- from Data ...
- SQLLoader6(一个或多个数据文件按条件导入不同的表)
测试一1.创建表: SQL), col2 )); 表已创建. SQL), col2 )); 表已创建. SQL> COMMIT; 提交完成. 2.数据文件:test.txt A A A B B ...
- [Spring入门学习笔记][静态资源]
遗留问题 在上一节课的作业中,我们一定遇到了一点问题——虽然将页面内容正确的返回给了浏览器,但是浏览器显示的样式却是不正确的,这是因为在HTML的\标签中我们这样引入了CSS资源: <link ...
- javascript 多图无缝切换
思路只要是ul移动前,首先将当前显示的li克隆岛ul最后,当每次运动执行完毕后,再将前面的li删除,如此循环. <!DOCTYPE html> <html> <head& ...
- css中的伪类
伪类用于向某些选择器添加一些特殊效果. 1):focus 伪类在元素获得焦点的时向元素添加特殊样式.一般用于输入文本域,按钮,以及超链接. a:focus{color:red;}超链接字体为红色 in ...
- IOS自适应库---- Masonry的使用
Masonry是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了并具有高可读性,而且同时支持 iOS 和 Max OS X.Masonry是一个用代码写iOS或OS ...
- String()与toString()区别和应用
首先,String()和toString()方法都是将其它类型的变量转换为字符串的方法.但两者存在一定的区别: x.toString(): 无法转换null和undefined: 来看下面的小例子: ...
- StringList 自定义快速排序
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...