• 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); //""
            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 + "");
        }
    }
     
  • 相关阅读:
    List<T>Find方法,FindAll方法,Contains方法,Equals方法
    C#SerialPort如何读取串口数据并显示在TextBox上
    49、css属性相关
    40、协程
    45、mysql 储存过程
    37、进程之间的通信
    38、线程及其方法
    39、多线程和线程池
    33、验证客户端的合法性、socketserver模块
    32、黏包的解决方式、struct模块
  • 原文地址:https://www.cnblogs.com/chenxibobo/p/6088338.html
Copyright © 2020-2023  润新知