[转]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;
}
复制代码

 

posted @ 2016-02-25 17:51  枪侠  阅读(505)  评论(0编辑  收藏  举报