zoukankan      html  css  js  c++  java
  • 如何在不同的语言/平台中获取Android ID

    如何在不同的语言/平台中获取Android ID#

    最近开发工作中需要使用到AndroidID,在Unity和native code中也需要使用,java获取很方便,Unity中也不难,最难的是在native code中获取。

    获取android ID需要有一个上下文实例,也就是Context实例,看下面的java获取方式:

    在java中获取##

    Android原生代码,这个是最简单的:

    public static String GetAndroid(Context context){
        final String androidId;
        androidId = android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
        return androidId;
     }
    

    在Unity中获取##

    Unity获取androidID首先需要获取Unity环境中当前的activity,由activiy调用getContentResolver。

    	private String GetAndroidID()
    	{
    		AndroidJavaClass up = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
    		AndroidJavaObject currentActivity = up.GetStatic<AndroidJavaObject> ("currentActivity");
    		AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject> ("getContentResolver");  
    		AndroidJavaClass secure = new AndroidJavaClass ("android.provider.Settings$Secure");
    		string android_id = secure.CallStatic<string> ("getString", contentResolver, "android_id");
    		return android_id;
    	}
    

    在C中获取

    在C代码中只能通过JNI方式调用java来获取,代码看起来比较乱,有很多同java进行交互的部分。获取流程如下:

    • 首先JVM加载native code所在动态库的时候(loadlibrary)会自动调用JNI_OnLoad,这时候会初始化一个全局的JavaJVM,一个进程只能有一个JavaJVM。

    • 当前线程获取JNIEnv,调用AttachCurrentThread来获得。

    • 通过JNI获取Java中的相关类,方法。获取Context(getGlobalContext)的方法研究了很长时间,网上搜了好多资料。

    • 得到jstring类型的Android,转换成char *

    • 最后返回。

    #include <jni.h>
    #include <assert.h>
    #include "libavutil/avassert.h"
    
    #define JNI_CLASS_PATH     /JNI/CLASS/path
    static JavaVM* g_jvm=NULL;
    
    static jobject getGlobalContext(JNIEnv *env)
    {
    
        jclass activityThread = (*env)->FindClass(env,"android/app/ActivityThread");
        jmethodID currentActivityThread = (*env)->GetStaticMethodID(env,activityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
        jobject at = (*env)->CallStaticObjectMethod(env,activityThread, currentActivityThread);
    
        jmethodID getApplication = (*env)->GetMethodID(env,activityThread, "getApplication", "()Landroid/app/Application;");
        jobject context = (*env)->CallObjectMethod(env,at, getApplication);
        return context;
    }
    
    static jstring
    _getAndroidID(JNIEnv *env, jobject thiz)
    {
      
        jclass c_settings_secure = (*env)->FindClass(env, "android/provider/Settings$Secure");
        jclass c_context = (*env)->FindClass(env,"android/content/Context");
        if(c_settings_secure == NULL || c_context == NULL){
            return NULL;
        }
        //Get the getContentResolver method
        jmethodID m_get_content_resolver = (*env)->GetMethodID(env, c_context, "getContentResolver",
                                                               "()Landroid/content/ContentResolver;");
        if(m_get_content_resolver == NULL){
            return NULL;
        }
        //Get the Settings.Secure.ANDROID_ID constant
        jfieldID f_android_id = (*env)->GetStaticFieldID(env, c_settings_secure, "ANDROID_ID", "Ljava/lang/String;");
    
        if(f_android_id == NULL){
            return NULL;
        }
        jstring s_android_id = (*env)->GetStaticObjectField(env, c_settings_secure, f_android_id);
      
        //create a ContentResolver instance context.getContentResolver()
        jobject o_content_resolver = (*env)->CallObjectMethod(env, getGlobalContext(env), m_get_content_resolver);
        if(o_content_resolver == NULL || s_android_id == NULL){
            return NULL;
        }
        //get the method getString
        jmethodID m_get_string = (*env)->GetStaticMethodID(env, c_settings_secure, "getString",
                                                           "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");
    
        if(m_get_string == NULL){
            return NULL;
        }
        //get the Android ID
        jstring android_id = (*env)->CallStaticObjectMethod(env, c_settings_secure,
                                                            m_get_string,
                                                            o_content_resolver,
                                                            s_android_id);
        return android_id;
    }
    
    
    static  char* jstringTostr( jstring jstr)
    {    
    
        JNIEnv* env = NULL;
        if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    
            return -1;
        }
        assert(env != NULL);    
        char* pStr = NULL;
    
        jclass     jstrObj   = (*env)->FindClass(env, "java/lang/String");
        jstring    encode    = (*env)->NewStringUTF(env, "utf-8");
        jmethodID  methodId  = (*env)->GetMethodID(env, jstrObj, "getBytes", "(Ljava/lang/String;)[B");
        jbyteArray byteArray = (jbyteArray)(*env)->CallObjectMethod(env, jstr, methodId, encode);
        jsize      strLen    = (*env)->GetArrayLength(env, byteArray);
        jbyte      *jBuf     = (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);
    
        if (jBuf > 0)
        {
            pStr = (char*)malloc(strLen + 1);
            if (!pStr)
            {
                return NULL;
            }
            memcpy(pStr, jBuf, strLen);
            pStr[strLen] = 0;
        }
       
        (*env)->ReleaseByteArrayElements(env, byteArray, jBuf, 0);
        //av_log(NULL, AV_LOG_INFO, "the android is end%s
    ", pStr);
        return pStr;
    }
    
    
    char * getAndroidID()
    {
        JNIEnv* env = NULL;
        if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK)
        {
           return NULL;
        }
        jstring androidID = _getAndroidID(env,NULL);
        return jstringTostr(androidID);
    }
    
    JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
    {
        JNIEnv* env = NULL;
        g_jvm = vm;
        if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
           return -1;
        }
        assert(env != NULL);
        return JNI_VERSION_1_4;
    }
    
    
    
    
  • 相关阅读:
    C语言-if语句
    C语言-表达式
    C语言-基础
    Java for LeetCode 187 Repeated DNA Sequences
    Java for LeetCode 179 Largest Number
    Java for LeetCode 174 Dungeon Game
    Java for LeetCode 173 Binary Search Tree Iterator
    Java for LeetCode 172 Factorial Trailing Zeroes
    Java for LeetCode 171 Excel Sheet Column Number
    Java for LeetCode 169 Majority Element
  • 原文地址:https://www.cnblogs.com/harlanc/p/7710355.html
Copyright © 2011-2022 走看看