carsten-klaffke / send-intent

Repository for send-intent Capacitor plugin
MIT License
106 stars 12 forks source link

On android, app crashes when trying to share to it. #49

Closed AlonBru closed 2 years ago

AlonBru commented 2 years ago

Describe the bug Following instructions in the README, I added the activity on AndroidManifest.xml The app now appears in the share dialog, but when clicked it seems to open and crash immediately.

appreciate any help Screenshots If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

Additional context On ios everything works as expected

michael-maenner commented 2 years ago

My first guess, without knowing your code, would be that you have to add some code into MainActivity.java, this is by now not provided in the README

https://github.com/carsten-klaffke/send-intent/blob/master/Example/SendIntentExample/android/app/src/main/java/io/ionic/starter/MainActivity.java

public class MainActivity extends BridgeActivity {
  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    String action = intent.getAction();
    String type = intent.getType();

    if ((Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action)) && type != null) {
      bridge.getActivity().setIntent(intent);
      bridge.eval("window.dispatchEvent(new Event('sendIntentReceived'))", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String s) {
        }
      });
    }
  }
}
carsten-klaffke commented 2 years ago

Hey @AlonBru, please provide a bit more information! Is there an Exception in the Logs? Which send-intent Version are you using?

@michael-maenner: In the latest version, the code in MainActivity is not needed anymore. There is a separate activity now, which comes with the plugin.

AlonBru commented 2 years ago

Hey guys, thanks a lot for the quick responses!

send-intent version is 3.0.11. I test it on my phone, and when i tried looking at logs through chrome inspect-devices, I didn't see any error logs.

it doesnt really seem to open the app, just a brief transition appears and then back to the app I shared from. if I try multiple times I get a prompt saying " my-app keeps crashing"

carsten-klaffke commented 2 years ago

Hey @AlonBru, It's still hard to tell what causes your problem. My suggestion would be to run your app in debug mode and see if the SendIntent:checkSendIntentReceived()-call is executed properly. You could also/instead add some logging in your JS-code. What exactly are you trying to share?

alcalyn commented 2 years ago

I had the same crash when I tried this configuration:

        <activity
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:name="io.ionic.starter.MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBarLaunch"
            android:launchMode="singleTask">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

        <!-- accept share intent -->
        <activity
                android:name=".sendIntent.SendIntentActivity"
                android:label="@string/app_name"
                android:exported="true"
                android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
                <data android:mimeType="image/*" />
                <data android:mimeType="application/*" />
                <data android:mimeType="video/*" />
            </intent-filter>
        </activity>

It stopped crashing when changing to:

        <activity
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:name="io.ionic.starter.MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBarLaunch"
            android:launchMode="singleTask">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <!-- accept share intent -->
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
                <data android:mimeType="image/*" />
                <data android:mimeType="application/*" />
                <data android:mimeType="video/*" />
            </intent-filter>

        </activity>

Which looks like the config from this other plugin: https://www.npmjs.com/package/cordova-plugin-intent

But I still does not receive send intent...

I have these logs at app start:

