安卓学习笔记---使用浏览器打开app指定协议(Url Scheme)

首先要吐槽一下,这个问题已经困扰好几天了!自己没做过这样的需求,在网上查找,使用Url Scheme协议实现浏览器跳转app指定页面,网上的例子很多,但是都比较简单,例子也很简单,但是放在项目里面就出现了各种问题,因为只是单纯的一个例子,没有考虑各种情况和问题,后来终于看到了一篇文章,写的算是比较详细的了,感兴趣的可以看一看,我看到这位博主写的文章确实很不错:

博客地址:

Android 外部唤起应用跳转指定页面

https://www.jianshu.com/p/1439c8bbc34b

实现的基本需求如下:

在微信里面打开app的指定页面,考虑到使用Url Scheme,微信好像已经禁止了,但是通过浏览器可以实现,最终是在微信里面让用户通过打开浏览器,使用Url Schme实现在浏览器中打开app指定页面,通过传递不同的参数实现跳转不同的页面

启动页A 主页面B 跳转页面C

我实现的是在主页面B接收跳转页面的参数,从而进行跳转页面C,因为我还有一个启动页A,基本操作是这样的

1.在Manifest.xml中

<activity
    android:name=".SplachActivity"
    android:screenOrientation="portrait">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    intent-filter>
activity>
<activity
    android:name=".MainActivity"
    android:screenOrientation="portrait"
    android:launchMode="singleTask"
    >
    
    <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="自己定义"
            android:host="自己定义"
            />
        
    intent-filter>
activity>
Url Scheme协议的定义以及使用可以自己去搜索使用的方式,就不在说了,网上说的已经有很多了,这里要注意的是启动页是SplachActivity,但是接收浏览器参数跳转是在MainActivity,我看到网上大部分写的例子都是启动和接收参数都是在一个Activity里面,同时还要注意在MainActivity里面设置的一个参数android:launchMode="singleTask" 这个模式是保证在整个应用中只有这一个MainActivity,设置了这个模式,才发现后面遇到的都是坑!


在进行第二步操作之前,希望还是先阅读以下这篇文章,如果没看到这篇文章,估计遇到的坑还没有填上

博客地址:

当Activity的launchMode设为singleTask的时候,你要注意了!

http://blog.csdn.net/caiwenfeng_for_23/article/details/46918743

感谢两位博主的文章,也是看到了他们写的文章之后自己才有了思路,解决了问题!弄的自己都头疼了!
接下来就是第二步
2.在MainActivity接收浏览器的指定跳转页面

跳转方法
//根据拦截的url跳转页面
private void startIntent(Intent intentUrl)
{
    ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); activityManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME);
    //在浏览器获取到需要制定打开app的某个页面
    if (intentUrl.getScheme() != null) {
        LoggerUtil.i("Alex", "mIntent.getScheme()-->" + intentUrl.getScheme().toString());
        String action = intentUrl.getAction();
        if (Intent.ACTION_VIEW.equals(action)) {
            Uri uri = intentUrl.getData();
            Log.i("Alex", "uri--:" + uri.toString());
            if (uri != null) {
                String host = uri.getHost();
                String dataString = intentUrl.getDataString();
                String bookId = uri.getQueryParameter("bookId");
                String path = uri.getPath();
                String queryString = uri.getQuery();
                LoggerUtil.i("Alex", "host:" + host);
                LoggerUtil.i("Alex", "dataString:" + dataString);
                LoggerUtil.i("Alex", "id:" + bookId);
                LoggerUtil.i("Alex", "path:" + path);
                LoggerUtil.i("Alex", "queryString:" + queryString);
                
                if(path.contains("records_list.jhtml"))
                {
                    rb1.setChecked(true);
                    Intent resultExercise=new Intent(MainActivity.this,HomeExerciseActivity.class);
                    startNewActivity(resultExercise);
                }
                
                else if(path.contains("task.jhtml"))
                {
                    rb1.setChecked(true);
                    Intent resultTask=new Intent(MainActivity.this,HomeTaskActivity.class);
                    startNewActivity(resultTask);

                }
               
                else if(path.contains("score_list.jhtml"))
                {
                    rb4.setChecked(true);
                    Intent resultCourseDetails=new Intent(MainActivity.this,CourseDetailsActivity.class);
                    resultCourseDetails.putExtra("bookId", Integer.parseInt(bookId));
                    startNewActivity(resultCourseDetails);
                }
            }
        }
    }
}
private void startNewActivity(Intent resultIntent)
{
    if (ViewUtils.isLaunchedActivity(this, MainActivity.class)) {
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(resultIntent);
        LoggerUtil.i("Alex","创建new task-->"+getTaskId());
    } else {
        TaskStackBuilder.create(this)
                .addParentStack(resultIntent.getComponent())
                .addNextIntent(resultIntent)
                .startActivities();
        LoggerUtil.i("Alex","当前未打开,重新打开-->"+getTaskId());
    }
}

在MainActivity的onCreate()和onNewIntnet()方法中加入该方法

在onCreate()方法中加入 startIntent(getIntent());
在onNewIntent()方法中也加入
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    LoggerUtil.i("Alex","onNewIntent启动");
    startIntent(intent);
}

注意:

第一.如果你在上面看到了我说的当Activity的launchMode设为singleTask的时候,你要注意了!这篇博客,你就明白了为什么要在onCreate和onNewIntent方法里面都要加入该方法

第二.startIntent(getIntent())该方法传入一个Intent intent参数,不可少!在onCreate和onIntnet里面都要传入Intent参数,这个问题在上面的博客中就能看到,当初因为粗心就没有传入,导致数据一直不是最新的,还是旧的,就是这个原因!

3.在你要跳转的页面C,在Manifest.xml可以设置

<activity
    android:name=".HomeExerciseActivity"
    android:screenOrientation="portrait"
    android:launchMode="singleTop"
    >
android:launchMode="singleTop" 是为了避免当你要打开的页面已经打开,再次打开的时候不需要在栈里面创建一个新的了,

感觉网上说的都挺简单的,但是实际做的时候需要考虑的问题还挺多的,自己看到的说的详细的也比较少,走了不少弯路,困扰了好几天,现在记录一下,以后遇到这样的问题也好知道该怎么办了。再次感谢两位博主写的,基本把自己的问题解决了。


你可能感兴趣的:(工具类的封装(手机号验证,屏幕唤醒,身份证号等其他))