微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android 如何打开基于 Chrome 意图的 URI

如何解决Android 如何打开基于 Chrome 意图的 URI

Chrome docs,我了解到可以使用以下 URI 打开应用

intent:  
   HOST/URI-path // Optional host  
   #Intent;  
      package=\[string\];  
      action=\[string\];  
      category=\[string\];  
      component=\[string\];  
      scheme=\[string\];  
   end;

我想知道是否可以从我的应用打开这个 URI。

示例 URI

intent:
    //qr/json/%7B%22u%22%3A%22https%3A%2F%2Fprivacybydesign.foundation%2Fbackend%2Firma%2Fsession%2FvsRjkZF2B2H17sBWmVZe%22%2C%22irmaqr%22%3A%22disclosing%22%7D
    #Intent;
        package=org.irmacard.cardemu;
        scheme=cardemu;
        l.timestamp=1620907855707;
        S.browser_fallback_url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dorg.irmacard.cardemu
    ;end

因为它看起来像一个普通的 URI,所以我想我可以这样打开它:

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("%EXAMPLE_URI%"));
startActivity(intent);

这给了我一个 ActivityNotFoundException。我错过了什么?

引起:android.content.ActivityNotFoundException:没有找到处理意图的活动{ act=android.intent.action.VIEW dat=intent://qr/json/{"u":"https://privacybydesign.基金会/后端/irma/session/vsRjkZF2B2H17sBWmVZe","irmaqr":"disclosure"} pkg=org.irmacard.cardemu(有额外的)}

解决方法

Chrome docs 中描述的“意图:”语法用于从网页启动应用,Chrome 将处理 href 并检索参数以启动应用通过 Android Intent。

您提供的示例 URI 的方案是 intent://,默认情况下不处理。

如果要处理 intent:// URI,则需要 create a deep link

如果您想从您的 Android 应用打开网页,您可以使用 ACTION_VIEW 操作并在 Intent 数据中指定网址。

public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW,webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

// example
// openWebPage("https://privacybydesign.foundation/backend/irma/session/vsRjkZF2B2H17sBWmVZe")

关于Intents and Intent Filters 的更多信息

,

您可以尝试以下几件事:

1.确保您要启动的应用程序实现了正确的意图。

<application android:label="@string/app_name">
...
    <activity android:name=".PleaseStartThisActivity" android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
        </intent-filter>
    </activity>
...
</application>

2.始终使用新意图,切勿重复使用旧意图。

Intent intent = new Intent(android.content.Intent.ACTION_VIEW); //OK.
// Intent intent = getIntent(); //Not OK.

3.把其他一切都做好。

// If package name and activity are known.
intent.setComponent(new ComponentName("org.irmacard.cardemu","org.irmacard.cardemu.PleaseStartThisActivity"));
// Else
// intent = new Intent(android.content.Intent.ACTION_GET_CONTENT);
// intent.setDataAndType(Uri.parse("file://" + filePath),"text/plain");

4.设置或添加标志可能会有所帮助

intent.setFlags(
    android.content.Intent.FLAG_ACTIVITY_FORWARD_RESULT |
    android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP |
    android.content.Intent.FLAG_INCLUDE_STOPPED_PACKAGES |
    android.content.Intent.FLAG_RECEIVER_FOREGROUND |
    android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION |
    android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
    android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION |
    android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION |
    android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

5.现在您可以安全地开始活动了。

startActivity(intent);
// Or this:
// startActivity(android.content.Intent.createChooser(intent,null));

编辑

* intent.getDataString() - To get intent data (You may have to parse it to get the package name).
* getPackageManager().queryIntentActivities() - To check available activities for that package like the following example:
private final String getActivity(final String packageName,final Intent intent,final Bundle bundle,final String mimeType) {
        final String activity;
        int activityLen = 0;
        final int packageLen = packageName.length();
        
        if(bundle != null && (activity = bundle.getString("activity")) != null) {
            activityLen = activity.length();
        } else {
            activity = null;
        }

        final List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,PackageManager.GET_RESOLVED_FILTER);
        
        for(ResolveInfo ri : list) {        
            final IntentFilter filter = ri.filter;  

            final String activityName = ri.activityInfo.name;
            //Make sure the activity is valid and exist for the package.
            //Tolerate with case insensitive
            if(activity != null && activity.regionMatches(true,activityName,activityLen)
               && packageName.regionMatches(true,ri.activityInfo.packageName,packageLen)) {
                return activityName;
            } else if(filter == null) {
                Toast.makeText(this,"ERROR: No available ACTIONS to handle this file",1).show();
                return null;
                //Auto search only if user hasn't specified the activity,else return null. Tolerate with case insensitive
            } else if(activity == null && filter.hasAction(intent.getAction()) && filter.hasDataType(mimeType)) {
                if(ri.activityInfo.packageName.regionMatches(true,packageName,packageLen)) {
                    return ri.activityInfo.name;
                }
            } // Else keep validating next activities
        }
        
        if(activity == null) {
            Toast.makeText(this,"ERROR: No available ACTIVITIES to open this file",1).show();
        } else {
            Toast.makeText(this,"ERROR: No such activity found",1).show();
        }
        return null;
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。