onscript loading complete
VM3:218 native SendIntent.checkSendIntentReceived (#122024245)
VM3:192 result SendIntent.checkSendIntentReceived (#122024245)
App.vue?847a:23 send intent catch, err: Error: No processing needed
    at Object.cap.fromNative (VM3:413:32)
    at <anonymous>:1:18
eval @ App.vue?847a:23
VM3:218 native App.addListener (#122024246)

And nothing happens when I share a picture.

My App.vue looks like this:

import { SendIntent } from 'send-intent';

SendIntent.checkSendIntentReceived().then((result: any) => {
    if (result) {
        console.log('SendIntent received');
        console.log(JSON.stringify(result));
    }

    if (result.url) {
        console.log('send intent result:', result);
    }
}).catch(err => console.error('send intent catch, err:', err));

export default defineComponent({
    name: 'App',
    components: {
        IonApp,
        IonRouterOutlet,
    },
    created() {
        window.addEventListener('sendIntentReceived', () => {
            SendIntent.checkSendIntentReceived().then((result: any) => {
                console.log('event', result);

                if (result) {
                    // ...
                }
            });
        })
    },
});

But now it works when using the same https://github.com/carsten-klaffke/send-intent/blob/master/Example/SendIntentExample/android/app/src/main/java/io/ionic/starter/MainActivity.java file.

Is there a way not to modify generated files in android app, and instead use merge syntax to modify AndroidManifest and patching MainActivity.java ?

carsten-klaffke commented 2 years ago

Hey @alcalyn,

The first configuration is the plugin's latest one, which should be correct. If you have a crash with this, please send me an error message! There should be some exception if it crashes on the Java-part.

What you basically did with adjusting your Manifest.xml and using the activity from the old example, is going back to an earlier version of the plugin. That works in general, but it can lead to complicated state issues if you use the MainActivity of your app to handle the intents (e.g. the intent can re-appear unintentionally once your app goes into idle mode). Because of that, and also because returning to the original context as fast as possible is a common/standard behaviour for apps supporting share, I decided to handle the intent in a separate activity. This activity closes automatically if you leave your app and must be finished (by calling SendIntent.finish()) when you have processed the intent.

I hope this brings some light into the configuration decisions. If someone could send me an exception, that would be very helpful to track down the issues you have with it.

Best regards, Carsten

alcalyn commented 2 years ago

you use the MainActivity of your app to handle the intents

yes it's what I understand from android doc. Trying to use another activity didn't worked for me, nothing happens, no log.

And when it crashes, I tried to get some log, but same as Alon, I don't know how to get any log.

AlonBru commented 2 years ago

Ill try to look into running in debug mode today, thanks everyone for your help!

AlonBru commented 2 years ago

Hey, Attached the debugger to my app on my phone. this happened when I minimized my app, went in into chrome and tried to share text into the my app. I hope this helps, please let me know if there's anything else I can do to help. thanks!

D/Capacitor: App paused I/ViewRootImpl@c194a62[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 0 1 I/SurfaceControl: nativeRelease nativeObject s[498087462272] nativeRelease nativeObject e[498087462272] nativeRelease nativeObject s[498087460256] nativeRelease nativeObject e[498087460256] I/SurfaceControl: nativeRelease nativeObject s[498087460448] nativeRelease nativeObject e[498087460448] D/InputTransport: Input channel destroyed: 'ClientS', fd=169 I/SurfaceControl: nativeRelease nativeObject s[493931570144] nativeRelease nativeObject e[493931570144] W/libEGL: EGLNativeWindowType 0x7300858010 disconnect failed I/SurfaceControl: nativeRelease nativeObject s[495390879936] nativeRelease nativeObject e[495390879936] I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x7a0d5f6 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1826 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x9d08a47 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1836 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 I/ViewRootImpl@c194a62[MainActivity]: Relayout returned: old=(0,0,1080,2400) new=(0,0,1080,2400) req=(1080,2400)8 dur=83 res=0x5 s={false 0} ch=true fn=147 I/ViewRootImpl@c194a62[MainActivity]: stopped(true) old=false D/Capacitor/AppPlugin: Firing change: false V/Capacitor/AppPlugin: Notifying listeners for event appStateChange D/Capacitor/AppPlugin: No listeners found for event appStateChange D/Capacitor: App stopped D/Capacitor: Saving instance state! I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x7a0d5f6 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1826 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x9d08a47 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1836 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 I/ViewRootImpl@c194a62[MainActivity]: Relayout returned: old=(0,0,1080,2400) new=(0,0,1080,2400) req=(1080,2400)8 dur=115 res=0x5 s={false 0} ch=false fn=-1 W/System: A resource failed to call release. I/SurfaceControl: nativeRelease nativeObject s[495542542432] nativeRelease nativeObject e[495542542432] W/System: A resource failed to call release. I/SurfaceControl: nativeRelease nativeObject s[495542542336] nativeRelease nativeObject e[495542542336] D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main Process: org.il.Chimu, PID: 18383 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{org.il.Chimu/org.il.Chimu.sendIntent.SendIntentActivity}: java.lang.ClassNotFoundException: Didn't find class "org.il.Chimu.sendIntent.SendIntentActivity" on path: DexPathList[[zip file "/data/app/~~sioXDPsfq2tNSmzzArNbwg==/org.il.Chimu-KybLQco18YBtc4vmG-fNfg==/base.apk"],nativeLibraryDirectories=[/data/app/~~sioXDPsfq2tNSmzzArNbwg==/org.il.Chimu-KybLQco18YBtc4vmG-fNfg==/lib/arm64, /system/lib64]] at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3726) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8633) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) Caused by: java.lang.ClassNotFoundException: Didn't find class "org.il.Chimu.sendIntent.SendIntentActivity" on path: DexPathList[[zip file "/data/app/~~sioXDPsfq2tNSmzzArNbwg==/org.il.Chimu-KybLQco18YBtc4vmG-fNfg==/base.apk"],nativeLibraryDirectories=[/data/app/~~sioXDPsfq2tNSmzzArNbwg==/org.il.Chimu-KybLQco18YBtc4vmG-fNfg==/lib/arm64, /system/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95) at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45) at android.app.Instrumentation.newActivity(Instrumentation.java:1253) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3714) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4011)  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2325)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loop(Looper.java:246)  at android.app.ActivityThread.main(ActivityThread.java:8633)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)  I/Process: Sending signal. PID: 18383 SIG: 9 Disconnected from the target VM, address: 'localhost:64099', transport: 'socket'

