美文网首页Android知识Android开发android成神之路
Android 调用手机浏览器的正确方式

Android 调用手机浏览器的正确方式

作者: 5c7e9c07cd43 | 来源:发表于2016-09-28 10:12 被阅读3718次

    效果1

    效果1.png
    参考 - 程序亦非猿 - Android 调用手机浏览器的正确方式

    代码实现

    final Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);、intent.setData(Uri.parse("http://www.baidu.com"));
    // 注意此处的判断intent.resolveActivity()可以返回显示该Intent的Activity对应的组件名
    // 官方解释 : Name of the component implementing an activity that can display the intent
    if (intent.resolveActivity(getPackageManager()) != null) {    
      final ComponentName componentName = intent.resolveActivity(getPackageManager()); 
      // 打印Log   ComponentName到底是什么
      Log.e(TAG, "componentName = " + componentName.getClassName());
      startActivity(Intent.createChooser(intent, "请选择浏览器"));
    } else {    
      Toast.makeText(getApplicationContext(), "没有匹配的程序", Toast.LENGTH_SHORT).show();
    }
    

    不太严谨的实现方式

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    Uri content_url = Uri.parse(url);
    intent.setData(content_url);
    startActivity(intent);
    这里出现问题的原因有2个:
    1. 如果手机没有浏览器 - 程序崩溃。
    2. 即便是有浏览器 - 也会使用默认的浏览器打开。我想使用Android的同学都用的是第三方的浏览器吧,都不给用户选择的权利,体验很差。
    

    深入学习

    final Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));
    if (intent.resolveActivity(getPackageManager()) != null) {    
      final ComponentName componentName = intent.resolveActivity(getPackageManager());   
      Log.e(TAG, "componentName = " + componentName.getClassName());
    } 
    
    Log-ComponentName
    ComponentName : 原来是 BrowserActivity !
    大家可以查看Android 源码找到这个类,本人能力有限,就不再献丑了!
    参考 - SuShine的博客 - Android Browser学习二 BrowserActivity 的初始化 --其他重要模块

    效果2

    效果2.png

    代码实现

    // 1.Button注册了点击事件 
    mRequstBtn.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        
    final Intent intent = new Intent();        
    intent.setAction(Intent.ACTION_VIEW);        
    intent.setData(Uri.parse("http://www.baidu.com"));        
    if (intent.resolveActivity(getPackageManager()) != null) {            
      final ComponentName componentName = intent.resolveActivity(getPackageManager());            
      Log.e(TAG, "componentName = " + componentName.getClassName());            
      startActivity(Intent.createChooser(intent, "请选择浏览器"));       
     } 
    
    // 给需要调起的Activity增加 intent-filter
    <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="http" />
    </intent-filter>
    解读:
    1. Button 注册了点击事件,打开浏览器访问 http://www.baidu.com,注意这里是Http协议
    2. 需要被调起的Activity 注册 <intent-filter>  注意这里的约束scheme 是http协议,如果需要访问的网址是https协议,此处约束应该是scheme=https
    
    字段 解释
    action 指定 ACTION_VIEW Intent 操作,以便能够从 Google 搜索中访问该 Intent 过滤器
    category 定义了 BROWSABLE 和 DEFAULT 这两种 Intent 的 Activity-BROWSABLE:若要能够从 Web 浏览器执行该 Intent,则必须将其设为 BROWSABLE。如果未设置,点击浏览器中的链接将无法解析到您的应用(在这种情况下,只有当前的移动 Web 浏览器能响应该 URL)。DEFAULT:只有当您希望自己的 Android 应用能够响应任何引用网站中的 HTTP 链接时,才需要设为 DEFAULT。在 Google 搜索结果中使用的 Intent 包含您的应用标识信息,以便将您的应用明确指定为接收方。指向您的网站的其他链接不知道您的应用标识,因此 DEFAULT 类别声明了您的应用可以对隐式 Intent 做出响应。
    data Activity 接受的每种 URI 格式都有一个这样的标记。此 <data> 标记必须至少包括 android:scheme 属性。您可以添加额外的属性,以进一步细化 Activity 接受的 URI 类型。例如,您可能有多个接受类似 URI 的 Activity,但其不同之处只是在于路径名。在这种情况下,可以使用 android:path 属性或者其变体(pathPattern 或 pathPrefix)来区分对于不同的 URI 路径,系统应打开哪个 Activity

    intent-filter详解

    效果3

    前提: 本人通过手机默认浏览器及html查看器都可以成功调起本地app


    步骤1-打开测试的网页.png
    // 网页的源码,很简单
    <!DOCTYPE html>
    <html lang="en">
      <head>    
        <meta charset="UTF-8">    
        <title>        通过浏览器调起本地App    </title>
      </head>
      <body>
        <a href="cmc://test/name/familyname/?name=Wankaz&family_name=Arale">open app</a>
      </body>
    </html>
    
    调起App效果图.png
    // AndroidManifest.xml文件中的设置
    <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:host="test"        
        android:path="/name/familyname/"        
        android:scheme="cmc" />
    </intent-filter>
    //  获取到的数据
    // 常量的定义
    private final static String NAME = "name";
    private final static String LASTNAME = "family_name";
    // 解析intent中的数据
    Intent intent = getIntent();
    if (intent != null) {    
      Uri uri = intent.getData();    
      if (uri != null) {        
        Log.e("uri", uri.toString());        
        if ("cmc".equals(uri.getScheme())) {            
          List<String> list = uri.getPathSegments();            
          if (list != null && list.size() == 2) {                            
            mShowWebContentTv.setText("获取到了浏览器数据,姓=" + uri.getQueryParameter(NAME) + ", 名=" + uri.getQueryParameter(LASTNAME));            
          }        
       } else {       
         Log.e("intent", "uri = null");    
      }
    } else {    
      Log.e("intent", "intent = null");
    }
    // 代码解读
    1. Html页面中只有一个超链接,<a href="cmc://test/name/familyname/?name=Wankaz&family_name=Arale">open app</a>
    2. 设置 AndroidManifest.xml ,为需要调起的页面设置<intent-filter>,我们发现 <intent-filter>里面设置的<data>中的scale,host,path正好对应超链接中的 cmc://test/name/familyname/;而name=Wankaz&family_name=Arale则是对应的数据。
    3. 代码中解析数据- 从html页面中获取到的数据见下图
    

    调起App时,获取到html中的内容如下,该内容被封装到Intent中,并通过 intent.getData()获取(使用Uri表示),我们通过uri.getQueryParameter()获取具体字段的值。


    Log-Uri.jpeg

    问题

    1.当App已启动时,也可以调起app,只是获取不到Intent中的数据。我的大概理解是Android中Activity启动时通过Intent在传递数据,如果我们的Activity已经启动,没有再次获取Intent对象,android:launchMode="singleInstance";这个需要其它同学解答下。
    2.为什么我把Activity启动模式设置为android:launchMode="singleInstance"?因为如果我们使用默认的standard模式,会发现被调起的app的Activity运行在浏览器的任务栈中了。这是Activity启动模式对调起App的影响。
    3.有什么不足之处,希望大家指正。谢谢

    相关文章

      网友评论

        本文标题:Android 调用手机浏览器的正确方式

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