在 pathPrefixes /abc 和 /abc/def 上打开不同的 Activity

Open different Activities on pathPrefixes /abc and /abc/def

我有两个 url。例如:

  1. http://host.com/abc/12345
  2. http://host.com/abc/def/12345

其中 12345 - 是某个 ID。

我想为这些 url 开展不同的活动。

目前我在AndroidManifest.xml中有下一个实现:

<activity
    android:name=".ui.activities.Activity1"
    android:windowSoftInputMode="adjustResize">
    <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" android:host="host.com" android:pathPrefix="/abc"/>
    </intent-filter>
</activity>
<activity
    android:name=".ui.activities.Activity2"
    android:windowSoftInputMode="adjustResize">
    <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" android:host="host.com" android:pathPrefix="/abc/def"/>
    </intent-filter>
</activity>

第一个 url 效果很好:当我点击它时 android 建议我使用 一些其他应用程序 或我的 Activity1.

但是当我点击第二个 url 时出现问题:android 建议我使用 一些其他应用程序 或我的 Activity1 或我的 Activity2.

所以我的问题是:有没有办法从建议列表中排除 Activity1

我尝试使用 pathPattern 并尝试使用谷歌搜索如何从 IntentFilter 中排除 url 但我失败了。

我认为你应该这样做:

 <activity android:windowSoftInputMode="adjustResize"     
           android:name=".ui.activities.Activity1" >
        <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" android:host="host.com" 
                  android:pathPattern="http://host.com/abc/12345" 
                  android:pathPrefix="/abc/12345"/>
        </intent-filter>
    </activity>
    <activity android:windowSoftInputMode="adjustResize"  android:name=".ui.activities.Activity2">
        <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" android:host="host.com"  
                  android:pathPattern="http://host.com/abc/def/12345"  
                  android:pathPrefix="/abc/def/12345"/>
        </intent-filter>
    </activity>

希望对您有所帮助...

我想不出更好的方法,但这行得通:

<activity
    android:name=".ui.activities.Activity1"
    android:windowSoftInputMode="adjustResize">
    <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="test.com"
            android:pathPattern="/abc/1.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/2.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/3.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/4.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/5.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/6.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/7.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/8.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/9.*"
            android:scheme="http"/>
        <data
            android:host="host.com"
            android:pathPattern="/abc/0.*"
            android:scheme="http"/>
    </intent-filter>
</activity>
<activity
    android:name=".ui.activities.Activity2"
    android:windowSoftInputMode="adjustResize">
    <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="host.com"
            android:pathPattern="/abc/def/.*"
            android:scheme="http"/>
    </intent-filter>
</activity>

由于我没有通过`AndroidManifest.xml'找到优雅的解决方案,所以我决定通过代码实现部分"choosing"逻辑。所以我有:

在清单文件中,我们定义了 UrlActivity,它将响应任何 url,例如“http://host.com/abc/...”,因此它看起来像:

<activity
    android:name=".ui.activities.UrlActivity"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="adjustResize">
    <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" android:host="host.com" android:pathPrefix="/abc"/>
    </intent-filter>
</activity>

然后我们定义专门为UrlActivity调优的接口Component(您可以根据行为选择任何名称)。在简单的情况下,它可以只复制 activity 中的类似方法。例如:

public interface Component {
    void onStart();
    void onStop();
}

然后在您的 UrlActivity 中检索 uri 并选择适当的组件实现。例如:

private Component component;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Uri uri = getIntent().getData();
    List<String> segments = uri.getPathSegments();

    if (segments.contains("def")) {
        component = new Component2(...);
    } else {
        component = new Component1(...);
    }
}

@Override
protected void onStart() {
    super.onStart();
    component.onStart();
}

@Override
protected void onStop() {
    super.onStop();
    component.onStop();
}

与@KamranAhmed 解决方案相比,此解决方案具有优势:可扩展性、减少重复。但它也有一个缺陷:您需要编写更多代码并为该解决方案考虑合适的架构。所以它确实比@KamranAhmed 方法更难,但对我来说它更干燥和灵活。