Android: How to Capture Screen in Gingerbread(2.3中实现截屏)
示例代码在:
frameworks\base\services\surfaceflinger\tests\screencap\screencap.cpp
/** Copyright (C) 2010 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <utils/Log.h>#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>#include <binder/IMemory.h>
#include <surfaceflinger/ISurfaceComposer.h>#include <SkImageEncoder.h>
#include <SkBitmap.h>using namespace android;int main(int argc, char** argv)
{if (argc != 2) {printf("usage: %s path\n", argv[0]);exit(0);}const String16 name("SurfaceFlinger");sp<ISurfaceComposer> composer;getService(name, &composer);sp<IMemoryHeap> heap;uint32_t w, h;PixelFormat f;status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0);if (err != NO_ERROR) {fprintf(stderr, "screen capture failed: %s\n", strerror(-err));exit(0);}printf("screen capture success: w=%u, h=%u, pixels=%p\n",w, h, heap->getBase());printf("saving file as PNG in %s ...\n", argv[1]);SkBitmap b;b.setConfig(SkBitmap::kARGB_8888_Config, w, h);b.setPixels(heap->getBase());SkImageEncoder::EncodeFile(argv[1], b,SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);return 0;
}
编译后生成 /system/bin/test-screencap
测试时终端输入 test-screencap /mnt/sdcard/scapxx.png
可以看到SD卡生成截屏文件scapxx.png,默认大小为屏幕分辨率
如果想把这个功能写到自己的应用里
写个JNI,参考上面代码即可,但记得权限声明
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
贴出JNI代码,或资源下载地址:http://download.csdn.net/detail/zmyde2010/3835127
jni/com_android_ScreenCap_ScreenCapNative.cpp
/** Copyright (C) 2010 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#define LOG_TAG "ScreenCapNative-JNI"//#define LOG_NDEBUG 0#include "JNIHelp.h"
#include "jni.h"#include <utils/Log.h>#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>#include <binder/IMemory.h>
#include <surfaceflinger/ISurfaceComposer.h>#include <SkImageEncoder.h>
#include <SkBitmap.h>namespace android { static void android_ScreenCap_ScreenCapNative_nativeCaptureScreen(JNIEnv* env,jobject obj, jstring file)
{const char *file_path = env->GetStringUTFChars(file, NULL);const String16 name("SurfaceFlinger");sp<ISurfaceComposer> composer;getService(name, &composer);sp<IMemoryHeap> heap;uint32_t w, h;PixelFormat f;status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0);if (err != NO_ERROR) {LOGE("screen capture failed: %s\n", strerror(-err));exit(0);}LOGD("screen capture success: w=%u, h=%u, pixels=%p\n",w, h, heap->getBase());LOGD("saving file as PNG in %s ...\n", file_path);SkBitmap b;b.setConfig(SkBitmap::kARGB_8888_Config, w, h);b.setPixels(heap->getBase());SkImageEncoder::EncodeFile(file_path, b,SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
}static JNINativeMethod gScreenCapNativeMethods[] = {/* name, signature, funcPtr */{ "nativeCaptureScreen", "(Ljava/lang/String;)V",(void*) android_ScreenCap_ScreenCapNative_nativeCaptureScreen },
};int register_android_ScreenCap_ScreenCapNative(JNIEnv* env) {int res = jniRegisterNativeMethods(env, "com/android/ScreenCap/ScreenCapNative",gScreenCapNativeMethods, NELEM(gScreenCapNativeMethods));LOG_FATAL_IF(res < 0, "Unable to register native methods.");return 0;
} extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{JNIEnv* env = NULL;jint result = -1;if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {LOGE("GetEnv failed!");return result;}LOG_ASSERT(env, "Could not retrieve the env!");register_android_ScreenCap_ScreenCapNative(env);return JNI_VERSION_1_4;
} } /* namespace android */
jni/Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)LOCAL_SRC_FILES := com_android_ScreenCap_ScreenCapNative.cppLOCAL_C_INCLUDES += \$(JNI_H_INCLUDE)LOCAL_SHARED_LIBRARIES := \libnativehelper \libcutils \libutils \libbinder \libskia \libui \libsurfaceflinger_clientLOCAL_C_INCLUDES += \external/skia/include/core \external/skia/include/effects \external/skia/include/images \external/skia/src/ports \external/skia/include/utilsLOCAL_MODULE:= libscreencapjni
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := falseinclude $(BUILD_SHARED_LIBRARY)
看到有人问Java怎么调用JNI,贴出例子:
src/com/android/ScreenCap/ScreenCapNative.java
/* zmyde2010@csdn */
package com.android.ScreenCap;import java.io.File;
import android.os.Environment;public class ScreenCapNative {static {System.loadLibrary("screencapjni");};private native static void nativeCaptureScreen(String file);public static String startCaptureScreen() {String file_name = getUniqueFileName();if (file_name != null) {nativeCaptureScreen(file_name);}return file_name;}private static String getUniqueFileName() {File file = null;if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {file = createUniqueFile(Environment.getExternalStorageDirectory(),"ScreenCap.PNG");} else if (Environment.getInternalStorageState().equals(Environment.MEDIA_MOUNTED)) {file = createUniqueFile(Environment.getInternalStorageDirectory(),"ScreenCap.PNG"); }return (file != null) ? file.getAbsolutePath() : null;}private static File createUniqueFile(File directory, String filename) {File file = new File(directory, filename);if (!file.exists()) {return file;}// Get the extension of the file, if any.int index = filename.lastIndexOf('.');String format;if (index != -1) {String name = filename.substring(0, index);String extension = filename.substring(index);format = name + "-%d" + extension;}else {format = filename + "-%d.PNG";}for (int i = 2; i < Integer.MAX_VALUE; i++) {file = new File(directory, String.format(format, i));if (!file.exists()) {return file;}}return null;} }
可以在你的Acitvity或Service里面调用 ScreenCapNative.startCaptureScreen();来截屏
4.0源码已经公布了,大家不要花时间研究2.3的截屏了
当然最好是系统级实现,响应某个组合键来截屏,像Android4.0
发两张截图:
我上传了全部源码,包括编译后的APK,so,稍后请到我的资源里面下载:
http://download.csdn.net/detail/zmyde2010/3911916
例子中截屏作为一个开机启动的后台service,在需要截屏的任何地方(系统servic或其他APK),发送
Intent "com.android.CAPTURE_SCREEN" 即可
我的测试版本是2.3.4,其它不保证能用
Android: How to Capture Screen in Gingerbread(2.3中实现截屏)相关推荐
- Android: How to Capture Screen in Gingerbread(2.3中实现截屏)(续)
在这里首先很感谢博主zmyde2010发表的这篇http://blog.csdn.net/zmyde2010/article/details/6925498#reply文章,我最开始也是看了他的文章才 ...
- android禁止录屏功能,react-native(安卓)项目中禁止截屏与录屏
一.整个项目中禁止截屏与录屏 在android/app/src/main/java/com/your-app-name/MainActivity.java文件中的onCreate方法中添加如下代码即可 ...
- Android中的截屏、录屏、投屏等常用命令和工具
1:截屏命令screencap adb shell screencap -p /sdcard/screen.png 详细使用可以使用命令adb shell screencap –v查看帮助 对应的编译 ...
- FastStone Capture安装、注册及使用教程(截屏、滚动截图、录屏、图片编辑工具)
FastStone Capture是一款集截屏.滚动截图.录屏.图片编辑为一体轻量级截图软件.免费试用30天. 如果你需要找一个具有上述红色字描述的功能的软件的话,可以继续往下阅读.若是你想找一个截图 ...
- android平板怎么截图,在安卓手机或平板电脑上截屏的5种方法,学起来!
在Android手机或平板电脑上截屏并不是随便按下一个按钮那样简单,尤其是当你尝试捕获运动中的特定场景(例如游戏或视频),或者你担心可能会消失的屏幕时,以及当你正打算截屏,但是一不小心把手机屏幕关了的 ...
- 荣耀android手机怎么截图,华为荣耀畅玩5C怎么截图/截屏方法教程
华为荣耀畅玩5C怎么截图/截屏方法教程 来源:www.18183.com作者:皮卡时间:2016-04-29 作为荣耀今年的首款开年作品,该机受到了很多用户们的关注,而小编也相信有不少花粉们已经入手了 ...
- android后台截屏实现(2)--screencap源码修改
首先找到screencap类在Android源码中的位置,/442/frameworks/base/cmds/screencap/screencap.cpp. 源码如下: [cpp] view pla ...
- Android Studio实现设备截屏
通过Android Studio可以实现对虚拟器和真机的截屏. 1 对模拟器的截屏 可以通过虚拟器的"Take screenshot"实现截屏 1.1默认方式截屏 Android ...
- Android截屏的几种实现
Android截屏的几种实现 最近我们的APP要求需要截屏功能,网上看了看大致有一下几种实现的方式,由于我们的机器是特定的设备,(类似于广告机,已经ROOT),所以就采用最简单的方式,只需在代码中执行 ...
最新文章
- xmake入门,构建项目原来可以如此简单
- “在使用GCC时,同意Xcode / iOS许可证需要管理员权限,请通过sudo以root身份重新运行。”
- 买房子还是不买房子,这是一个问题
- 整理的部分Java和C#不同点
- 新手上路,Python黑帽子学习笔记从此开篇
- android 手机地图
- 十道经典javaWeb面试题
- 零碎记录- spring security oauth2 资源服务器中设置放行路径
- Matplotlib:线类型
- VB长度宽度高度单位,width,scaleWidth,Height,scaleHeight,scaleMode
- 电商营销新思路:CPS分销推广模式
- 微信小程序,高德地图
- c语言数据结构课程设计停车场管理系统,数据结构课程设计报告停车场管理系统...
- 初学makefile
- 旺旺号userid转换店铺shopid和评分性别
- TLD 源码详解(一)--- TLD的编译和运行
- 灰关联分析与语音/音乐信号识别
- 细思极恐,第三方跟踪器正在获取你的数据,如何防范?
- 电路板上的插头怎么拔下来_如何在电路板上完美的取下多针脚电子元件?求高手指教方法技巧?...
- 使用Microsoft Toolkit激活微软Office2010
热门文章
- javaS的tring和androidS的tring区别是什么?
- 元月元日是哪一天_2021年元旦是在哪一天几号 1月1日周五
- OracleP6机场工程进度控制系列15:总进度综合管控报告
- 软件工程课程周学习进度报告——第三周
- 本地电脑ssh连接机器人,使用rviz控制机器人导航
- 楼教主的ACM心路历程
- Android Studio快速集成讯飞SDK实现文字朗读功能
- 回归预测 | MATLAB实现MPR多元多项式回归
- 详细理解HashMap数据结构,太齐全了!
- execjs 模块 call() 方法报错 AttributeError: ‘NoneType‘ object has no attribute ‘replace‘