使Unity Android活动与Android服务进行通信

时间:2018-08-20 06:16:11

标签: android unity3d plugins service broadcastreceiver

我正在尝试设置一个后台服务,以便与我在Unity中开发的游戏一起使用。在这个阶段,我希望变量能够更新并在服务启动后统一显示。当前,该变量每秒更新一次,并显示在烤面包上,但不能被统一看到或使用。

我已尝试根据本教程http://jeanmeyblum.weebly.com/scripts--tutorials/communication-between-an-android-app-and-unity设置BroadcastReceiver 但是它似乎已经过时了,其他人也在努力解决这个问题。

统一代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PluginWrapper : MonoBehaviour {

TextMesh textmesh;

AndroidJavaClass unityClass;
AndroidJavaObject unityActivity;
AndroidJavaClass customClass;
// Use this for initialization
void Start () {
    //AndroidJNIHelper.debug = true;
    textmesh = GetComponent<TextMesh>();  
    sendActivityReference("com.example.locationplugin.StatusCheckStarter");
    customClass.CallStatic("createInstance");
}

void Update() {
    print(customClass.GetStatic<string>("text"));
}

public void clickButton() {
    startService();
    customClass.CallStatic("makeToast");
}

public void decreaseCount() {
    stopService();
}

void sendActivityReference(string packageName) {
    unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    unityActivity = unityClass.GetStatic<AndroidJavaObject> ("currentActivity");
    customClass = new AndroidJavaClass(packageName);
    customClass.CallStatic("receiveActivityInstance", unityActivity);
}

void startService() {
    customClass.CallStatic("StartCheckerService");
}

void stopService() {
    customClass.CallStatic("StopCheckerService");
}
}

Android插件:

    package com.example.locationplugin;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

public class LocationPlugin extends Service {

public LocationPlugin ref;
public static int number = 0;
private final Handler handler = new Handler();

private Runnable sendData = new Runnable() {
    public void run() {
        number++;

        send(number);

        Toast.makeText(ref, "number is: " + number, Toast.LENGTH_LONG).show();

        // In our case we run this method each 2 second with postDelayed
        handler.removeCallbacks(this);
        handler.postDelayed(this, 1000);
    }
};

public void send(int num) {
    Intent sendIntent = new Intent();

    sendIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_FROM_BACKGROUND | Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    sendIntent.setAction("com.example.locationplugin.LocationPlugin");
    sendIntent.putExtra(Intent.EXTRA_TEXT, num);
    sendBroadcast(sendIntent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startID) {
    // number = 0;
    ref = this;
    Toast.makeText(this, "service started", Toast.LENGTH_LONG).show();

    handler.removeCallbacks(sendData);
    handler.postDelayed(sendData, 1000);
    return START_STICKY;
}

public void onDestroy() {
    super.onDestroy();
    Toast.makeText(this, "service stopped", Toast.LENGTH_LONG).show();
    handler.removeCallbacks(sendData);
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}
}

广播接收器:

    package com.example.locationplugin;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public final class StatusCheckStarter extends BroadcastReceiver{
static Context myActivity;
private static StatusCheckStarter instance;
public static LocationPlugin loc = new LocationPlugin();
public static String text = "hello world";

public static void makeToast(){
    Toast.makeText(myActivity, text, Toast.LENGTH_LONG).show();
}

public static void receiveActivityInstance(Context tempActivity) {
    myActivity = tempActivity;
}

public static void StartCheckerService() {
    myActivity.startService(new Intent(myActivity, LocationPlugin.class));
}

public static void StopCheckerService() {
    myActivity.stopService(new Intent(myActivity, LocationPlugin.class));
}


@Override
public void onReceive(Context context, Intent intent) {
    Toast.makeText(myActivity, "received!!!!", Toast.LENGTH_LONG).show();

    String sentIntent = intent.getStringExtra(Intent.EXTRA_TEXT);
    text = "got into onreceive";
    if (sentIntent != null) {
        // We assigned it to our static variable
        text = sentIntent;
    }
}

public static void createInstance()
{
    if(instance ==  null)
    {
        instance = new StatusCheckStarter();
    }
}
}

Android清单:

    <?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<supports-screens
    android:smallScreens="true"
    android:normalScreens="true"
    android:largeScreens="true"
    android:xlargeScreens="true"
    android:anyDensity="true"/>

<application
    android:theme="@style/UnityThemeSelector"
    android:icon="@drawable/app_icon"
    android:label="@string/app_name">
    <activity android:name="com.unity3d.player.UnityPlayerActivity"
              android:label="@string/app_name">
        <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" />
    </activity>

  <receiver android:name="com.example.locationplugin.StatusCheckStarter">
    <intent-filter>
      <action android:name="com.example.locationplugin.LocationPlugin" ></action>
    </intent-filter>
  </receiver>


  <service android:name="com.example.locationplugin.LocationPlugin"/>

</application>
</manifest>

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

Toast应该在UI Thread上执行。请尝试这个。

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                      Toast.makeText(ref, "number is: " + number, Toast.LENGTH_LONG).show();
                }
}