一、Android 截屏攻击
针对 Android 应用的 " 截屏攻击 " 是 恶意应用程序 或者 攻击者利用某些漏洞或技术手段 , 非法获取用户屏幕上的敏感信息 , 会导致用户 隐私泄漏 或者 造成安全风险 , 下面是常见的攻击方式 :
- 恶意应用程序 : 恶意应用程序 可能会 请求截屏权限 并将截屏的内容上传到远程服务器 , 尤其是账号密码输入界面的截屏 ;
- 操作系统漏洞利用 : 利用操作系统中的 漏洞 来执行 未授权的截屏操作 ;
- 屏幕录制 : 屏幕录制技术 也可能被用于窃取用户的屏幕信息 ;
二、Android 系统的截屏方式
在 Android 系统中 , 用户可以 通过 特定的键盘组合触发 截屏 ;
- 电源键 音量减小键 : Android 设备上触发截屏的组合键 , 系统会触发截屏操作 , 并将当前屏幕内容保存为图片文件 ; 手势操作:
- 滑动手势 : 在特定的 Android 设备上 , 可以使用手势或者滑动手势来触发截屏操作 ; 通知栏快捷方式:
- 通知栏菜单 : 有些 Android 设备 在通知栏中提供了截屏的快捷方式按钮 , 用户可以通过点击该按钮来执行截屏操作 ; 系统设置中的截屏选项 ;
- 自定义截屏 : 用户 在 系统设置中 配置截屏的 自定义触发方式 ;
三、通过 adb 命令截屏
通过 adb 命令截屏 :
- 首先 , 执行如下命令 , 进行截图 , 并将截图存储到手机的存储空间中 ;
adb shell screencap -p /sdcard/screenshot.png
- 然后 , 执行如下命令 , 将手机中的截图传输到电脑中 ;
adb pull /sdcard/screenshot.png /path/to/save/on/computer/
Android Studio 中的截图功能 , 就是这么实现的 ;
四、Android 截屏代码
在 Android 应用程序中 , 通过代码进行截屏 , 需要如下几个步骤 :
- 首先 , 获取 Activity 的 根 View 视图 ;
View rootView = activity.getWindow().getDecorView().getRootView();
- 然后 , 创建一个空的 Bitmap 对象 , 位图的宽高就是 根 View 的宽高 ;
Bitmap screenshotBitmap = Bitmap.createBitmap(rootView.getWidth(), rootView.getHeight(), Bitmap.Config.ARGB_8888);
- 最后 , 将 根 View 组件的内容 , 绘制到 Bitmap 对象上 ;
rootView.draw(new Canvas(screenshotBitmap));
代码示例 :
代码语言:javascript复制import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Environment;
import android.view.View;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class ScreenshotUtils {
// 截屏并保存到指定文件
public static void takeScreenshot(Activity activity) {
// 获取屏幕内容的视图
View rootView = activity.getWindow().getDecorView().getRootView();
// 创建一个空的Bitmap,大小为屏幕的宽高
Bitmap screenshotBitmap = Bitmap.createBitmap(rootView.getWidth(), rootView.getHeight(), Bitmap.Config.ARGB_8888);
// 将屏幕内容绘制到Bitmap上
rootView.draw(new Canvas(screenshotBitmap));
// 保存Bitmap到文件
saveBitmapToFile(screenshotBitmap, "screenshot.png");
}
// 将Bitmap保存到文件
private static void saveBitmapToFile(Bitmap bitmap, String fileName) {
// 获取外部存储的公共目录
File directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
// 创建存储文件的目录
File screenshotFile = new File(directory, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(screenshotFile);
// 将Bitmap压缩为PNG格式并写入文件
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
// 刷新文件输出流
fos.flush();
// 在此可以发送广播通知系统相册更新
// MediaScannerConnection.scanFile(context, new String[]{screenshotFile.getAbsolutePath()}, null, null);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五、设置 FLAG_SECURE 标志位禁止屏幕截屏
在 Activity 代码中 , 可以在调用 setContentView 函数之前 ,
为 Window 窗口对象 设置 LayoutParams.FLAG_SECURE 标志位 , 可以禁止对本界面进行截屏 ,
Window 窗口对象 , 可通过 getWindow 方法获取 ,
核心代码如下 :
代码语言:javascript复制getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
代码示例 :
代码语言:javascript复制import android.app.Activity;
import android.os.Bundle;
import android.view.WindowManager.LayoutParams;
public class FlagSecureTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置 FLAG_SECURE 标志位,禁止屏幕截屏
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
// 设置布局内容
setContentView(R.layout.main);
}
}