Android通过JNI实现守护进程与卸载后跳转指定网页

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); //"\0"
        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 + "");
    }
}

 

 
posted @ 2016-11-22 10:55  chenxibobo  阅读(1886)  评论(0编辑  收藏  举报