最近项目中有这样一个需求,需要在网页中打开app,并跳转到相对应的界面,一开始还有点困惑,怎么从浏览器的网页中打开app呢?在网上查阅了资料发现实现起来还是比较简单的,特此记录一下:

实现原理

就Android平台而言,URI主要分三个部分:scheme, authority,path, queryString。其中authority又分为host和port。格式如下:
scheme://host:port/path?qureyParameter=queryString
每个属性的含义如下:
scheme:判别启动的App。
host:
port:端口号
path:传值时必须的key
query:获取值的Key和Value
如果只是启动APP而不需要传值的话,一个scheme字段就足够了

本项目中只用到了scheme和query,格式如下:

ivluowei://?travelNoteId="+travelNoteId+"&type=type

网页端实现

function android(ua,travelNoteId){
            if(ua.match(/MicroMessenger/i) == "micromessenger"){
                ShowDiv("MyDiv");
            }else{
                window.location.href = "ivluowei://?travelNoteId="+travelNoteId+"&type=2";
                window.setTimeout(function(){

                    window.location.href = "<%=basePath%>/downloadApp.jsp";

                },3000)
            }
        };

Android端实现:

首先需要在Mainifest文件里面对要启动的Activity添加一个过滤器。

<activity
   android:name=".activity.LoadingActivity"
   android:configChanges="keyboardHidden|orientation|screenSize"
   android:screenOrientation="portrait"
   android:windowSoftInputMode="stateHidden|adjustPan">
   <intent-filter>
      <action android:name="android.intent.action.MAIN"/>
      <category
            android:name="android.intent.category.LAUNCHER"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateHidden|adjustPan"/>
    </intent-filter>

    <!--网页启动Activity需要的过滤器-->
    <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="ivluowei"/>
    </intent-filter>
</activity>

mainifest文件配置好之后,需要在添加对应过滤器的activity里接收数据

public class LoadingActivity extends AppCompatActivity {
    private Context mContext;
    private Intent mIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);
        mContext= this;
        mIntent = getIntent();
        if (mIntent.getScheme() != null) {
            Uri uri = mIntent.getData();
            String type = uri.getQueryParameter("type");
            if (type.equals("1")) {
                int specialityId = Integer.parseInt(uri.getQueryParameter("specialityId"));
                Intent it = new Intent(mContext, GoodsActivity.class);
                it.putExtra("specialityId", specialityId);
                context.startActivity(it);
            } else {
                int travelNoteId = Integer.parseInt(uri.getQueryParameter("travelNoteId"));
                Intent it = new Intent(mContext, TravelBrowseActivity.class);
                it.putExtra("travelId", travelNoteId);
                mContext.startActivity(it);
            }
        } else {
            Intent it = new Intent(this, MainActivity.class);
            startActivity(it);
        }
    }
}

通过mIntent.getScheme()是否为null来判断是否从网页启动的,如果getScheme()不为空,则可以通过mIntent.getData()得到Uri对象,从而通过uri.getQueryParameter(“xx”)方法来获取query的value值.
测试中发现, 在微信内置的浏览器里屏蔽了schema协议,我们没法通过这个schema协议在微信浏览器中打开app,因此,我们需要在网页中先判断页面场景是否在微信中,如果在微信中,就要提示用户在其他的浏览器中打开,这样就可以了,经测试, qq和其他浏览器都可以,除了微信.