无法在Unity C#中获取Activity的实例

时间:2015-05-29 00:01:15

标签: java c# android android-intent unity3d

我一直在尝试从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错误。

C#代码

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

    activity.Call("TakePicture");

它永远不会达到活动。呼叫(“TakePicture”);。

Java类-UPDATED WITH 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输出-UPDATED WITH NEW STATIC IMPLEMENTATION -

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字段。

的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(),但是,这并不能解决无法获取活动实例的原始问题。

cameraLinkContext为null,因为永远不会调用onCreate()。活动永远不会被“创造”。

2 个答案:

答案 0 :(得分:1)

你得到空指针异常,因为你尝试在AndroidJavaClass上调用非静态方法

答案 1 :(得分:0)

我能够根据YouTube教程制作解决方案(如果感兴趣,可以在下面链接)。

问题

问题在于Unity没有技术上知道活动,尽管它已在清单中定义,因此它无法创建它。有人在下面指出了这一点,但当我将我的活动作为主要活动时,该应用程序将拒绝启动。这是正确的方法,但如下所述还有更多方法。

解决方案

为了让它工作,我不得不复制UnityPlayerActivity的原始实现,并将其粘贴到我的Java项目中。在那里,我相应地定制了它,并扩展了UnityPlayerActivity。我将活动设置为清单中的主要活动。我并没有试图直接调用活动方法,而是建立了一个桥梁&#34;上课为我做。这简化了事情。 Java类中的UnityPlayer.currentActivity包含对UnityPlayer中当前活动的引用。在这种情况下,我的自定义类。我能够使用它调用Intent,现在它完美无缺。

逐步修复

第一步是复制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>

第三步是添加一个&#34;桥接&#34;在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 = new AndroidJavaClass(&#34; com.syncedsoftware.cameralink.LinkBridge&#34;);     jc.CallStatic(&#34; ShowCamera&#34;,1);

经过几天(字面意思)搜索答案后,我看到了这段视频:https://www.youtube.com/watch?v=4l64nUGt0l0这有很大帮助!我相应地调整了实现以适应我的Camera意图情况。

相关问题