Android-应用被作为第三方浏览器打开

作者: Jinbeen | 来源:发表于2018-12-15 21:27 被阅读14次

    前言

    微信里的文章页面,可以选择“在浏览器打开”。现在很多应用都内嵌了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()方法会在onCreateonNewIntent方法中调用。

    解释:

    在实际使用中,有这样的场景:
    我们在微信中“通过浏览器”打开自己的应用,然后将自己的应用切到后台。重复上面的操作,会一直创建应用的实例,这样肯定是不好的,为了避免这种情况我们设置启动模式为: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

    相关文章

      网友评论

        本文标题:Android-应用被作为第三方浏览器打开

        本文链接:https://www.haomeiwen.com/subject/jogahqtx.html