Android-应用被作为第三方浏览器打开
前言
微信里的文章页面,可以选择“在浏览器打开”。现在很多应用都内嵌了WebView,那是否可以使自己的应用作为第三方浏览器打开此文章呢? 如图:
微信打开三方浏览器.png
就像图中这样,让自己的应用出现在列表里。 这篇文章就是为了实现这个功能。
项目代码地址:WebViewStudy
正文
实现其实很简单: 在Manifest文件中,给想要接收跳转的Activity添加<intent-filter>配置:
<activity
android:name=".WebViewActivity"
android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/WebViewTheme">
<!--需要添加下面的intent-filter配置-->
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!--使用http,则只能打开http开头的网页-->
<data android:scheme="https" />
</intent-filter>
</activity>
然后在 WebViewActivity 中获取相关传递数据:
public class WebViewActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
getIntentData();
initTitle();
initWebView();
webView.loadUrl(mUrl);
// 处理 作为三方浏览器打开传过来的值
getDataFromBrowser(getIntent());
}
/**
* 使用singleTask启动模式的Activity在系统中只会存在一个实例。
* 如果这个实例已经存在,intent就会通过onNewIntent传递到这个Activity。
* 否则新的Activity实例被创建。
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
getDataFromBrowser(intent);
}
/**
* 作为三方浏览器打开传过来的值
* Scheme: https
* host: www.jianshu.com
* path: /p/1cbaf784c29c
* url = scheme + "://" + host + path;
*/
private void getDataFromBrowser(Intent intent) {
Uri data = intent.getData();
if (data != null) {
try {
String scheme = data.getScheme();
String host = data.getHost();
String path = data.getPath();
String text = "Scheme: " + scheme + "n" + "host: " + host + "n" + "path: " + path;
Log.e("data", text);
String url = scheme + "://" + host + path;
webView.loadUrl(url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
以上是核心代码,有几点需要说明的:
- 1、设置启动模式:
launchMode="singleTask"
- 2、
getDataFromBrowser()
方法会在onCreate
和onNewIntent
方法中调用。
解释:
在实际使用中,有这样的场景:
我们在微信中“通过浏览器”打开自己的应用,然后将自己的应用切到后台。重复上面的操作,会一直创建应用的实例,这样肯定是不好的,为了避免这种情况我们设置启动模式为:launchMode="singleTask"
。
使用singleTask启动模式的Activity在系统中只会存在一个实例。 如果这个实例不存在,新的Activity实例被创建。 如果这个实例已经存在,那么在Activity回退栈中,所有位于该Activity上面的Activity实例都将被销毁掉(销毁过程会调用Activity生命周期回调),这样使得singleTask Activity实例位于栈顶。与此同时,Intent会通过
onNewIntent
传递到这个SingleTask Activity实例。 - <深入讲解Android中Activity launchMode>
这就是为什么要在onNewIntent
中调用的原因,当此Activity已存在时,值会通过onNewIntent
传递过来。
继续拓展
也许大家用知乎
进行过类似的操作,会发现有这样一个效果:
当知乎没有开启时,在其他应用打开知乎后,关闭页面会回到知乎的主页面。正常是不会有出现这样的情况的,我们需要简单设置一下。
1、在主页面设置静态变量,初始化时改变静态变量的值
public class MainActivity extends AppCompatActivity {
// 是否开启了主页,没有开启则会返回主页
public static boolean isLaunch = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
isLaunch = true;
}
@Override
protected void onDestroy() {
super.onDestroy();
isLaunch = false;
}
2、当WebViewActivity
关闭时判断是否打开主页面
/**
* 直接通过三方浏览器打开时,回退到首页
*/
public void handleFinish() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAfterTransition();
} else {
finish();
}
if (!MainActivity.isLaunch) {
MainActivity.start(this);
}
}
结语
其实这相当于Activity隐式跳转,其中点击网页中的电话跳转到手机的拨号盘也是这样的原理,DeepLink也基本是这个逻辑。
设想这样一种情况: 我们通过浏览器拉起自己的应用,不一定要打开WebView,也可以打开原生的页面,只需要传过来的数据里有此页面想要的数据即可。其实很多应用都这样做了。
End
- 下载体验:https://fir.im/webviewstudy
- 最后再附一遍项目地址?:WebViewStudy
- 多图见证模拟机器人的逆天成长:论进化策略在强化学习中的应用
- Hue禁止用户下载数据问题分析
- 如何在RedHat6上使用Bind搭建DNS服务
- 如何使用Cloudera Manager升级Spark2.1版本至Spark2.2
- Cloudera Manager分发Parcel异常分析
- 如何在Hue中配置Impala的负载均衡
- 35行代码实现千万级别字典的快速去重
- PIMS三个漏洞+里程密最新版V2.3 SQL注入漏洞
- 如何在Redhat7.3安装CDH5.14
- CDSW1.3的新功能
- 如何在Hue中配置HiveServer2的负载均衡
- 如何修改CDH集群的IP地址
- 如何在Kerberos环境的CDH集群部署Livy
- 如何在Kerberos环境下使用Haproxy实现HiveServer2负载均衡
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- springboot 事务,多张表的操作事务回滚
- 移动硬盘显示盘符但是打不开,提示加密
- GORM V2 模型定义、约定、标签
- 字符串:简单的反转还不够!
- TypeScript 实战算法系列(七):实现图的遍历
- 63. Vue MUI的基本使用
- 初学web自动化测试--笔记1
- R语言作图——Line plot with error
- Python自学成才之路 玩转虚拟环境
- 基于腾讯云的 Rust 和 WebAssembly 函数即服务
- 谷歌开源NLP模型可视化工具LIT,模型训练不再「黑箱」
- Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方案
- 社区开源框架预制件相关模块:CollectManager详解
- Kettle构建Hadoop ETL实践(三):Kettle对Hadoop的支持
- 3种 Springboot 全局时间格式化方式,别再写重复代码了