2015-05-29 6 views
3

Я пытаюсь получить доступ к методу Activity из Unity и не могу понять, насколько он работает, почему он не работает. Я читал различные страницы, такие как http://forum.unity3d.com/threads/call-a-method-in-an-activity-using-androidjavaobject.219950/ и http://docs.unity3d.com/460/Documentation/Manual/PluginsForAndroid.htmlНевозможно получить экземпляр Activity in Unity C#

Я пытаюсь создать плагин камеры для Unity. Есть некоторые плагины, но большинство из них устарело и не работает. В любом случае я мог бы использовать эти знания для будущего использования. Я изначально просто использовал обычный Java-класс, но, чтобы сделать снимок, я обнаружил, что лучшим маршрутом было использование намерения в связи с тем, что он используется для быстрых фотографий, а не для персонализированного приложения камеры. Чтобы использовать намерение, необходимо использовать действие. Активность передается в Intent, но Activity также должна переопределить метод для получения результата из Intent, как описано в документации для Android. Я бы связался с ним, но я ограничен двумя ссылками.

Я использую это для доступа к активности. Однако AndroidJavaClass успешно инициализируется, когда я пытаюсь получить контекст, я получаю ошибку null ptr в logcat.

C# код

AndroidJavaClass link = new AndroidJavaClass("com.syncedsoftware.cameralink.CameraLinkActivity"); 
    AndroidJavaObject activity = link.Call<AndroidJavaObject>("getLinkContext"); // jni null ptr! 

    activity.Call("TakePicture"); 

Он никогда не достигает activity.Call ("TakePicture") ;.

класс Java -Обновленного С STATICS-

public class CameraLinkActivity extends UnityPlayerActivity { 

private static Context cameraLinkContext; 

public static Context getLinkContext(){ 
    Log.v("Unityx", "GetLinkContext()"); 
    return cameraLinkContext; 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.v("Unity", "OnCreate"); 
    cameraLinkContext = this; 
} 

public void TakePicture(){ 
    Log.v("Unity", "TakePicture()"); 
} 
} 

выхода LogCat -Обновленного С НОВОГО STATIC реализации-

05-29 12:32:50.560 3408-3498/? V/Unityx﹕ GetLinkContext() 
05-29 12:32:50.810 3408-3498/? I/Unity﹕ Exception: JNI: Init'd AndroidJavaObject with null ptr! 
     at UnityEngine.AndroidJavaObject..ctor (IntPtr jobject) [0x00000] in <filename unknown>:0 
     at UnityEngine.AndroidJavaObject.AndroidJavaObjectDeleteLocalRef (IntPtr jobject) [0x00000] in <filename unknown>:0 
     at UnityEngine.AndroidJavaObject._CallStatic[AndroidJavaObject] (System.String methodName, System.Object[] args) [0x00000] in <filename unknown>:0 
     at UnityEngine.AndroidJavaObject.CallStatic[AndroidJavaObject] (System.String methodName, System.Object[] args) [0x00000] in <filename unknown>:0 
     at AndroidCameraLink.Start() [0x00000] in <filename unknown>:0 

Что-то я заметил, что сообщение в OnCreate() никогда не отображается. Это заставляет меня думать, что деятельность не создается должным образом или не создается вообще. Деятельность никогда не «создается», поэтому onCreate() никогда не вызывается для инициализации поля «Контекст».

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.syncedsoftware.cameralink"  android:theme="@android:style/Theme.NoTitleBar" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal"> 
    <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" /> 
    <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false"> 
    <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"> 
     <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 
     <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
     <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> 
     <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" /> 
    </activity> 
<activity android:name="com.syncedsoftware.cameralink.CameraLinkActivity" /> 
     </application> 
     <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="18" /> 
     <uses-feature android:glEsVersion="0x00020000" /> 
     <uses-permission android:name="android.permission.INTERNET" /> 
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.CAMERA" /> 
<uses-feature android:name="android.hardware.camera" /> 
</manifest> 

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

UPDATE: getLinkContext() вызывается, но проблема сохраняется.

После того, как вы выполнили реализацию до статики, я обнаружил, что я пропускаю сообщение logcat. При переключении на статичное, getLinkContext() успешно вызван, однако, это не устраняет исходную проблему неспособности получить экземпляр Activity.

cameraLinkContext имеет значение null, потому что onCreate() никогда не вызывается. Активность никогда не «создается».

+0

Пожалуйста, используйте тег unity3d. –

+1

