alinz / react-native-share-extension

react-native as an engine to drive share extension
MIT License
762 stars 397 forks source link

Error after clicking on my app icon during sharing (Expokit, Android) #204

Open flo-wolf opened 4 years ago

flo-wolf commented 4 years ago

I am running an ejected expo project (Expokit, SDK 36). I have managed to install the module successfully and my application appears in the list of apps to share to for the specified mime types.

Though when I click my app icon, I get the following error:

W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@94102b5
V/FA: onActivityCreated
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.florianwolf.voicekeep, PID: 11585
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.florianwolf.voicekeep/host.exp.exponent.share.ShareActivity}: java.lang.ClassCastException: host.exp.exponent.MainApplication cannot be cast to com.facebook.react.ReactApplication
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.ClassCastException: host.exp.exponent.MainApplication cannot be cast to com.facebook.react.ReactApplication
        at com.facebook.react.ReactActivityDelegate.getReactNativeHost(ReactActivityDelegate.java:61)
        at com.facebook.react.ReactActivityDelegate.onCreate(ReactActivityDelegate.java:76)
        at com.facebook.react.ReactActivity.onCreate(ReactActivity.java:44)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

MainApplication.java:

package host.exp.exponent;

import android.util.Log;

import com.facebook.react.ReactPackage;

import org.unimodules.core.interfaces.Package;

import java.util.Arrays;
import java.util.List;

import expo.loaders.provider.interfaces.AppLoaderPackagesProviderInterface;
import host.exp.exponent.generated.BasePackageList;
import okhttp3.OkHttpClient;

import com.alinz.parkerdan.shareextension.SharePackage;

public class MainApplication extends ExpoApplication implements AppLoaderPackagesProviderInterface<ReactPackage> {

  @Override
  public boolean isDebug() {
    return BuildConfig.DEBUG;
  }

  // Needed for `react-native link`
  public List<ReactPackage> getPackages() {

    // debugging message with amother tag:
    Log.d("GetPackages","reached");

    return Arrays.<ReactPackage>asList(
        // Add your own packages here!
        // TODO: add native modules!

        // Needed for `react-native link`
        // new MainReactPackage(),
            new SharePackage()
    );
  }

  public List<Package> getExpoPackages() {
    return new BasePackageList().getPackageList();
  }

  @Override
  public String gcmSenderId() {
    return getString(R.string.gcm_defaultSenderId);
  }

  public static OkHttpClient.Builder okHttpClientBuilder(OkHttpClient.Builder builder) {
    // Customize/override OkHttp client here
    return builder;
  }
}

MainActivity.java:

package host.exp.exponent;

import android.os.Bundle;

import com.facebook.react.ReactPackage;

import org.unimodules.core.interfaces.Package;

import java.util.List;

import host.exp.exponent.experience.DetachActivity;
import host.exp.exponent.generated.DetachBuildConstants;

public class MainActivity extends DetachActivity {

  @Override
  public String publishedUrl() {
    return "exp://exp.host/@flodox/voice-keep";
  }

  @Override
  public String developmentUrl() {
    return DetachBuildConstants.DEVELOPMENT_URL;
  }

  @Override
  public List<ReactPackage> reactPackages() {
    return ((MainApplication) getApplication()).getPackages();
  }

  @Override
  public List<Package> expoPackages() {
    return ((MainApplication) getApplication()).getExpoPackages();
  }

  @Override
  public boolean isDebug() {
    return BuildConfig.DEBUG;
  }

  @Override
  public Bundle initialProps(Bundle expBundle) {
    // Add extra initialProps here
    return expBundle;
  }
}

ShareApplication.java:

// your package you defined in ShareActivity
package host.exp.exponent.share;
// import build config
//import com.sample1.BuildConfig;

import com.alinz.parkerdan.shareextension.SharePackage;

import android.app.Application;

import com.facebook.react.shell.MainReactPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactPackage;

import java.util.Arrays;
import java.util.List;

public class ShareApplication extends Application implements ReactApplication {
 private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
   @Override
   public boolean getUseDeveloperSupport() {
       return false;
     //return BuildConfig.DEBUG;

   }

