Android WebView中跳转第三方APP

一、概述

当你的应用中WebView打开一个H5页面,在这个页面中需要可以打开第三方App页面,通用的跳转方式为Scheme协议Intent协议

Scheme格式

客户端自定义的 URL 作为从一个应用调用另一个的基础,遵循 RFC 1808 (Relative Uniform Resource Locators) 标准。这跟我们常见的网页内容 URL 格式一样。

一个普通的 URL 分为几个部分,scheme、host、relativePath、query。

比如:http://www.baidu.com/s?rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709,这个URL中,scheme 为 http,host 为 www.baidu.com,relativePath 为 /s,query 为 rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709。

一个应用中使用的 URL 例子(该 URL 会调起车辆详情页):uumobile://mobile/carDetail?car_id=123456,其中 scheme 为 uumobile,host 为 mobile,relativePath 为 /carDetail,query 为 car_id=123456。

Intent格式  

intent:
HOST/URI-path // Optional host

Intent;

  package=[string];
  action=[string];
  category=[string];
  component=[string];
  scheme=[string];

end;


举个栗子
```java
intent:
   //scan/
   #Intent;
      package=com.sapp.android;
      scheme=fengye;
   end;
即:
  intent://scan/#Intent;scheme= fengye;package=com.sapp.android;end
  intent://platformapi/startapp?appId=20000013&pwdType=ordinaryPassword&_t=1456301771669#Intent;scheme=alipays;package=com.eg.android.AlipayGphone;end

二、在Webview支持Scheme和intent协议

WebViewClientshouldOverrideUrlLoading方法中实现以下代码:

@Override
public boolean shouldOverrideUrlLoading(WebView view, String newurl) {
    try {
    //处理intent协议
      if (newurl.startsWith("intent://")) {
      Intent intent;
        try {
              intent = Intent.parseUri(newurl, Intent.URI_INTENT_SCHEME);
              intent.addCategory("android.intent.category.BROWSABLE");
              intent.setComponent(null);
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
                    intent.setSelector(null);
               }
               List<ResolveInfo> resolves = context.getPackageManager().queryIntentActivities(intent,0);
               if(resolves.size()>0){
                    startActivityIfNeeded(intent, -1);
               }
               return true;
          } catch (URISyntaxException e) {
               e.printStackTrace();
          }
      }
     // 处理自定义scheme协议
        if (!newurl.startsWith("http")) {
            MyLogUtil.LogI("yxx","处理自定义scheme-->" + newurl);
            try {
               // 以下固定写法
               final Intent intent = new Intent(Intent.ACTION_VIEW,
                        Uri.parse(newurl));
               intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
               startActivity(intent);
            } catch (Exception e) {
               // 防止没有安装的情况
               e.printStackTrace();
               ToastManager.showToast("您所打开的第三方App未安装!");
            }
             return true;
         }
    } catch (Exception e) {
        e.printStackTrace();
    }

        return super.shouldOverrideUrlLoading(view, newurl);
}

三、App中支持第三方App或者浏览器跳转自己App

修改Manifest文件,给想要接收跳转的Activity添加<intent-filter>配置,例如:

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <!--需要添加下面的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:scheme="fengye"/>
        </intent-filter>
    </activity>

然后在MainActivityonCreate方法中获取相关传递数据。例如:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent =getIntent();
        Log.e(TAG, "scheme:" +intent.getScheme());
        Uri uri =intent.getData();
        Log.e(TAG, "scheme: "+uri.getScheme());
        Log.e(TAG, "host: "+uri.getHost());
        Log.e(TAG, "port: "+uri.getPort());
        Log.e(TAG, "path: "+uri.getPath());
        Log.e(TAG, "queryString: "+uri.getQuery());
        Log.e(TAG, "queryParameter: "+uri.getQueryParameter("key"));
    }
}