Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从JNI调用Java方法需要上下文(this)来接收帐户名_Android_Android Ndk_Java Native Interface_Accountmanager - Fatal编程技术网

Android 从JNI调用Java方法需要上下文(this)来接收帐户名

Android 从JNI调用Java方法需要上下文(this)来接收帐户名,android,android-ndk,java-native-interface,accountmanager,Android,Android Ndk,Java Native Interface,Accountmanager,基本问题,但需要复杂的代码: 我想主要使用安卓NDK获取安卓设备上使用的帐户名。为了安全起见,应该尽可能多地使用本机代码。在分析Android源代码中*1(见下文)中建议的调用时,发现由于缺少权限,无法访问原始数据库文件并读取帐户名 因此,我的下一个方法是使用*1的代码(见下文),并将其放入src文件夹中一个单独的java类“Account”中。不幸的是,它需要活动上下文,我不知道如何在本机代码中请求它,因为一切都应该从本机代码中完成,而不包括主活动。我假设它可能是JNI调用的第二个参数thiz

基本问题,但需要复杂的代码:

我想主要使用安卓NDK获取安卓设备上使用的帐户名。为了安全起见,应该尽可能多地使用本机代码。在分析Android源代码中*1(见下文)中建议的调用时,发现由于缺少权限,无法访问原始数据库文件并读取帐户名

因此,我的下一个方法是使用*1的代码(见下文),并将其放入src文件夹中一个单独的java类“Account”中。不幸的是,它需要活动上下文,我不知道如何在本机代码中请求它,因为一切都应该从本机代码中完成,而不包括主活动。我假设它可能是JNI调用的第二个参数thiz,但我对此非常不确定

我当前的本机代码是基于*2的,看起来是这样的,但到目前为止还不起作用。你有什么建议或更好的解决方案吗?我可以直接从本机代码调用AccountManager吗

// based on http://www.rgagnon.com/javadetails/java-0284.html
JNIEXPORT jstring JNICALL Java_com_example_nils_myapplication_MyNDK_getMyString(JNIEnv* env, jobject thiz){

const char *str;

jclass myclass_class =(jclass) env->NewGlobalRef
        (env->FindClass ("com/example/nils/myapplication/Account"));

jmethodID constructorID = env->GetMethodID
        (myclass_class, "", "()V");

jmethodID methodID = env->GetMethodID
        (myclass_class, "getUsername", "(Landroid/content/Context;)Ljava/lang/String;");

jobject myclass_object =  env->NewObject
        (myclass_class, constructorID);

jstring s = (jstring)  env->CallObjectMethod
        (myclass_object, methodID, thiz);
[...]
这里是Java类

public class Account {
    public Account(){

    };

    // based on https://stackoverflow.com/questions/2727029/how-can-i-get-the-google-username-on-android
        public static String getUsername(Context c) {
            AccountManager manager = AccountManager.get(c);
            android.accounts.Account[] accounts = manager.getAccountsByType("com.google");
            LinkedList<String> possibleEmails = new LinkedList<String>();

            for (android.accounts.Account account : accounts) {
                // TODO: Check possibleEmail against an email regex or treat
                // account.name as an email address only for certain account.type values.
                possibleEmails.add(account.name);
            }

            if (!possibleEmails.isEmpty() && possibleEmails.get(0) != null) {
                String email = possibleEmails.get(0);
                String[] parts = email.split("@");

                if (parts.length > 1)
                    return parts[0];
            }
            return null;
        }


    }
作为对第二条评论的回复:MyNDK只是一个加载本机库的简单类,同时定义getMyString()方法

*一,


*好的,谢谢你的提示。我解决了。因此,解决方案如下:

构造函数需要作为名称

jmethodID constructorID = env->GetMethodID
        (myclass_class, "<init>", "()V")
还有什么?不会返回帐户名,但出于测试目的,我使用了一个固定的返回字符串。这解决了实际的JNI问题,应用程序运行正常,但java实现中接收帐户名时肯定仍然存在错误


无论如何。充分解决。谢谢大家。

“我想它可能是JNI调用的第二个参数thiz”
thiz
是对调用了
getMyString
的Java对象的引用。您还没有向我们展示该代码,因此我们无法确定这是否是有效的
上下文;出于测试目的,JNI调用现在从主活动中调用。但它不会在
MainActivity
的实例上调用。根据您的代码,它是在
MyNDK
的实例上调用的,不管是什么。我现在也添加了MyNDK类。因此,问题在于如何在本机代码中获取上下文,或者当前thiz是否正确……
thiz
是一个
MyNDK
实例,而不是
上下文。显而易见的解决方案是使用
公共本机字符串getMyString(Context)(并相应地更改C++函数),并用“代码> .GETMyStand(this)调用它;<代码>来自您的活动。
public class MyNDK {

    static{
        System.loadLibrary("MyLibrary");
    }
    public native String getMyString();
}
jmethodID constructorID = env->GetMethodID
        (myclass_class, "<init>", "()V")
public native String getMyString(Context c);


JNIEXPORT jstring JNICALL Java_com_example_nils_myapplication_MyNDK_getMyString
        (JNIEnv * env, jobject thiz, jobject thiz2) {