Прошло некоторое время с тех пор, как я использовал любое действие, которое расширяет UnityPlayerNativeActivity (мы переключились на совершенно другой способ создания плагинов давным-давно), поэтому я не уверен на 100%, но я считаю, что проблема может заключаться в тот факт, что ваша пользовательская активность (com.syncedsoftware .....) не отмечена как MainActivity в манифесте. В принципе, замените «com.unity3d.player.UnityPlayerNativeActivity» с именем вашей деятельности в манифесте. –

+0

@VenkatatAxiomStudios После этого приложение даже не запустится. Я получаю сообщение с тостом, в котором говорится: «Приложение не установлено». –

ответ

0

я смог подделать решение, основанное на учебнике YouTube (ссылку, если интересно).

Проблема

Проблема проживающих в том, что Unity не технически знают о деятельности, несмотря на это определяется в манифесте, поэтому он не смог создать. Кто-то указал на это ниже, но когда я сделал свою деятельность основной деятельностью, приложение откажется запускать. Это был правильный подход, но было больше, как описано ниже.

Решение

Для того, чтобы заставить его работать, мне пришлось скопировать оригинальную реализацию UnityPlayerActivity, и вставьте его в свой проект Java. Там я настроил его соответствующим образом и расширил UnityPlayerActivity. Я установил активность как основное действие в манифесте. Вместо того, чтобы пытаться напрямую вызвать метод активности, я сделал класс «bridge», чтобы сделать это для меня. Это упрощенные вопросы. UnityPlayer.currentActivity в классах Java содержит ссылку на текущую активность, которая используется в UnityPlayer. В этом случае мой индивидуальный класс. Я смог использовать это намерение, и теперь все работает безупречно.

Шаг за шагом Фикс

Первого шаг должны был скопировать исходные реализации UnityPlayerActivity.java (находится в подпапке установки Unity) и настроить его. Он также расширяет UnityPlayerActivity (оригинал), чтобы убедиться, что все правильно связано с Unity. Первоначальная реализация определяет множество объектов и методов, которые заставляют игрока Unity работать в первую очередь.

UnityPlayerActivity.java

package com.syncedsoftware.player; // changed package name 

import android.content.Intent; 
import android.os.Bundle; 

import com.unity3d.player.UnityPlayer; 

public class UnityPlayerActivity extends com.unity3d.player.UnityPlayerActivity // extends the ORIGINAL implementation 
{ 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    // Process intent data 
} 

// Setup activity layout 
@Override protected void onCreate (Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
} 
} 

Вторым шагом был добавить активность в качестве основной активности в манифесте.

AndroifManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.syncedsoftware.inventory" android:theme="@android:style/Theme.NoTitleBar" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal"> 
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" /> 
<application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false" android:isGame="false" android:banner="@drawable/app_banner"> 
<activity android:name="com.syncedsoftware.player.UnityPlayerActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"> 
    <intent-filter> 
    <action android:name="android.intent.action.MAIN" /> 
    <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
    </activity> 
    </application> 
    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="18" /> 
    <uses-feature android:glEsVersion="0x00020000" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-feature android:name="android.hardware.camera" /> 
    <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> 
</manifest> 

Третий шаг должен был добавить в классе «моста», чтобы призвать в Unity для легкого доступа.

LinkBridge.java

package com.syncedsoftware.cameralink; 

import android.content.Intent; 
import android.provider.MediaStore; 

import com.unity3d.player.UnityPlayer; 

/** 
* Created by Anthony on 5/30/2015. 
*/ 
public class LinkBridge { 

public static void ShowCamera(int requestCode){ 
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    UnityPlayer.currentActivity.startActivityForResult(cameraIntent, requestCode); // Gets custom activity and uses the callback accordingly 
} 

} 

Наконец, мы добавим код в Unity, чтобы вызвать ShowCamera(). # C# код AndroidJavaClass jc = новый AndroidJavaClass ("com.syncedsoftware.cameralink.LinkBridge"); jc.CallStatic («ShowCamera», 1);

После нескольких дней (буквально) в поисках ответа я наткнулся на это видео: https://www.youtube.com/watch?v=4l64nUGt0l0 Это очень помогло! Я перевернул реализации, соответственно, в соответствии с ситуацией с моей камерой.

1

Вы получаете исключения нулевого указателя, так как вы пытаетесь вызова, не статический метод AndroidJavaClass

+0

Если я изменяю реализацию на статическую, она вызывает getLinkContext() успешно, но она все равно бросает jni null ptr.Вероятно, это связано с тем, что активность не инициализируется. Контекст NULL, потому что onCreate() никогда не вызывается. –

+0

Сообщение было обновлено, чтобы отразить это. Ваше решение устраняет одну из проблем, спасибо! Однако активность все еще не «создана». –

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