Android App链接多个域启动相同的活动

时间:2017-08-25 11:40:47

标签: android android-intent android-manifest intentfilter applinks

这是我的AndroidManifest.xml文件

<activity
    android:name=".activity.LaunchActivity"
    android:autoVerify="true"
    android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
    android:label="@string/app_name"
    android:noHistory="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <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="subdomain1.domain.ext"
            android:path="/path1/subpath1/.*"
            android:scheme="https" />
    </intent-filter>
    <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="subdomain1.domain.ext"
            android:pathPattern="/path2/subpath2/..*"
            android:scheme="https" />
    </intent-filter>
    <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="subdomain2.subdomain1.domain.ext"
            android:pathPattern="^..*"
            android:scheme="https" />
    </intent-filter>
</activity>
<activity
    android:name=".activity.LoginActivity"
    android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
    android:label="@string/app_name" />
<activity
    android:name=".activity.MainActivity"
    android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
    android:label="@string/app_name" />

我想为2个域使用Android App Links,

  1. subdomain1.domain.ext
  2. subdomain2.subdomain1.domain.ext
  3. 我已经将assetlinks.json文件放在了

    subdomain1.domain.ext/.well-known/assetlinks.json
    
    subdomain2.subdomain1.domain.ext/.well-known/assetlinks.json
    

    但是在使用Android Studio安装应用时, 我没有看到任何点击到apache服务器 访问日志 中的任一文件。

    请注意,我使用的是发布版本变体,它使用相同的密钥库文件,用于在assetlinks.json中生成SHA256指纹。

    当我使用

    等链接进行测试时
    https://subdomain1.domain.ext/path1/subpath1/
    
    https://subdomain2.subdomain1.domain.ext/path2
    

    只有较低的一个启动应用程序,前一个只是在浏览器中打开。 所以似乎为app链接设置了最后一行代码(第二个主机)。

    Qn 1 。如何 在具有相同活动的不同主机上打开两个路径/链接 ?在我的情况下,如何让第一个链接也打开应用程序?

    Qn 2 。我想限制在应用中打开一些链接,我试过这个正则表达式作为路径模式,它没有用。我知道它是一个水母,有什么可以做到的吗?

    android:pathPattern="^(?!foo|bar)..*$"
    

    排除以foo和bar开头但允许其他人的链接路径。

    我想打开

    example.com in web browser
    example.com/test in web browser
    example.com/test/temp in web browser
    example.com/{anything else} in the app
    

    我阅读了关于此的其他stackoverflow帖子:

    但我没有任何查询参数。我的情况与Android Deep linking omit certain url

    中描述的情况非常相似

    Qn 3 强制性对于定义此类应用程序链接(Web链接启动应用程序)的intent过滤器的活动是否包含action = MAIN和category = LAUNCHER?

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

    期待一些帮助。 Android团队不允许排除路径似乎很愚蠢,应该从使用简单NOT子句的Apple服务器端文件中学习。

    如果有帮助, 这是LaunchActivity的onCreate()方法中的java代码

    public class LaunchActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.splashscreen);
            Intent intent = getIntent();
            if (intent != null) {
                Uri target = intent.getData();
                if (target != null && target.isHierarchical()) {
                    String goal = intent.getDataString();
                    List<String> params = target.getPathSegments();
                    Log.d(TAG, "app uri : " + goal);
                    Log.d(TAG, "app link : " + target.toString());
                    Log.d(TAG, "path segments : " + params);
                    if (target.toString().startsWith(MON_DOM)) {
                        if (searchString(AppLinksUtil.TARGET_URLS, target.toString())) {
                            Log.d(TAG, "Open TARGET Link in APP");
                        } else {
                            Log.d(TAG, "Open Excluded Link in Browser");
                            openLinkInChrome(LaunchActivity.this, goal);
                            finish();
                        }
                    } else if (target.toString().startsWith(ENQ_DOM)) {
                        Log.d(TAG, "Exclude List : " + AppLinksUtil.ENQ_EXCLUDE_URLS);
                        if (searchString(AppLinksUtil.EXCLUDE_URLS, target.toString())) {
                            Log.d(TAG, "Open Excluded Link in Browser");
                            openLinkInChrome(LaunchActivity.this, goal);
                            finish();
                        } else {
                            Log.d(TAG, "Open Link in APP");
                        }
                    }
                }
            } else {
                Log.d(TAG, "no intent");
            }
            appFlow();
        }
        ...
        public void openLinkInChrome(final Activity activity, String link) {
            Log.d(TAG, "Opening " + link + " in web browser");
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setPackage("com.android.chrome");
            try {
                activity.startActivity(intent);
            } catch (ActivityNotFoundException ex) {
                intent.setPackage(null);
                activity.startActivity(intent);
            }
        }
        public static boolean searchString(String[] arr, String targetValue) {
            for (String s : arr) {
                if (targetValue.startsWith(s))
                    return true;
            }
            return false;
        }
    }
    

2 个答案:

答案 0 :(得分:1)

在尝试更改代码时,我意识到了

对于1 ,相同域的子域没有通配符选项,支持多个域,使用正确的pathPatterns一个接一个地列出它们,修复了我面临的问题。

AndroidManifest.xml

<activity android:name="MainActivity">
<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="http" />
    <data android:host="subdomain1.example1.com" />
    <data android:host="subdomain2.example1.com" />
    <data android:host="subdomain3.example2.com" />
    <data android:path="/onlythis" />
    <data android:pathPrefix="/starter" />
    <data android:pathPattern="/prefix.*" />
    <data android:pathPattern="/.*suffix" />
</intent-filter>
</activity>

对于2 ,目前尚无法排除路径,Google必须向Apple学习。

对于3 ,任何活动都可以链接,而不仅仅是MAIN / LAUNCHER。

应用程序链接代码不需要

action = MAIN和category = LAUNCHER, action = VIEW以及category = DEFAULT和BROWSABLE是必需且足够的。

因此,只要默认和可浏览与action = VIEW一起定义,不同的域/子域就可以启动不同的活动

答案 1 :(得分:0)

pathPattern不支持完整的正则表达式功能。它只支持&#34; *&#34;和&#34;。*&#34;。那就是它。

请参阅https://developer.android.com/guide/topics/manifest/data-element.html

pathPattern的说明
  

pathPattern属性指定匹配的完整路径   针对Intent对象中的完整路径,但它可以包含。{   以下通配符:

     
      
  • 星号(&#39; *&#39;)匹配前一个字符的0到多次出现的序列。
  •   
  • 星号后面跟着一个星号(&#34;。*&#34;)匹配任意0到多个字符的序列。
  •   

另见https://developer.android.com/reference/android/os/PatternMatcher.html#PATTERN_SIMPLE_GLOB

对于给定的<intent-filter>,您可以拥有任意数量的<activity><intent-filter>。由于您无法使用正则表达式来描述所需的不同网址,因此只需为每个网址创建单独的{{1}}说明。