JNI进程守护
c代码部分如下:
JNIEXPORT void JNICALL Java_com_sharetimes_qude_jni_JNIDaemon_daemon(JNIEnv * env, jobject obj,jstring packageDir,jint sdkVersion,jstring user) { char * pd = Jstring2CStr(env, packageDir); pid_t pid = fork(); if (pid < 0) { LOGD("create process failure"); exit(1); } else if (pid > 0) { //pid_r=wait(NULL); } else { while (JNI_TRUE) { pid_t sid_r,sid; sid = fork(); //创建捕捉子进程退出信号 if(sid == 0) { LOGD("app run create"); if (sdkVersion >= 17) { execlp("am", "am", "startservice", "--user","0", "-n","com.sharetimes.qude/.service.StartService", (char*) 0); } else { execlp("am", "am", "startservice", "-n","com.sharetimes.qude/.service.StartService", (char*) 0); } sleep(2); //等待子线程 } else if(sid<0) { exit(1); } else { LOGD("app run clear"); sid_r = wait(NULL); } FILE* file = fopen(pd, "rt"); if(file == NULL) { LOGD("app run daemon exit"); exit(0); } fclose(file); if(file != NULL) { free(file); file==NULL; } sleep(10); } } }
Java代码调用
public class JNIDaemon { public native void daemon(String packageDir, int sdkVersion, String user); public void init(Context context) { String packageDir = "/data/data/" + context.getPackageName(); daemon(packageDir, android.os.Build.VERSION.SDK_INT, context.getApplicationInfo().uid + ""); } }
JNI 卸载后跳转指定网页
c代码如下:
/** * 返回值 char* 这个代表char数组的首地址 * Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串 */ char* Jstring2CStr(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = (*env)->FindClass(env, "java/lang/String"); //String jstring strencode = (*env)->NewStringUTF(env, "GB2312"); // 得到一个java字符串 "GB2312" jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312"); jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312"); jsize alen = (*env)->GetArrayLength(env, barr); // byte数组的长度 jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE); if (alen > 0) { rtn = (char*) malloc(alen + 1); //" " memcpy(rtn, ba, alen); rtn[alen] = 0; } (*env)->ReleaseByteArrayElements(env, barr, ba, 0); // return rtn; } JNIEXPORT void JNICALL Java_com_sharetimes_qude_jni_JNIUninstall_uninstall(JNIEnv * env, jobject obj, jstring packageDir, jint sdkVersion ,jstring parameter,jstring user) { // 1,将传递过来的java的包名转为c的字符串 char * pd = Jstring2CStr(env, packageDir); char * para=Jstring2CStr(env, parameter); char url[1024]; strcpy (url,"http://vic.i.angjoy.com:8080/uninstall/index.jsp?"); strcat (url,para); puts (url); char * userid= Jstring2CStr(env,user); // 2,创建当前进程的克隆进程 pid_t pid = fork(); // 3,根据返回值的不同做不同的操作,<0,>0,=0 if (pid < 0) { exit(1); } else if (pid > 0) { } else { while (JNI_TRUE) { FILE* file = fopen(pd, "rt"); if (file == NULL) { if (sdkVersion >= 17) { // Android4.2系统之后支持多用户操作,所以得指定用户 execlp("am", "am", "start", "--user", "0", "-a","android.intent.action.VIEW", "-d",url, (char*) NULL); } else { // Android4.2以前的版本无需指定用户 execlp("am", "am", "start", "-a","android.intent.action.VIEW", "-d",url, (char*) NULL); } LOGD("app run uninstall exit"); exit(0); } else { // 应用没有被卸载 LOGD("app run normal"); } fclose(file); if(file != NULL) { free(file); file==NULL; } sleep(1); } } }
Java代码调用:
public class JNIUninstall { static { System.loadLibrary("uninstall"); } private String imei; private String phones; private String Versions; private String chanels; private String imsi; public native void uninstall(String packageDir, int sdkVersion, String parameter, String uid); public void init(Context context) { String packageDir = "/data/data/" + context.getPackageName(); int sdkVersion = android.os.Build.VERSION.SDK_INT; TelephonyManager mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); ApplicationInfo info; try { info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); imsi = mTelephonyMgr.getSubscriberId(); imei = mTelephonyMgr.getDeviceId(); phones = android.os.Build.MODEL; Versions = pInfo.versionName; chanels = info.metaData.getString("ZHUGE_CHANNEL"); } catch (NameNotFoundException e) { e.printStackTrace(); } String parameter = "m=" + imei + "&m1=" + imsi + "&model=" + phones + "&v=" + Versions + "&ch=" + chanels + "&sdk_int=" + sdkVersion; uninstall(packageDir, sdkVersion, parameter, context.getApplicationInfo().uid + ""); } }