首先要吐槽一下,这个问题已经困扰好几天了!自己没做过这样的需求,在网上查找,使用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的时候,你要注意了!
//根据拦截的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()); } }
@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" 是为了避免当你要打开的页面已经打开,再次打开的时候不需要在栈里面创建一个新的了,
感觉网上说的都挺简单的,但是实际做的时候需要考虑的问题还挺多的,自己看到的说的详细的也比较少,走了不少弯路,困扰了好几天,现在记录一下,以后遇到这样的问题也好知道该怎么办了。再次感谢两位博主写的,基本把自己的问题解决了。