yasirkula / UnityIonicIntegration

A guide to integrating Unity 3D content into an Ionic app and sending messages between them (for Android & iOS)(tested with Vuforia plugin)
104 stars 32 forks source link

app crash when launch unity #61

Closed seepot closed 4 years ago

seepot commented 4 years ago

hello,

i got this error when trying to launch AR in ionic app

2019-12-17 11:59:49.804 31255-31255/my.com.menarakl.app E/ActivityThread: Activity my.com.menarakl.app.MainActivity has leaked IntentReceiver org.apache.cordova.plugin.CordovaUnityLauncher$UnityToIonicBroadcastReceiver@49a799d that was originally registered here. Are you missing a call to unregisterReceiver()? android.app.IntentReceiverLeaked: Activity my.com.menarakl.app.MainActivity has leaked IntentReceiver org.apache.cordova.plugin.CordovaUnityLauncher$UnityToIonicBroadcastReceiver@49a799d that was originally registered here. Are you missing a call to unregisterReceiver()? at android.app.LoadedApk$ReceiverDispatcher.(LoadedApk.java:1588) at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:1368) at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1515) at android.app.ContextImpl.registerReceiver(ContextImpl.java:1488) at android.app.ContextImpl.registerReceiver(ContextImpl.java:1476) at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:627) at org.apache.cordova.plugin.CordovaUnityLauncher.execute(CordovaUnityLauncher.java:80) at org.apache.cordova.CordovaPlugin.execute(CordovaPlugin.java:98) at org.apache.cordova.PluginManager.exec(PluginManager.java:132) at org.apache.cordova.CordovaBridge.jsExec(CordovaBridge.java:59) at org.apache.cordova.engine.SystemExposedJsApi.exec(SystemExposedJsApi.java:41) at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:336) at android.os.Looper.loop(Looper.java:174) at android.os.HandlerThread.run(HandlerThread.java:67)

jakeeind commented 4 years ago

image

I got this problem too when clicked the unity button

yasirkula commented 4 years ago

Can you try changing CordovaUnityLauncher.java as follows:

package org.apache.cordova.plugin;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class CordovaUnityLauncher extends CordovaPlugin
{
    public static class UnityToIonicBroadcastReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) 
        {
            if( intent.hasExtra( "message" ) )
            {
                CordovaUnityLauncher ionicPlugin = CordovaUnityLauncher.getInstance();
                if( ionicPlugin != null )
                    ionicPlugin.onMessageReceivedFromUnity( intent.getStringExtra( "message" ) );
            }
            else
                Log.w( "UnityIonic", "No 'message' input is specified in UnityToIonicBroadcastReceiver!" );
        }
    }

    private static CordovaUnityLauncher Instance = null;

    public final int UNITY_LAUNCH_OP = 11;

    public static final String IONIC2UNITY_SEND_MESSAGE_BROADCAST = "IONIC2UNITY_SEND_MESSAGE";
    public static final String UNITY2IONIC_SEND_MESSAGE_BROADCAST = "UNITY2IONIC_SEND_MESSAGE";

    private CallbackContext callback = null;

    private UnityToIonicBroadcastReceiver broadcastReceiver = new UnityToIonicBroadcastReceiver();
    private boolean broadcastReceiverRegistered = false;

    public static CordovaUnityLauncher getInstance() 
    {
        return Instance;
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException 
    {
        if (action.equals("launchAR")) 
        {
            String param = "";
            try
            {
                param = args.getString(0);
            }
            catch( Exception e )
            {
            }

            callback = callbackContext;

            cordova.setActivityResultCallback (this);

            Intent intent = new Intent();
            intent.setClassName(cordova.getActivity().getPackageName(),"com.unitycaller.ionic.UnityPlayerExtendedActivity");
            intent.putExtra("my_param", param);

            Instance = this;

            if (!broadcastReceiverRegistered)
            {
                cordova.getActivity().registerReceiver(broadcastReceiver, new IntentFilter( UNITY2IONIC_SEND_MESSAGE_BROADCAST ) );
                broadcastReceiverRegistered = true;
            }

            cordova.startActivityForResult (this, intent, UNITY_LAUNCH_OP);

            return true;
        }
        else if (action.equals("sendMessage")) 
        {
            try
            {
                String func = args.getString(0);
                String param = args.getString(1);

                // Need to send broadcast for IPC as Ionic and Unity run on different processes
                Intent unityMessage = new Intent( IONIC2UNITY_SEND_MESSAGE_BROADCAST );
                unityMessage.putExtra( "func", func );
                unityMessage.putExtra( "param", param );
                cordova.getActivity().sendBroadcast( unityMessage );
            }
            catch( Exception e )
            {
                Log.e( "UnityIonic", "exception", e );
            }

            return true;
        }

        return false;
    }

    @Override
    public void onStart()
    {
        if (!broadcastReceiverRegistered)
        {
            cordova.getActivity().registerReceiver(broadcastReceiver, new IntentFilter( UNITY2IONIC_SEND_MESSAGE_BROADCAST ) );
            broadcastReceiverRegistered = true;
        }
    }

    @Override
    public void onStop()
    {
        if (broadcastReceiverRegistered)
        {
            cordova.getActivity().unregisterReceiver(broadcastReceiver);
            broadcastReceiverRegistered = false;
        }
    }

    public void onMessageReceivedFromUnity(String message) 
    {
        if( callback != null )
        {
            PluginResult result = new PluginResult(PluginResult.Status.OK, "MESSAGE" + message);
            result.setKeepCallback(true);
            callback.sendPluginResult(result);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        if( requestCode == UNITY_LAUNCH_OP && callback != null )
        {
            if( resultCode == Activity.RESULT_OK && data.hasExtra("my_param") )
            {
                if (broadcastReceiverRegistered)
                {
                    cordova.getActivity().unregisterReceiver(broadcastReceiver);
                    broadcastReceiverRegistered = false;
                }

                PluginResult result = new PluginResult(PluginResult.Status.OK, "RETURN" + data.getStringExtra("my_param"));
                result.setKeepCallback(true);
                callback.sendPluginResult(result);
            }
            else
            {
                PluginResult result = new PluginResult(PluginResult.Status.ERROR, "" );
                result.setKeepCallback(true);
                callback.sendPluginResult(result);
            }
        }
    }
}
seepot commented 4 years ago

i solved it by add this line in string.xml

<string name="game_view_content_description">Game view</string>