   @Override
   protected List<ReactPackage> getPackages() {
     return Arrays.<ReactPackage>asList(
         new SharePackage()
     );
   }
 };

 @Override
 public ReactNativeHost getReactNativeHost() {
     return mReactNativeHost;
 }
}

ShareActivity.java:

// define your share project, if your main project is com.sample1, then com.sample1.share makes sense....
package host.exp.exponent.share;

// import ReactActivity
import com.facebook.react.ReactActivity;

public class ShareActivity extends ReactActivity {
    @Override
    protected String getMainComponentName() {
      // this is the name AppRegistry will use to launch the Share View
        return "MyShareEx";
    }
}

AndroidManifext.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
  package="host.exp.exponent"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">

  <permission
    android:name="com.florianwolf.voicekeep.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>

  <!-- These are required permissions to make the app run -->
  <uses-permission android:name="com.florianwolf.voicekeep.permission.C2D_MESSAGE" />
  <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />

  <!-- ADD PERMISSIONS HERE -->
  <!-- BEGIN OPTIONAL PERMISSIONS -->
  <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
  <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-permission android:name="android.permission.USE_FINGERPRINT" />
  <uses-permission android:name="android.permission.VIBRATE" />
  <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

  <!-- These require runtime permissions on M -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.READ_CONTACTS" />
  <uses-permission android:name="android.permission.READ_CALENDAR" />
  <uses-permission android:name="android.permission.WRITE_CALENDAR" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_SETTINGS" />
  <!-- END OPTIONAL PERMISSIONS -->

  <!-- ADD TEST PERMISSIONS HERE -->

  <uses-feature android:glEsVersion="0x00020000" android:required="false" />
  <uses-feature android:name="android.software.leanback" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />

  <application
    android:name=".MainApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:usesCleartextTraffic="true">

    <activity
      android:name=".LauncherActivity"
      android:exported="true"
      android:launchMode="singleTask"
      android:theme="@android:style/Theme.Translucent.NoTitleBar">
    </activity>

    <activity
      android:name=".experience.ExperienceActivity"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
      android:theme="@style/Theme.Exponent.Light"
      android:windowSoftInputMode="adjustResize">
    </activity>

    <activity
      android:name=".MainActivity"
      android:launchMode="singleTask"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
      android:theme="@style/Theme.Exponent.Splash"
      android:windowSoftInputMode="adjustResize">

      <intent-filter>
        <data android:scheme="myapp"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <!-- ADD DETACH APP SPECIFIC INTENT FILTERS -->

        <!-- react-native-file-share-intent;  android:documentLaunchMode="never" was added manually too underneath android:windowSoftInputMode="adjustResize". 
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="audio/*" />
        </intent-filter>
        -->
    </activity>

    <activity
      android:name=".experience.HomeActivity"
      android:label="@string/app_name"
      android:launchMode="singleTask"
      android:screenOrientation="portrait"
      android:theme="@style/Theme.Exponent.Light">
    </activity>

    <activity
      android:name=".experience.TvActivity"
      android:label="@string/app_name"
      android:theme="@style/Theme.Exponent.Light"
      android:screenOrientation="landscape">
     <intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
     </intent-filter>
   </activity>

    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>

    <!-- react-native-share-extention start -->
    <activity
        android:noHistory="true"
        android:name=".share.ShareActivity"
        android:configChanges="orientation"
        android:label="@string/title_activity_share"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.Share.Transparent" >
      <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/*" />
      </intent-filter>
    </activity>
    <!-- react-native-share-extention end -->

    <!-- WHEN_PREPARING_SHELL_REMOVE_FROM_HERE -->
    <!-- ADD DEV SETTINGS HERE -->
    <!-- BEGIN_SDK_36 -->
    <activity android:name="abi36_0_0.com.facebook.react.devsupport.DevSettingsActivity"/>
    <!-- END_SDK_36 -->
    <!-- BEGIN_SDK_35 -->
    <activity android:name="abi35_0_0.com.facebook.react.devsupport.DevSettingsActivity"/>
    <!-- END_SDK_35 -->
    <!-- BEGIN_SDK_34 -->
    <activity android:name="abi34_0_0.com.facebook.react.devsupport.DevSettingsActivity"/>
    <!-- END_SDK_34 -->
    <!-- BEGIN_SDK_33 -->
    <activity android:name="abi33_0_0.com.facebook.react.devsupport.DevSettingsActivity"/>
    <!-- END_SDK_33 -->
    <!-- WHEN_PREPARING_SHELL_REMOVE_TO_HERE -->

    <activity
        android:name="net.openid.appauth.RedirectUriReceiverActivity"
        tools:node="replace">
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="com.florianwolf.voicekeep" android:path="oauthredirect"/>
      </intent-filter>
    </activity>

    <!-- START OF STRIPE SCHEMES -->
    <activity
        android:exported="true"
        android:launchMode="singleTask"
        android:name="expo.modules.payments.stripe.RedirectUriReceiver"
        android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="expo.modules.payments.stripe.4dbab755-b3c0-49b2-8789-20bdd90a1704" />
        </intent-filter>
    </activity>
    <!-- Versioned Activity for Stripe -->
    <!-- BEGIN_SDK_36 -->
    <activity
      android:exported="true"
      android:launchMode="singleTask"
      android:name="abi36_0_0.expo.modules.payments.stripe.RedirectUriReceiver"
      android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="abi36_0_0.expo.modules.payments.stripe" />
      </intent-filter>
    </activity>
    <!-- END_SDK_36 -->
        <!-- BEGIN_SDK_35 -->
        <activity
            android:exported="true"
            android:launchMode="singleTask"
            android:name="abi35_0_0.expo.modules.payments.stripe.RedirectUriReceiver"
            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="abi35_0_0.expo.modules.payments.stripe" />
            </intent-filter>
        </activity>
        <!-- END_SDK_35 -->
    <!-- BEGIN_SDK_34 -->
    <activity
      android:exported="true"
      android:launchMode="singleTask"
      android:name="abi34_0_0.expo.modules.payments.stripe.RedirectUriReceiver"
      android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />
          <data android:scheme="abi34_0_0.expo.modules.payments.stripe" />
      </intent-filter>
    </activity>
    <!-- END_SDK_34 -->
    <!-- BEGIN_SDK_33 -->
    <activity
      android:exported="true"
      android:launchMode="singleTask"
      android:name="abi33_0_0.expo.modules.payments.stripe.RedirectUriReceiver"
      android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />
          <data android:scheme="abi33_0_0.expo.modules.payments.stripe" />
      </intent-filter>
    </activity>
    <!-- END_SDK_33 -->
    <!-- END OF STRIPE SCHEMES -->

    <activity
      android:name=".experience.ErrorActivity"
      android:theme="@style/Theme.Exponent.Dark"
      android:screenOrientation="portrait">
    </activity>

    <activity
      android:name=".experience.InfoActivity"
      android:screenOrientation="portrait"
      android:theme="@style/Theme.Exponent.Light">
    </activity>

    <activity
      android:name="com.facebook.FacebookActivity"
      android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
      android:label="@string/app_name"
      android:theme="@android:style/Theme.Translucent.NoTitleBar"
      tools:replace="android:theme" />

    <activity
      android:name="com.facebook.ads.InterstitialAdActivity"
      android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
      android:label="@string/app_name"
      android:theme="@android:style/Theme.Translucent.NoTitleBar" />

    <service
      android:name=".ExponentIntentService"
      android:exported="false" />

    <!-- Analytics -->
    <receiver
      android:name="host.exp.exponent.referrer.InstallReferrerReceiver"
      android:exported="true">
      <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
      </intent-filter>
    </receiver>

    <!--
    This crashes: https://code.google.com/p/analytics-issues/issues/detail?id=667
    TODO: turn it back on when it's fixed
    <service
      android:name="com.google.android.gms.analytics.CampaignTrackingService"
      android:enabled="true"
      android:exported="false" />-->

    <receiver android:name="com.google.android.gms.analytics.AnalyticsReceiver"
              android:enabled="true">
      <intent-filter>
        <action android:name="com.google.android.gms.analytics.ANALYTICS_DISPATCH" />
      </intent-filter>
    </receiver>

    <service android:name="com.google.android.gms.analytics.AnalyticsService"
             android:enabled="true"
             android:exported="false"/>

    <!-- GCM -->
    <receiver
      android:name="com.google.android.gms.gcm.GcmReceiver"
      android:exported="true"
      android:permission="com.google.android.c2dm.permission.SEND">
      <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>

        <category android:name="com.florianwolf.voicekeep"/>
      </intent-filter>
    </receiver>

    <service
      android:name=".gcm.ExponentGcmListenerService"
      android:exported="false">
      <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
      </intent-filter>
    </service>
    <service
      android:name=".gcm.ExponentInstanceIDListenerService"
      android:exported="false">
      <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID"/>
      </intent-filter>
    </service>
    <service
      android:name=".gcm.GcmRegistrationIntentService"
      android:exported="false">
    </service>

    <!-- FCM -->
    <service
      android:name=".fcm.ExpoFcmMessagingService">
      <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
      </intent-filter>
    </service>
    <meta-data
      android:name="com.google.firebase.messaging.default_notification_icon"
      android:resource="@drawable/shell_notification_icon" />
    <meta-data
      android:name="com.google.firebase.messaging.default_notification_color"
      android:resource="@color/colorAccent" />
    <service
      android:name=".fcm.FcmRegistrationIntentService"
      android:exported="false">
    </service>

    <!-- ImagePicker native module -->
    <activity
      android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
      android:theme="@style/Base.Theme.AppCompat">
    </activity>

    <!-- ADD FABRIC CONFIG HERE -->
    <!-- BEGIN FABRIC CONFIG -->
    <meta-data
      android:name="io.fabric.ApiKey"
      android:value="a25fafe9f9edee11a9882b32e0cd7a26df6e2c42"/>
    <!-- END FABRIC CONFIG -->

    <!-- ADD GOOGLE MAPS CONFIG HERE -->
    <!-- BEGIN GOOGLE MAPS CONFIG -->
    <meta-data
      android:name="com.google.android.geo.API_KEY"
      android:value="AIzaSyDh7eDB9snEFSYtf-k0gfxA45HFoR0L--I"/>
    <!-- END GOOGLE MAPS CONFIG -->

    <!-- ADD GOOGLE MOBILE ADS CONFIG HERE -->
    <!-- BEGIN GOOGLE MOBILE ADS CONFIG -->
    <meta-data
      android:name="com.google.android.gms.ads.APPLICATION_ID"
      android:value="ca-app-pub-3940256099942544~3347511713"/>
    <meta-data android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT" android:value="true"/>
    <!-- END GOOGLE MOBILE ADS CONFIG -->

    <!-- ADD BRANCH CONFIG HERE -->

    <!-- ADD FACEBOOK APP ID CONFIG HERE -->
    <!-- ADD FACEBOOK APP DISPLAY NAME CONFIG HERE -->
    <!-- Tags below need to be in one line with no whitespace after android:value -->
    <!-- in order for XDL to be able to replace values in them -->
    <meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/>
    <meta-data android:name="com.facebook.sdk.AutoInitEnabled" android:value="false"/>
    <meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="false"/>

    <meta-data android:name="standaloneStripeScheme" android:value="4dbab755-b3c0-49b2-8789-20bdd90a1704" />
  </application>

</manifest>

Folder structure: image

Index.js: The problem might be related to the index.js, which was not automatically created for me after ejecting from Expo, Thus I created my own index.js in the root folder where App,js is located and inserted the following, exactly as stated in the installation instructions (note that prior to the installation of this module this index.js did not exist and the app ran fine):

//index.android.js
import React from 'react'
import { AppRegistry } from 'react-native'

import App from './app.android'
import Share from './share.android'

AppRegistry.registerComponent('VoiceKeep', () => App)
AppRegistry.registerComponent('MyShareEx', () => Share) // TODO: Replace MyShareEx with my extension name
ajith-ab commented 4 years ago

i ve used this package with all new features with react native greater than 0.60 support react-native-receive-sharing-intent