• Android NDK几点回调方式


    一、NDK中获取android设备ID的方式

    Java代码如下(获取设备ANDROID_ID):

    final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);

    对应的c代码(相当蛋疼),注意如果是C++,需要把所有的(*env)->替换成env->,同时去掉第一个参数env

    char *
    get_android_id(JNIEnv *env, jobject mContext, jobject actObj)
    {
        char *szDevId = NULL;
    
        if (!mContext) {
            return szDevId;
        }
    
        jclass resCls = (*env)->FindClass(env, "android/content/Context");
        jmethodID getMethod = (*env)->GetMethodID(env, resCls, "getContentResolver", "()Landroid/content/ContentResolver;");
        jobject resolver = (*env)->CallObjectMethod(env, actObj, getMethod);
        if (resolver == NULL) {
            LOGE("Invalid resolver!");
        }
    
        jclass cls_context = (*env)->FindClass(env, "android/provider/Settings$Secure");
        if (cls_context == NULL) {
            LOGE("Invalid cls_context!");
        }
    
        jmethodID getStringMethod = (*env)->GetStaticMethodID(env, cls_context, "getString", "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");
        if (getStringMethod == NULL) {
            LOGE("Invalid getStringMethod!");
        }
    
        jfieldID ANDROID_ID = (*env)->GetStaticFieldID(env, cls_context,
                "ANDROID_ID", "Ljava/lang/String;");
        jstring str = (jstring)((*env)->GetStaticObjectField(env, cls_context, ANDROID_ID));
    
        jstring jId = (jstring)((*env)->CallStaticObjectMethod(env, cls_context, getStringMethod, resolver, str));
        szDevId = (char *)((*env)->GetStringUTFChars(env, jId, 0));
    
        return szDevId;
    }

    如果是手机,还可以通过TelephoneManager.getDeviceId()方式来获取:

    Java代码:

    final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();

    对应的C代码:

    char *
    get_telepone_id(JNIEnv *env, jobject mContext, jobject actObj) {
        char *szDevId = NULL;
    
        if(mContext == 0){
           return szDevId;
        }
    
        jclass cls_context = (*env)->FindClass(env, "android/content/Context");
    
        jmethodID getSystemService = (*env)->GetMethodID(env, cls_context, "getSystemService",
                "(Ljava/lang/String;)Ljava/lang/Object;");
    
        if(!getSystemService){
           return szDevId;
        }
    
        jfieldID TELEPHONY_SERVICE = (*env)->GetStaticFieldID(env, cls_context,
                "TELEPHONY_SERVICE", "Ljava/lang/String;");
        if(!TELEPHONY_SERVICE){
           return szDevId;
        }
    
        jstring str = (jstring)(*env)->GetStaticObjectField(env, cls_context, TELEPHONY_SERVICE);
        jclass cls_tm = (*env)->FindClass(env, "android/telephony/TelephonyManager");
        if(!cls_tm){
           return szDevId;
        }
    
        jobject telephonymanager = (*env)->CallObjectMethod(env, actObj, getSystemService, str);
        if(!telephonymanager){
           return szDevId;
        }
    
        jmethodID getDeviceId = (*env)->GetMethodID(env, cls_tm, "getDeviceId", "()Ljava/lang/String;");
        if(!getDeviceId){
           return szDevId;
        }
        jstring deviceid = (jstring)(*env)->CallObjectMethod(env, telephonymanager, getDeviceId);
    
        szDevId = (char *)(*env)->GetStringUTFChars(env, deviceid, 0);
    
        (*env)->DeleteLocalRef(env, cls_tm);
        (*env)->DeleteLocalRef(env, cls_context);
        (*env)->DeleteLocalRef(env, telephonymanager);
    
        return szDevId;
    }

    二、通过NDK获取证书签名

    Java代码:

    PackageInfo pis;
    try {
        pis = mContext.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);  //获取包信息
        Signature sigs = pis.signatures[0];    //获取签名
        int hash = sigs.hashCode();              //获取签名的哈希码
    } catch(Exception e) {
        //TODO:log here.
    }

    对应的C代码:

    int
    get_apk_signature(JNIEnv *env, jobject obj) {
    
        jclass cls = (*env)->FindClass(env, "android/content/ContextWrapper");
        //this.getPackageManager();
        jmethodID mid = (*env)->GetMethodID(env, cls, "getPackageManager",
                "()Landroid/content/pm/PackageManager;");
        if (mid == NULL) {
            return -1;
        }
    
        jobject pm = (*env)->CallObjectMethod(env, obj, mid);
        if (pm == NULL) {
            return -2;
        }
    
        //this.getPackageName();
        mid = (*env)->GetMethodID(env, cls, "getPackageName", "()Ljava/lang/String;");
        if (mid == NULL) {
            return -3;
        }
    
        jstring packageName = (jstring)(*env)->CallObjectMethod(env, obj, mid);
    
        // packageManager->getPackageInfo(packageName, GET_SIGNATURES);
        cls = (*env)->GetObjectClass(env, pm);
        mid  = (*env)->GetMethodID(env, cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
        jobject packageInfo = (*env)->CallObjectMethod(env, pm, mid, packageName, 0x40); //GET_SIGNATURES = 64;
        cls = (*env)->GetObjectClass(env, packageInfo);
        jfieldID fid = (*env)->GetFieldID(env, cls, "signatures", "[Landroid/content/pm/Signature;");
        jobjectArray signatures = (jobjectArray)(*env)->GetObjectField(env, packageInfo, fid);
        jobject sig = (*env)->GetObjectArrayElement(env, signatures, 0);
    
        cls = (*env)->GetObjectClass(env, sig);
        mid = (*env)->GetMethodID(env, cls, "hashCode", "()I");
        int sig_value = (int)(*env)->CallIntMethod(env, sig, mid);
        return sig_value;
    }

    万里长城十亿兵, 
    国耻岂待儿孙平. 
    愿提十万虎狼族,
    越马扬刀入东京!
  • 相关阅读:
    多页面通信问题
    Web Worker
    http 状态码(转载)
    如何把一个Array 复制到ArrayList中?
    使用C#数据如何导到excel
    面试题:Web Service与wcf的区别
    ASP.NET为我们提供了几种错误处理机制?
    使用sql语句创建带有输出参数的存储过程
    存储过程维护
    Linux系统下的网络配置
  • 原文地址:https://www.cnblogs.com/dellinger/p/3454996.html
Copyright © 2020-2023  润新知