Android 多个域启动相同的应用程序链接 activity
Android App Links with multiple domains launching same activity
这是我的 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 应用程序链接,
- subdomain1.domain.ext
- 子域2.subdomain1.domain.ext
我已经将 assetlinks.json 文件放在
subdomain1.domain.ext/.well-known/assetlinks.json
subdomain2.subdomain1.domain.ext/.well-known/assetlinks.json
但是在使用 Android Studio 安装应用程序时,
我 在 Apache 服务器的 访问日志.[=23 中没有看到任何对任何文件的命中 =]
请注意,我使用的是发布版本变体,它使用用于在 assetlinks.json 中生成 SHA256 指纹的相同密钥库文件。
当我使用 link 进行测试时,例如
https://subdomain1.domain.ext/path1/subpath1/
https://subdomain2.subdomain1.domain.ext/path2
只有下一个启动应用程序,前一个只是在浏览器中打开。
所以看起来最后一行代码(第二个主机)是为app link.
设置的
Qn 1。如何在具有相同 activity 的不同主机上 打开两个 paths/links?就我而言,我怎样才能让第一个 link 也打开应用程序?
Qn 2。我想 限制在应用程序 link 中打开一些 ,我尝试将此正则表达式作为路径模式,但它没有用。我知道它是一个 glob,有什么办法可以做到吗?
android:pathPattern="^(?!foo|bar)..*$"
排除 link 以 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
我阅读了关于此的其他 Whosebug 帖子:
- How can I perform a negative match in Android intent filter?
- Exclude few Urls from deeplinking
但是我没有任何查询参数。我的情况与
中描述的情况非常相似
Qn 3。 强制性 对于 activity 这样的应用程序 links(网络 link 启动应用程序)的意图过滤器定义包含 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;
}
}
pathPattern
不支持完整的正则表达式功能。它只支持“*”和“.*”。就是这样。
参见 https://developer.android.com/guide/topics/manifest/data-element.html
中 pathPattern
的描述
The pathPattern
attribute specifies a complete path that is matched
against the complete path in the Intent
object, but it can contain the
following wildcards:
- An asterisk ('*') matches a sequence of 0 to many occurrences of the immediately preceding character.
- A period followed by an asterisk (".*") matches any sequence of 0 to many characters.
另见 https://developer.android.com/reference/android/os/PatternMatcher.html#PATTERN_SIMPLE_GLOB
对于给定的 <activity>
,您可以拥有任意数量的 <intent-filter>
。由于您不能使用正则表达式来描述您想要的不同 URL,只需为每个 URL.
创建一个单独的 <intent-filter>
描述
在尝试一些代码更改时我意识到
对于 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,可以链接任何 activity,而不仅仅是 MAIN/LAUNCHER。
应用程序链接代码不需要 action=MAIN 和 category=LAUNCHER,
action=VIEW 连同 category=DEFAULT 和 BROWSABLE 是必需且足够的。
因此,不同的 domains/subdomains 可以启动不同的活动,只要 default 和 browsable 与 action=VIEW
一起定义
这是我的 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 应用程序链接,
- subdomain1.domain.ext
- 子域2.subdomain1.domain.ext
我已经将 assetlinks.json 文件放在
subdomain1.domain.ext/.well-known/assetlinks.json
subdomain2.subdomain1.domain.ext/.well-known/assetlinks.json
但是在使用 Android Studio 安装应用程序时, 我 在 Apache 服务器的 访问日志.[=23 中没有看到任何对任何文件的命中 =]
请注意,我使用的是发布版本变体,它使用用于在 assetlinks.json 中生成 SHA256 指纹的相同密钥库文件。
当我使用 link 进行测试时,例如
https://subdomain1.domain.ext/path1/subpath1/
https://subdomain2.subdomain1.domain.ext/path2
只有下一个启动应用程序,前一个只是在浏览器中打开。 所以看起来最后一行代码(第二个主机)是为app link.
设置的Qn 1。如何在具有相同 activity 的不同主机上 打开两个 paths/links?就我而言,我怎样才能让第一个 link 也打开应用程序?
Qn 2。我想 限制在应用程序 link 中打开一些 ,我尝试将此正则表达式作为路径模式,但它没有用。我知道它是一个 glob,有什么办法可以做到吗?
android:pathPattern="^(?!foo|bar)..*$"
排除 link 以 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
我阅读了关于此的其他 Whosebug 帖子:
- How can I perform a negative match in Android intent filter?
- Exclude few Urls from deeplinking
但是我没有任何查询参数。我的情况与
Qn 3。 强制性 对于 activity 这样的应用程序 links(网络 link 启动应用程序)的意图过滤器定义包含 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;
}
}
pathPattern
不支持完整的正则表达式功能。它只支持“*”和“.*”。就是这样。
参见 https://developer.android.com/guide/topics/manifest/data-element.html
中pathPattern
的描述
The
pathPattern
attribute specifies a complete path that is matched against the complete path in theIntent
object, but it can contain the following wildcards:
- An asterisk ('*') matches a sequence of 0 to many occurrences of the immediately preceding character.
- A period followed by an asterisk (".*") matches any sequence of 0 to many characters.
另见 https://developer.android.com/reference/android/os/PatternMatcher.html#PATTERN_SIMPLE_GLOB
对于给定的 <activity>
,您可以拥有任意数量的 <intent-filter>
。由于您不能使用正则表达式来描述您想要的不同 URL,只需为每个 URL.
<intent-filter>
描述
在尝试一些代码更改时我意识到
对于 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,可以链接任何 activity,而不仅仅是 MAIN/LAUNCHER。
应用程序链接代码不需要 action=MAIN 和 category=LAUNCHER, action=VIEW 连同 category=DEFAULT 和 BROWSABLE 是必需且足够的。
因此,不同的 domains/subdomains 可以启动不同的活动,只要 default 和 browsable 与 action=VIEW
一起定义