Android 获取浏览器当前分享页面的截屏

版权声明:本文为博主原创文章,未经博主允许不得转载。

微博:厉圣杰

源码:AndroidDemo/BrowserScreenShotActivity

文中如有纰漏,欢迎大家留言指出。

今天在项目中碰见这么一个需求:获取 Chrome 浏览器分享时,页面的截屏。静下来一想,既然是分享,那么肯定得通过 Intent 来传递数据,如果真的能获取到 Chrome 分享页面时的截屏,那么 Intent 的数据中,一定有 .jpg 或者 .png 结尾的数据。说干就干,Demo 写起来。

首先,新建一个 BrowserScreenShotActivity.java,在 AndroidManifest.xml 注册一下 <intent-filter>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.littlejie.demo"> <!-- 读写权限 -->
<!-- 用于读取浏览器分享时生成的屏幕截图 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application
android:name=".modules.DemoApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"> <!-- some other thing --> <!-- 注册 Intent,用于接受浏览器分享 -->
<activity
android:name=".modules.advance.BrowserScreenShotActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<!-- 发送多个数据 -->
<action android:name="android.intent.action.SEND_MULTIPLE"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="*/*"/>
</intent-filter>
</activity> </application> </manifest>

接下去,在浏览器中随便打开一个页面,分享至 Demo,这里有个问题,就是:屏幕截图数据在 Intent 中对应的 Key 我们并不知道,那怎么办呢?打断点啊!

通过断点查看 Intent 的数据结构,发现 Intent 中的 mMap 成员变量含有一个 Uri,格式如下:content://com.android.chrome.FileProvider/BlockedFile_33215122012582,一眼看去就猜测这个 Uri 是 Chrome 通过 ContentProvider 供其他程序调用的,虽然与一开始猜测有已 .jpg 和 .png 结尾的数据不太一致,但好歹是有所发现。

恩,现在还有一个问题,那就是 mMap.value[3] 对应的 key 值是多少?在上述断点界面根本就差看不到,但是 Android Studio 是很强大的,只是你没发现而已,既然 mMap 是一个 Map,那么久能通过 keySet() 方法获取 Map 的 key。接下来就是 Android Studio 大展拳脚的时间。



如上图所示的,在 Debug 界面,点击最后一个图标:Evaluate Expression(快捷键:option + f8)。在弹出的对话框中输入如下内容,回车,你会发现 Map 的 key 都出来了:

通过与第一幅图对比,发现下标为3的值(share_screenshot_as_stream)为我们需要的 key。

布局比较简单,这里就不贴了,简单截取 BrowserSrceenShotActivity.java 中的代码:

@Override
protected void onResume() {
super.onResume();
if (getIntent() == null) {
return;
} Uri screenShot = getIntent().getExtras().getParcelable("screen_shot_as_stream"); if (screenShot == null) {
ToastUtil.showDefaultToast("获取浏览器截屏失败~");
return;
}
try {
//授权Uri的读取权限
//若不授权,在 Android 6.0 以上测试崩溃
//https://thinkandroid.wordpress.com/2012/08/07/granting-content-provider-uri-permissions/
//第一个参数为需要授权的apk包名
grantUriPermission("com.littlejie.demo", screenShot, Intent.FLAG_GRANT_READ_URI_PERMISSION);
//通过 Uri 获取截屏图片的输入流
InputStream is = getContentResolver().openInputStream(screenShot);
mIvScreenShot.setImageBitmap(BitmapFactory.decodeStream(is));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

运行结果如下:

对于获取 Chrome 浏览器分享页面的截屏就告一段落,闲着没事,自己又测试了几个浏览器,包括系统内置浏览器、QQ浏览器、UC浏览器、百度浏览器、火狐浏览器,发现每个浏览器的差异很大。

  • 系统浏览器、UC浏览器与 Chrome 相差不大,只是 key 变成了 share_full_screenfile
  • QQ浏览器的分享行为与分享文件很相似,其 key 为 android.intent.extra.STREAM(Intent.EXTRA_STREAM)。
  • 百度浏览器是个什么鬼就不知道了,默默的把应用图标给分享过来了
  • 火狐浏览器不支持分享页面截图

恩,就这么多,获取浏览器分享页面截屏主要还是靠浏览器的支持,真的市面上这么多浏览器适配起来还真麻烦。这次主要对 Android Studio 强大的 Debug功能进行了学习。PS:Android Studio真是极其强大的工具,用好它事半功倍,唯一不足的就是太耗性能。

Demo 代码传送门

Android 获取浏览器当前分享页面的截屏的更多相关文章

  1. Android应用内 代码截屏(获取View快照)和 禁止截屏

    1. 应用内的代码截屏(获取View的快照) Android的View类中提供了获取控件绘制缓存的方法,这种截屏的方式仅限于应用内自己的Activity界面,不需要任何权限,严格来说该方法不属于截屏, ...

  2. react native 中实现个别页面禁止截屏

    这里主要用到了原生模块,下面贴出FlagSecureModule.java的代码 package com.studyproj.flagsecure; import android.util.Log; ...

  3. Android通过浏览器打开app页面并且传递值

    最近公司有个需求,要求从第三方网页端打开一个网页,然后在网页中点击“下载”,“打开”按钮,在app端进行下载和打开操作.这里记录下方法. 首先,网页和app页面进行交互,其实会很快想到JS交互,但是现 ...

  4. javascript实现当前页面截屏

    javascript实现当前页面截屏 一.前言 有客户要求能对用户当前页面进行指定区域截屏,类似qq截屏的实现效果.比如用户在处理工作的时候,将当前页面录入后的一些信息进行截图下载保存.但又不能安装任 ...

  5. Android截屏的几种实现

    Android截屏的几种实现 微信公众号:CodingAndroid CSDN:http://blog.csdn.net/xinpengfei521 最近我们的APP要求需要截屏功能,网上看了看大致有 ...

  6. android手机截屏、录屏

    1. 手动截屏,通过其他第三方软件发送截图,或者从手机取出截图 2. 使用命令截图,将截图保存到手机,再拉取到电脑 #!/bin/sh #运行 sh screenshot name picName=$ ...

  7. Android 禁止截屏、录屏 — 解决PopupWindow无法禁止录屏问题

    项目开发中,为了用户信息的安全,会有禁止页面被截屏.录屏的需求. 这类资料,在网上有很多,一般都是通过设置Activity的Flag解决,如: //禁止页面被截屏.录屏 getWindow().add ...

  8. 【转】Android截屏

     http://blog.csdn.net/xww810319/article/details/17607749 Android截屏浅析 链接:http://blog.sina.com.cn/s/bl ...

  9. [置顶] Android 应用内禁止截屏功能的实现

    截图介绍   Android的调试工具DDMS提供有截屏功能,很多软件也会有截屏功能,在做支付等安全类应用的时候,为了保证用户的资产和系统安全,往往会禁止应用内截屏,禁止之后,在此应用处于前台的情况下 ...

随机推荐

  1. LPC1768IAP(详解,有上位机)

    之前说了stm32的iap编程,今天天气真好,顺手就来说说lpc1788的iap编程(没看前面的请查看stm笔记下的内容) 首先是flash的算法,lpc1768并没有寄存器来让我们操作flash,他 ...

  2. MongoDB的$type操作符

    字段类型定义: db.col.find({"title" : {$type : 2}})

  3. 1)Javascript设计模式:Module模式

    最简单的创建对象方法 function User(name) { this.name = name || '' } User.prototype.say = function() { console. ...

  4. UVa 10033 - Interpreter

    题目大意:模拟题,有一些寄存器和随机访问内存,给你一些指令以及它们代表的操作,模拟操作即可. #include <cstdio> #include <cstring> #def ...

  5. IOS 程序图标添加数字

    +(void)setAppIconNumber:(NSInteger)num{ if ([UIParam getIOSVersion]>8.0) { UIUserNotificationSett ...

  6. iOS 添加导航栏两侧按钮

    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"首页" style ...

  7. iOS 之 Aggregate Target

    工程导航栏>选中工程>菜单File>New>Target>Other>Aggregate

  8. 【spoj LCS2】 Longest Common Substring II

    http://www.spoj.com/problems/LCS2/ (题目链接) 题意 求多个串的最长公共子串 Solution 对其中一个串构造后缀自动机,然后其它串在上面跑匹配.对于每个串都可以 ...

  9. 关于firefox启动就崩溃的问题

    前些天在公司内网机器安装了Firefox Developer,每次启动直接就崩溃.最后发现问题出在Firefox的硬件加速上.解决办法: 1.右击firefox快捷方式,选择属性,在“目标”后面,即f ...

  10. GCD教程(三):Dispatch Sources

    接上一篇,原帖地址:http://www.dreamingwish.com/dream-2012/intro-to-grand-central-dispatch-part-iii-the-dispat ...