2015-07-05 2 views
2

Я не могу найти, как получить ListArray переменных из AndroidJavaObject в C#.
Я пытаюсь сделать функцию for с использованием Count для количества элементов в ListArray, который хранится как AndroidJavaObject. Но мне нужно знать, как получить Count от AndroidJavaObject и как правильно его использовать.
Это то, что я использую для получения переменных, также обратите внимание, что «пакеты» не являются AndroidJavaObject[].Как получить переменные из AndroidJavaObject в класс C#, используя Unity3D

AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity"); 
int flag = new AndroidJavaClass("android.content.pm.PackageManager").GetStatic<int>("GET_META_DATA"); 
AndroidJavaObject pm = currentActivity.Call<AndroidJavaObject>("getPackageManager"); 
AndroidJavaObject packages = pm.Call<AndroidJavaObject>("getInstalledApplications", flag); 

это очень рудиментарные на данный момент, но это работает благодаря некоторой помощи от этого How to get installed apps list with Unity3D?

Прогресс до сих пор киосков на получение значок, все остальное работает отлично, мне нужен путь к получите либо string, который ссылается на значок так или иначе, либо на значок Texture2D.
Другой альтернативой было бы использовать AndroidJavaObject, который содержит drawable, как если бы это Texture2D. Я не знаю, как это сделать.
Еще одна идея, которую я имел, заключалась в том, чтобы преобразовать ее в другую переменную, например byte[], которую можно перенести и преобразовать обратно, но мне еще предстоит найти способ того, что работает под этим обстоятельством.

int count = packages.Call<int>("size"); 
AndroidJavaObject[] links = new AndroidJavaObject[count]; 
string[] names = new string[count]; 
Texture2D[] icons = new Texture2D[count]; 
int ii =0; 
for(int i=0; ii<count;){ 
    //get the object 
    AndroidJavaObject currentObject = packages.Call<AndroidJavaObject>("get", ii); 
    try{ 
     //try to add the variables to the next entry 
     links[i] = pm.Call<AndroidJavaObject>("getLaunchIntentForPackage", currentObject.Get<AndroidJavaObject>("processName")); 
     names[i] = pm.Call<string>("getApplicationLabel", currentObject); 
     icons[i] = pm.Call<Texture2D>("getApplicationIcon", currentObject); 
     Debug.Log ("(" + ii + ") " + i +" "+ names[i]); 
     //go to the next app and entry 
     i++; 
     ii++; 
    } 
    catch 
    { 
     //if it fails, just go to the next app and try to add to that same entry. 
     Debug.Log("skipped "+ ii); 
     ii++; 
    } 

} 

Ненавижу задать два вопроса подряд здесь, и я извиняюсь за то, чтобы сделать это, но это трудно, и, казалось бы, неуклюжим обстоятельство, что имеет мало никакой документации (что я могу найти) ,

ответ

3

Прежде всего, документы на стыке между Unity3D и Android в лучшем случае ограничены.

Самое главное, что единственный интерфейс Unity для работы с java-объектом - AndroidJavaObject, и этот интерфейс имеет только несколько методов: defined. Вы можете использовать только те, и только те.

Это означает, что вы не получаете объект Count при работе с массивом java, и вы все равно будете работать с AndroidJavaObject.

int count = packages.Call<int>("size"); //getting the size of the array 

for(int i = 0; i < count; i++) 
{ 
//getting the object at location i 
AndroidJavaObject currentObject = packages.Call("get", i); 

//use currentObject using the same methods as before: Call, CallStatic, Get, GetStatic 
} 

Я знаю, что это многословным, и писать код, как это трудно проверить, что вам нужно сделать, и APK и развернуть его на устройство, чтобы проверить, что он работает.

Возможно, более быстрый способ сделать это - создать свой собственный класс java, который сделает все это на стороне java и выставить один метод, который вызывается со стороны Unity. Таким образом, по крайней мере, вы получаете преимущество статического ввода при создании банку, которую вы добавите в папку Plugins/Android.

+0

Метод, который вы описываете для получения счета, не работает, к сожалению, я попробовал получить и вызвать статичный и нет, капитал и не. Я привык к повторному развертыванию после каждого небольшого изменения на данный момент, ха-ха. Я не против работать с 'AndroidJavaObject', пока я получаю переменные, которые мне нужны в долгосрочной перспективе. чтобы сделать это java side, мне бы, вероятно, пришлось сделать вызов, который ничего не возвращает, а вместо этого, через java, сохраняет переменные в файл, который я могу проанализировать с помощью C#, мне также нужно будет изучить Java, Eclipse и т. п. У меня нет опыта в обоих. Я отредактирую сообщение, чтобы использовать ваш пример. –

