temel mesele almak için içerik (bu) gerektiren JNI gelen yöntem, ama karmaşık kodu gerekir:çağrılması Java hesap adı
Ben esas Android NDK kullanarak Android cihazda kullanılan hesap adı almak istiyorum. Yerel amaçlar için güvenlik amacıyla olabildiğince çok yapılmalıdır. Android'in kaynak kodlarında * 1'de (aşağıya bakın) önerilen çağrıları analiz ederken, ham veritabanı dosyasına erişmenin mümkün olmadığını ve muhtemelen eksik izinler nedeniyle hesap adını okuyabildiğini gördük.
Bundan sonraki yaklaşımım, * 1 kodunu (aşağıya bakınız) kullanmak ve src klasöründeki ayrılmış bir "java" sınıfına yerleştirmekti. Maalesef, etkinlik bağlamını gerektiriyor ve yerel kodda nasıl isteneceğine dair bir fikrim yok, çünkü ana aktiviteyi içermeden her şey yerel koddan yapılmalıdır. JNI çağrısının 2. parametre tezi olabileceğini sanıyorum, ama bu konuda çok emin değilim.
Geçerli yerel kodumda * 2 var ve buna benziyor, ancak şu ana kadar çalışmıyor. Herhangi bir ipucunuz veya daha iyi çözümleriniz var mı? AccountManager'ı doğrudan yerel koddan arayabilir miyim?
// 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);
[...]
İşte Java sınıfı
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;
}
}
cevapta 1. Yorum yapmak: Tabii, yerel kod bir yere başlangıçta çağrılacak vardır. Test amaçlı olarak, bu aramayı ana etkinliğimin onCreate() yöntemine yerleştirdim. 2 yoruma cevap olarak
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyNDK a = new MyNDK();
Log.i("MyTag", a.getMyString());
: MyNDK getMyString() yöntemini tanımlarken, yerli kütüphane yüklemek için sadece basit bir sınıftır.
public class MyNDK {
static{
System.loadLibrary("MyLibrary");
}
public native String getMyString();
}
* 1 How can I get the google username on Android?
* 2 http://www.rgagnon.com/javadetails/java-0284.html
_ "JNI çağrısının 2. parametresi olabileceğini varsayalım" _ 'thiz ', getMyString öğesinin çalıştırıldığı Java nesnesine yapılan bir başvurudır. Bize bu kodu göstermediniz, bu yüzden geçerli bir 'İçerik 'olup olmadığını gerçekten söyleyemeyiz. – Michael
yukarıdan bakın; JNI çağrısının şu an ana aktiviteden alındığı test amaçlı. – Nils
Ancak, "MainActivity" örneğinde _on_ çağrılmıyor.Kodunuza göre, ne olursa olsun, MyNDK'nin bir örneğinde çağrılır. – Michael