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

Error MainActivity #30

Closed bbiaudet closed 4 years ago

bbiaudet commented 6 years ago

Hello I have an error while running the application under android when I call the function to launch unity, I have the following error:

06-29 16:04:47.106 18699-18699/fr.xx.xx E/ActivityThread: Activity fr.xx.xx.MainActivity has leaked IntentReceiver org.apache.cordova.plugin.CordovaUnityLauncher$UnityToIonicBroadcastReceiver@ec2200e that was originally registered here. Are you missing a call to unregisterReceiver()?

Compilation is not a problem.

Thank you for your help

yasirkula commented 6 years ago

Can you try changing CordovaUnityLauncher.java like this:

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;
    }

    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);
            }
        }
    }
}

Basically, I've just added broadcastReceiverRegistered and checked its value before doing any register/unregister operations.

bbiaudet commented 6 years ago

thank but same error

yasirkula commented 6 years ago

Inside Android Studio, can you verify that CordovaUnityLauncher.java is the same as above? How about making broadcastReceiverRegistered a static variable? Does it fix the issue?

bbiaudet commented 6 years ago

Yes inside the Android Studio is same file.

Same error

here is the device report:

java.lang.Error: FATAL EXCEPTION [main]
Unity version     : 2018.1.6f1
Device model      : Xiaomi Redmi 5 Plus
Device fingerprint: xiaomi/vince/vince:7.1.2/N2G47H/V9.5.12.0.NEGMIFA:user/release-keys

Caused by: java.lang.UnsatisfiedLinkError: No implementation found for void com.unity3d.player.UnityPlayer.nativeRestartActivityIndicator() (tried Java_com_unity3d_player_UnityPlayer_nativeRestartActivityIndicator and Java_com_unity3d_player_UnityPlayer_nativeRestartActivityIndicator__)
    at com.unity3d.player.UnityPlayer.nativeRestartActivityIndicator(Native Method)
    at com.unity3d.player.UnityPlayer.resume(Unknown Source)
    at com.unity3d.player.UnityPlayerActivity.onResume(Unknown Source)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1270)
    at android.app.Activity.performResume(Activity.java:6988)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3497)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3560)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
    at android.app.ActivityThread.-wrap12(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1549)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:163)
    at android.app.ActivityThread.main(ActivityThread.java:6379)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

however, at the function level: onActivityResult

the return code is: requestCode = 0 resultCode = 0 Activity.RESULT_OK = -1

yasirkula commented 6 years ago

Can I see the contents of your jniLibs, with subdirectories expanded? Also, what is your Unity version?

bbiaudet commented 6 years ago

My Unity Version is 2018.1.6f1

capture d ecran 2018-06-30 a 10 49 38
bbiaudet commented 6 years ago
capture d ecran 2018-06-30 a 10 51 29
yasirkula commented 6 years ago

I can see libmain.so and libunity.so in your jniLibs; which is a good sign. But it is also bad news because now I can't think of any reasons for the java.lang.UnsatisfiedLinkError to occur.

Can you build your Unity project to another empty folder, open it in Android Studio and run the project on your Xiaomi device to see if it works from Android Studio without Ionic integration?

Then, can you try running the Unity integrated Ionic project on an emulator to see if the issue is related to Xiaomi device? I'd suggest you to test the project on both an ARM emulator and an x86 Intel emulator.

bbiaudet commented 6 years ago

Ok, so the project generate from Unity without ionic integration and launch from Android Studio works perfectly. On the Android emulator the ionic / Unity project is running without problems.

yasirkula commented 6 years ago

What are the specs of your emulator?

bbiaudet commented 6 years ago

android 8 api 26 X86 base of Pixel 2 XL

bbiaudet commented 6 years ago

LogCat error

06-30 14:40:42.960 20133-20227/fr.neomabs.lx I/Timeline: Timeline: Activity_launch_request time:2694546 intent:Intent { cmp=fr.neomabs.lx/com.unitycaller.ionic.UnityPlayerExtendedActivity (has extras) }
06-30 14:40:42.971 20133-20133/fr.neomabs.lx D/CordovaActivity: Paused the activity.
06-30 14:40:43.001 20133-20227/fr.neomabs.lx W/PluginManager: THREAD WARNING: exec() call to LaunchAR.launchAR blocked the main thread for 45ms. Plugin should use CordovaInterface.getThreadPool().
06-30 14:40:43.016 20133-20227/fr.neomabs.lx D/YoikScreenOrientation: execute action: screenOrientation
    Requested ScreenOrientation: any
06-30 14:40:43.360 20133-20133/fr.neomabs.lx D/CordovaActivity: Stopped the activity.
    CordovaActivity.onDestroy()
06-30 14:40:43.369 20133-20133/fr.neomabs.lx D/CordovaWebViewImpl: >>> loadUrl(about:blank)
06-30 14:40:43.372 20133-20133/fr.neomabs.lx W/cr_AwContents: WebView.destroy() called while WebView is still attached to window.
06-30 14:40:43.387 20133-20133/fr.neomabs.lx W/ContentCatcher: Failed to notify a WebView
06-30 14:40:43.392 20133-20133/fr.neomabs.lx W/cr_AwContents: Application attempted to call on a destroyed WebView
    java.lang.Throwable
        at org.chromium.android_webview.AwContents.f(SourceFile:310)
        at org.chromium.android_webview.AwContents.a(SourceFile:282)
        at org.chromium.android_webview.AwContents.q(SourceFile:529)
        at ass.loadingStateChanged(SourceFile:159)
        at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
        at org.chromium.base.SystemMessageHandler.handleMessage(SourceFile:9)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:163)
        at android.app.ActivityThread.main(ActivityThread.java:6396)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
yasirkula commented 6 years ago

Pixel 2 XL: 64-bit ARM Xiaomi Redmi 5 Plus: 32-bit ARM

If Pixel 2 XL emulator had an Intel (x86) processor, then it'd suggest that there might be something wrong with the ARM libraries of Unity. However, now that is not an option. To be honest, I don't have any clues about this problem at this point. What I'd suggest you to do is first try Ionic integration with an empty Unity project and see if it works on Xiaomi. If not, you can try using a different Unity version.

Regarding the latest logcat error, if it doesn't crash the app or doesn't seem to affect anything, then I think it is harmless.

Hordtoss commented 6 years ago

I've solved this issue by deleting the x86 jniLibs and replacing the arm .so files with an older export from unity. It seems that the .so didn't export corectly. DId you by any change upgrade to another version of unity before getting this error?

learnez commented 6 years ago

Could you share the file with us?

I'm facing the same issue

juan9506 commented 5 years ago

Have you validate that the generated apk have no other folders than armeabi-v7a? I mean, you have to decompile it and then go to libs, and look if the only folder there is armeabi-v7a in my case, it was causing this problem, because another library was creating extra folders there like x86, arm64-v8a. if that's what's happening, you can either delete the plugins that are creating those folders or use the following plugin (it's very simple) to exclude de undesired folders and .so files: https://github.com/Jween/android-soexcluder

sidbait commented 5 years ago

In my libs, there are no other folder presents except armeabi-v7a. Still unable to launch unity app through ionic app.

Getting the following errors:

yasirkula commented 5 years ago

@sidbait Can you see if this post resolves your issue: https://github.com/yasirkula/UnityIonicIntegration/issues/51

seepot commented 4 years ago

do u solve this issue @bbiaudet ?

yasirkula commented 4 years ago

Related to: #61