+0

Я обновил свой ответ, метод, который вам нужно назвать, - это размер –

+0

. Кажется, он работает идеально, имел/имел проблемы с получением переменных, должен был стать творческим с получением имен, выполнив 'pm.Call (« getApplicationLabel ", currentObject)'. Я думаю, мне нужно изменить строку ссылки на «AndroidJavaObject», чтобы я мог сохранить намерение запуска, чтобы позже узнать, как использовать 'something.Call (« startActivity », intent). Я уточню сообщение о том, как это происходит до сих пор, если у вас есть идеи, я был бы рад их услышать, но утром я должен снова проверить. –

2

Я пытаюсь сделать то же самое здесь, но моя пусковая установка должна показывать только приложения CardBoard.Что я решил это сделать библиотеку Java и импортировать его в Unity как плагин:

Это мой Java класс:

public class Launcher extends UnityPlayerActivity { 

private List<ApplicationInfo> cbApps; 

@Override 
protected void onStart() { 
    super.onStart(); 

    PackageManager pm= getPackageManager(); 
    List<ApplicationInfo> lista = pm.getInstalledApplications(PackageManager.GET_META_DATA); 
    cbApps= new LinkedList<ApplicationInfo>(); 

    for(ApplicationInfo ai : lista){ 
     Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 
     intentToResolve.addCategory("com.google.intent.category.CARDBOARD"); 
     intentToResolve.setPackage(ai.packageName); 
     if(pm.resolveActivity(intentToResolve, 0)!=null) { 
      cbApps.add(ai); 
     } 
    } 
} 


public int getListSize(){ 
    return cbApps.size(); 
} 

А вот мой C метод #:

void Start() { 
    AndroidJavaClass unity = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); 
    AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject> ("currentActivity"); 
    texto.text=""+currentActivity.Call<int> ("getListSize"); 

} 

Таким образом, я могу создать в Java каждый метод, который мне нужен для доступа к списку. Проблема, которую я все еще испытываю, заключается в попытке получить Texture2D из значков. Я попытался вернуть Drawable с Java и присоединиться к Call так же, как вы, но он вообще не работает. Я работаю с этим два дня, я дам вам знать, найду ли я решение.

EDIT: Наконец я мог бы получить изображения:

Сначала в Java Я создал этот метод:

public byte[] getIcon(int i) { 
     BitmapDrawable icon= (BitmapDrawable)context.getPackageManager().getApplicationIcon(cbApps.get(i)); 
     Bitmap bmp = icon.getBitmap(); 
     ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
     bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); 
     byte[] byteArray = stream.toByteArray(); 
     return byteArray; 
    } 

Таким образом я могу получить доступ к массиву байт, представляющий вытяжку из единства и показать его как основная текстура плоскости:

void Start() { 
    using (AndroidJavaClass unity = new AndroidJavaClass ("com.unity3d.player.UnityPlayer")) { 
     context = unity.GetStatic<AndroidJavaObject> ("currentActivity"); 
    } 
    using (AndroidJavaClass pluginClass=new AndroidJavaClass("com.droiders.launcher.Launcher")) { 
     launcher= pluginClass.CallStatic<AndroidJavaObject>("getInstance", context); 
     byte[] bytes= launcher.Call<byte[]>("getIcon",0); 
     Texture2D tex= new Texture2D(2,2); 
     tex.LoadImage(bytes); 
     plane.GetComponent<Renderer>().material.mainTexture=tex; 
    } 

} 

Надеюсь, это поможет вам. Это было сложно, но этот зверь был приручен: P Также благодарим всех вас за ваши идеи.

+0

Если у вас есть новый вопрос, обратитесь к нему, нажав кнопку [Ask Question] (http://stackoverflow.com/questions/ask). Включите ссылку на этот вопрос, если это поможет обеспечить контекст. –

+2

Это был не новый вопрос, он спросил 2, я отвечаю на первый, но я сказал ему, что у меня нет ответа на второй. Но спасибо, я сделаю то, что вы предложили. – Varu

+0

Да, часть значка очень сложная. Я знаю, что это можно сделать, если вы преобразуете Drawable в массив байтов изображения через java, а затем преобразуете массив байтов в Texture2D на C#, но я не знаю, как это сделать. И я понятия не имею, есть ли более простой и/или более эффективный метод. Честно. Вероятно, это просто более эффективно, чтобы создать его через Android Studio. –

Смежные вопросы