代码之家  ›  专栏  ›  技术社区  ›  SudoPlz

深度链接启动启动活动,而不是主活动

  •  10
  • SudoPlz  · 技术社区  · 6 年前

    我跟着 this guide - Splash screens the right way 要为我的Android应用程序创建启动屏幕,现在我有2个活动(MainActivity和SplashActivity)

    问题是深层链接丢失现在表现得很好,因为没有启动 MainActivity 他们启动了 SplashActivity .

    我不想要 飞溅活动 除非应用程序启动,否则不会显示。

    我能做什么?

    飞溅活动:

    public class SplashActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
            finish();
        }
    }
    

    主要活动:

    public class MainActivity extends SplashActivity implements OnImagePickerPermissionsCallback {
    
        private PermissionListener listener;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void setPermissionListener(PermissionListener listener)
        {
            this.listener = listener;
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
        {
            if (listener != null)
            {
                listener.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    
    
        @Override
        public View createSplashLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Window window = getWindow();
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(getResources().getColor(R.color.navBarColor));
            }
            LinearLayout view = new LinearLayout(this);
    //        view.setBackgroundColor(getResources().getColor(R.color.catalyst_redbox_background));
            view.setBackgroundResource(R.drawable.launch_screen_radius);
            return view;
        }
    }
    

    清单文件:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    
    <!-- For using react-native-fcm CLOUD MESSAGING-->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.VIBRATE" />
    
    
    <!-- For using react-native-image-picker -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    <!-- For react-native-webview-file-upload-android -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    
    <!-- For using NetInfo -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="24" />
    
    <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:theme="@style/AppTheme"
        >
    
        <!-- The 2 services below are for react-native-fcm cloud messaging -->
        <service android:name="com.evollu.react.fcm.MessagingService" android:enabled="true" android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
        <service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
    
        <!-- The 2 receivers below are for react-native-fcm local notifications-->
        <receiver android:name="com.evollu.react.fcm.FIRLocalMessagingPublisher"/>
        <receiver android:enabled="true" android:exported="true"  android:name="com.evollu.react.fcm.FIRSystemBootEventReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
    
        <activity
            android:name=".SplashActivity"
            android:label="@string/app_name"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustResize"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:screenOrientation="portrait"
            android:launchMode="singleTop"
            >
            <!-- launchMode="singleTop" is for fcm cloud messaging -->
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
            </intent-filter>
    
            <!--
                The intent filter below are for react-native-fcm click_action
                https://github.com/evollu/react-native-fcm#config-for-notification-and-click_action-in-android
            -->
            <intent-filter>
                <action android:name="fcm.ACTION.HELLO" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
    
            <intent-filter>
                <!-- Sets the intent action to view the activity -->
                <action android:name="android.intent.action.VIEW" />
    
                <!-- Allows the deep link to be used without specifying the app name -->
                <category android:name="android.intent.category.DEFAULT" />
    
                <!-- Allows the link to be opened from a web browser -->
                <category android:name="android.intent.category.BROWSABLE" />
    
                <!-- Accepts URIs that begin with "https://www.myExampleDomain.com -->
                <data android:scheme="https" android:host="www.myExampleDomain.com" />
    
                <!-- Accepts URIs that begin with "myExampleDomain:// -->
                <data android:scheme="myExampleDomain"/>
            </intent-filter>
        </activity>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>
    

    编辑:有人指出我正在使用 飞溅活动 . 这是真的,这是以下活动的代码。 这是 react-native-navigation 我用于屏幕导航的库。不确定这是否有帮助,但下面是代码:

    飞溅活动:

    public abstract class SplashActivity extends AppCompatActivity {
        public static boolean isResumed = false;
    
        public static void start(Activity activity) {
            Intent intent = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName());
            if (intent == null) return;
            intent.setAction(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            activity.startActivity(intent);
        }
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setSplashLayout();
            IntentDataHandler.saveIntentData(getIntent());
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            isResumed = true;
    
            if (NavigationApplication.instance.getReactGateway().hasStartedCreatingContext()) {
                if (CompatUtils.isSplashOpenedOverNavigationActivity(this, getIntent())) {
                    finish();
                    return;
                }
                NavigationApplication.instance.getEventEmitter().sendAppLaunchedEvent();
                if (NavigationApplication.instance.clearHostOnActivityDestroy()) {
                    overridePendingTransition(0, 0);
                    finish();
                }
                return;
            }
    
            if (ReactDevPermission.shouldAskPermission()) {
                ReactDevPermission.askPermission(this);
                return;
            }
    
            if (NavigationApplication.instance.isReactContextInitialized()) {
                NavigationApplication.instance.getEventEmitter().sendAppLaunchedEvent();
                return;
            }
    
            // TODO I'm starting to think this entire flow is incorrect and should be done in Application
            NavigationApplication.instance.startReactContextOnceInBackgroundAndExecuteJS();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            isResumed = false;
        }
    
        private void setSplashLayout() {
            final int splashLayout = getSplashLayout();
            if (splashLayout > 0) {
                setContentView(splashLayout);
            } else {
                setContentView(createSplashLayout());
            }
        }
    
        /**
         * @return xml layout res id
         */
        @LayoutRes
        public int getSplashLayout() {
            return 0;
        }
    
        /**
         * @return the layout you would like to show while react's js context loads
         */
        public View createSplashLayout() {
            View view = new View(this);
            view.setBackgroundColor(Color.WHITE);
            return view;
        }
    }
    

    主应用程序。Java语言 公共类MainApplication扩展NavigationApplication实现ReactInstanceHolder{

        @Override
        public boolean clearHostOnActivityDestroy() {
            return false;
        }
    
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
                // only for KITKAT_WATCH and newer versions
                MultiDex.install(this);
            }
        }
    
        @Override
        public boolean isDebug() {
            // Make sure you are using BuildConfig from your own application
            return BuildConfig.DEBUG;
        }
    
        @Override
        public String getJSMainModuleName() {
            return "index";
        }
    
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            // Log.v(TAG, "onConfigChange"+newConfig);
            Intent intent = new Intent("onConfigurationChanged");
            intent.putExtra("newConfig", newConfig);
            this.sendBroadcast(intent);
        }
    
    
        // 2. Override the getJSBundleFile method in order to let
        // the CodePush runtime determine where to get the JS
        // bundle location from on each app start
        @Override
        public String getJSBundleFile() {
            return CodePush.getJSBundleFile();
        }
    
        @NonNull
        @Override
        public List<ReactPackage> createAdditionalReactPackages() {
            return Arrays.<ReactPackage>asList(
                new LinearGradientPackage(),
                new OrientationPackage(),
                new VectorIconsPackage(),
                new KeychainPackage(),
                new BackgroundTimerPackage(),
                new RNI18nPackage(),
                BugsnagReactNative.getPackage(),
                new BlurViewPackage(),
                new PickerViewPackage(),
                new ImagePickerPackage(),
                new RNFetchBlobPackage(),
                new MapsPackage(),
                new FIRMessagingPackage(),
                new RNAmplitudeSDKPackage(MainApplication.this),
                new RNVersionCheckPackage(),
                new RNCardIOPackage(),
                new AndroidWebViewPackage(),
                new WheelPackage()
            );
        }
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            setActivityCallbacks(new ActivityCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    
                }
    
                @Override
                public void onActivityStarted(Activity activity) {
    
                }
    
                @Override
                public void onActivityResumed(Activity activity) {
    
                }
    
                @Override
                public void onActivityPaused(Activity activity) {
    
                }
    
                @Override
                public void onActivityStopped(Activity activity) {
    
                }
    
                @Override
                public void onActivityResult(int requestCode, int resultCode, Intent data) {
    
                }
    
                @Override
                public void onActivityDestroyed(Activity activity) {
    
                }
    //            @Override
    //            public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    //                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    //            }
    
            });
        }
    
        @Override
        public ReactInstanceManager getReactInstanceManager() {
            return getReactNativeHost().getReactInstanceManager();
        }
    }
    

    如有任何提示,将不胜感激, 非常感谢。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Nirav Joshi    6 年前

    你的url应该是 https://example.com 您在Android清单中有如下意图过滤器:

    <activity
        android:name="com.droid.MainActivity"
        android:label="@string/app_name" >
    
        <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:host="example.com"
                android:scheme="https" />
        </intent-filter>
    </activity>
    

    使用 URL映射 编辑器,可通过Android应用程序链接(Android Studio>工具>Android应用程序链接)轻松将URL意图过滤器添加到您的活动中。

        2
  •  2
  •   Mustafa Dualeh    6 年前

    android系统查看第一个标记的清单,其中包含:

       <category android:name="android.intent.category.LAUNCHER" />
    

    将MainActivity设置为使用此标记而不是SplashActivity。

    始终首先启动MainActivity,并在MainActivity onCreate中对意图执行任何检查。

        //replace getStringExtra with whatever you use to identify deeplink.
    Boolean isDeepLink= getIntent().getStringExtra("").startsWith("mydeeplink://");
    
    if(!isDeepLink)
        {
            Intent splashIntent=new Intent(this, SplashActivity.class);
            startActivity(splashIntent);
        }
    
        3
  •  2
  •   SudoPlz    6 年前

    找到导致问题的原因。

    实际上是这行代码 MainApplication.java :

    public boolean clearHostOnActivityDestroy() {
        return false;
    }
    

    当我将该值更改为 真的 ,一切都开始按预期的方式工作。

    这是我的导航库导致的问题: https://github.com/wix/react-native-navigation