我一直在尝试从Unity访问一个Activity方法,无法弄清楚为什么它不起作用。我已阅读各种网页,例如http://forum.unity3d.com/threads/call-a-method-in-an-activity-using-androidjavaobject.219950/和http://docs.unity3d.com/460/Documentation/Manual/PluginsForAndroid.html
我正在尝试为Unity创建一个Camera插件。有一些插件,但大多数已过时,不起作用。无论如何我都可以使用这些知识以备将来使用。我最初只是使用常规Java类,但为了拍照,我发现最好的路线是使用Intent,因为它被用于快速照片,而不是个性化的相机应用程序。要使用Intent,必须使用Activity。 Activity被传递给Intent,但Activity也必须覆盖一个方法,以便从Android文档中概述的Intent接收结果。我会链接到它,但我只限于2个链接。
我正在使用它来访问该活动。 AndroidJavaClass成功初始化,但是,当我尝试获取上下文时,我在logcat中得到一个null ptr错误。
AndroidJavaClass link = new AndroidJavaClass("com.syncedsoftware.cameralink.CameraLinkActivity");
AndroidJavaObject activity = link.Call<AndroidJavaObject>("getLinkContext"); // jni null ptr!
activity.Call("TakePicture");
它永远不会达到活动。呼叫(“TakePicture”);。
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()");
}
}
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()中的消息永远不会显示。这使我相信Activity没有被正确创建或创建。 Activity永远不会被“创建”,因此永远不会调用onCreate()来初始化Context字段。
<?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>
如果有人能解释为什么这不起作用,我将非常感激。我一直试图解决这个问题近一周,但无济于事。这是我第一次带着团结进入本土领域,请原谅我的无知。
将实现翻转为静态之后,我发现我忽略了logcat消息。将其翻转为静态时,会成功调用getLinkContext(),但是,这并不能解决无法获取活动实例的原始问题。
cameraLinkContext为null,因为永远不会调用onCreate()。活动永远不会被“创造”。
答案 0 :(得分:1)
你得到空指针异常,因为你尝试在AndroidJavaClass上调用非静态方法
答案 1 :(得分:0)
我能够根据YouTube教程制作解决方案(如果感兴趣,可以在下面链接)。
问题在于Unity没有技术上知道活动,尽管它已在清单中定义,因此它无法创建它。有人在下面指出了这一点,但当我将我的活动作为主要活动时,该应用程序将拒绝启动。这是正确的方法,但如下所述还有更多方法。
为了让它工作,我不得不复制UnityPlayerActivity的原始实现,并将其粘贴到我的Java项目中。在那里,我相应地定制了它,并扩展了UnityPlayerActivity。我将活动设置为清单中的主要活动。我并没有试图直接调用活动方法,而是建立了一个桥梁&#34;上课为我做。这简化了事情。 Java类中的UnityPlayer.currentActivity包含对UnityPlayer中当前活动的引用。在这种情况下,我的自定义类。我能够使用它调用Intent,现在它完美无缺。
第一步是复制UnityPlayerActivity.java的原始实现(在Unity安装子文件夹中找到)并自定义它。它还扩展了UnityPlayerActivity(原始版本),以确保所有内容都正确地链接到Unity。最初的实现定义了许多使Unity播放器首先工作的对象和方法。
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);
}
}
第二步是将活动添加为清单中的主要活动。
<?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>
第三步是添加一个&#34;桥接&#34;在Unity中调用以便于访问的类。
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 = new AndroidJavaClass(&#34; com.syncedsoftware.cameralink.LinkBridge&#34;); jc.CallStatic(&#34; ShowCamera&#34;,1);
经过几天(字面意思)搜索答案后,我看到了这段视频:https://www.youtube.com/watch?v=4l64nUGt0l0这有很大帮助!我相应地调整了实现以适应我的Camera意图情况。