carsten-klaffke commented 2 years ago

Hello,

this stack contains an error message that might get us a step further:

"com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) Caused by: java.lang.ClassNotFoundException: Didn't find class "org.il.Chimu.sendIntent.SendIntentActivity" on path: DexPathList[[zip file..."

So, for some reason your app is looking for the "SendIntentActivity"-class in the wrong package (should be "de.mindlib.sendIntent.SendIntentActivity" instead of "org.il.Chimu.sendIntent.SendIntentActivity"). Please double check that you have that package configured correctly in your AndroidManifest.xml!

<activity
        android:name="de.mindlib.sendIntent.SendIntentActivity"
...

Best regards Carsten

AlonBru commented 2 years ago

Hey, thanks for the reply.

Ive changed to what you said, my mistake, I thought this was similar to ios where I had to create an extension with a custom name.

Now I have no crash, so a step further indeed 🥳 .

Sadly though, it seems the event is not being fired. I have it set up like this: image

does it seem right?

When I try sharing a link, text or image ( haven't tried video), the app opens but:

When running with debug mode in android studio I don't see any messages at all.

Thanks again for all your help.

Best wishes, Alon

carsten-klaffke commented 2 years ago

Hey Alon,

on Android there is no event fired (anymore). As we have configured in AndroidManifest.xml, when receiving a "Send"-intent a new activity gets started. So you must call your handler on app startup. In your case just call handleIntent() before render() (you might also have to add a catch block to your handler, for the case your app wasn't started by share). I know that is a bit complicated, but unfortunately Android and iOS behave differently here. If you are done with your handling, don't forget to call SendIntent.finish()! This will close the additional activity.

And please, if everything works, let me know by closing this issue!

Best regards Carsten

AlonBru commented 2 years ago

Hi Carsten. I see now the difference. It works well for me now, thanks! May I suggest that the package should wrap this functionality in some way as to make the process easier for the user ( that they don't have to implement platform based logic)? I'd be glad to take a shot at a PR to make that happen, or edit the README to make the difference more clear.

All the best, Alon

carsten-klaffke commented 2 years ago

Sure, you're very welcome to create a PR on this!