Android: How to Capture Screen in Gingerbread(2.3中实现截屏)

示例代码在:

frameworks\base\services\surfaceflinger\tests\screencap\screencap.cpp

  1. /*  
  2.  * Copyright (C) 2010 The Android Open Source Project  
  3.  *  
  4.  * Licensed under the Apache License, Version 2.0 (the "License");  
  5.  * you may not use this file except in compliance with the License.  
  6.  * You may obtain a copy of the License at  
  7.  *  
  8.  *      http://www.apache.org/licenses/LICENSE-2.0  
  9.  *  
  10.  * Unless required by applicable law or agreed to in writing, software  
  11.  * distributed under the License is distributed on an "AS IS" BASIS,  
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13.  * See the License for the specific language governing permissions and  
  14.  * limitations under the License.  
  15.  */  
  16.   
  17. #include <utils/Log.h>  
  18.   
  19. #include <binder/IPCThreadState.h>  
  20. #include <binder/ProcessState.h>  
  21. #include <binder/IServiceManager.h>  
  22.   
  23. #include <binder/IMemory.h>  
  24. #include <surfaceflinger/ISurfaceComposer.h>  
  25.   
  26. #include <SkImageEncoder.h>  
  27. #include <SkBitmap.h>  
  28.   
  29. using namespace android;  
  30.   
  31. int main(int argc, char** argv)  
  32. {  
  33.     if (argc != 2) {  
  34.         printf("usage: %s path\n", argv[0]);  
  35.         exit(0);  
  36.     }  
  37.   
  38.     const String16 name("SurfaceFlinger");  
  39.     sp<ISurfaceComposer> composer;  
  40.     getService(name, &composer);  
  41.   
  42.     sp<IMemoryHeap> heap;  
  43.     uint32_t w, h;  
  44.     PixelFormat f;  
  45.     status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0);  
  46.     if (err != NO_ERROR) {  
  47.         fprintf(stderr, "screen capture failed: %s\n", strerror(-err));  
  48.         exit(0);  
  49.     }  
  50.   
  51.     printf("screen capture success: w=%u, h=%u, pixels=%p\n",  
  52.             w, h, heap->getBase());  
  53.   
  54.     printf("saving file as PNG in %s ...\n", argv[1]);  
  55.   
  56.     SkBitmap b;  
  57.     b.setConfig(SkBitmap::kARGB_8888_Config, w, h);  
  58.     b.setPixels(heap->getBase());  
  59.     SkImageEncoder::EncodeFile(argv[1], b,  
  60.             SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);  
  61.   
  62.     return 0;  
  63. }  

编译后生成 /system/bin/test-screencap

测试时终端输入 test-screencap /mnt/sdcard/scapxx.png

可以看到SD卡生成截屏文件scapxx.png,默认大小为屏幕分辨率


如果想把这个功能写到自己的应用里

写个JNI,参考上面代码即可,但记得权限声明

  1. <span style="font-size:24px;"><uses-permission android:name="android.permission.READ_FRAME_BUFFER" /></span>  

贴出JNI代码,或资源下载地址:http://download.csdn.net/detail/zmyde2010/3835127

jni/com_android_ScreenCap_ScreenCapNative.cpp

  1. /* 
  2.  * Copyright (C) 2010 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. #define LOG_TAG "ScreenCapNative-JNI"  
  18.   
  19. //#define LOG_NDEBUG 0  
  20.   
  21. #include "JNIHelp.h"  
  22. #include "jni.h"  
  23.   
  24. #include <utils/Log.h>  
  25.   
  26. #include <binder/IPCThreadState.h>  
  27. #include <binder/ProcessState.h>  
  28. #include <binder/IServiceManager.h>  
  29.   
  30. #include <binder/IMemory.h>  
  31. #include <surfaceflinger/ISurfaceComposer.h>  
  32.   
  33. #include <SkImageEncoder.h>  
  34. #include <SkBitmap.h>  
  35.   
  36. namespace android {   
  37.   
  38. static void android_ScreenCap_ScreenCapNative_nativeCaptureScreen(JNIEnv* env,  
  39.         jobject obj, jstring file)   
  40. {  
  41.     const char *file_path = env->GetStringUTFChars(file, NULL);  
  42.   
  43.     const String16 name("SurfaceFlinger");  
  44.     sp<ISurfaceComposer> composer;  
  45.     getService(name, &composer);  
  46.   
  47.     sp<IMemoryHeap> heap;  
  48.     uint32_t w, h;  
  49.     PixelFormat f;  
  50.     status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0);  
  51.     if (err != NO_ERROR) {  
  52.         LOGE("screen capture failed: %s\n", strerror(-err));  
  53.         exit(0);  
  54.     }  
  55.   
  56.     LOGD("screen capture success: w=%u, h=%u, pixels=%p\n",  
  57.             w, h, heap->getBase());  
  58.   
  59.     LOGD("saving file as PNG in %s ...\n", file_path);  
  60.   
  61.     SkBitmap b;  
  62.     b.setConfig(SkBitmap::kARGB_8888_Config, w, h);  
  63.     b.setPixels(heap->getBase());  
  64.     SkImageEncoder::EncodeFile(file_path, b,  
  65.             SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);              
  66. }  
  67.   
  68. static JNINativeMethod gScreenCapNativeMethods[] = {  
  69.     /* name, signature, funcPtr */  
  70.     { "nativeCaptureScreen""(Ljava/lang/String;)V",  
  71.             (void*) android_ScreenCap_ScreenCapNative_nativeCaptureScreen },              
  72. };  
  73.       
  74. int register_android_ScreenCap_ScreenCapNative(JNIEnv* env) {  
  75.     int res = jniRegisterNativeMethods(env, "com/android/ScreenCap/ScreenCapNative",  
  76.             gScreenCapNativeMethods, NELEM(gScreenCapNativeMethods));  
  77.     LOG_FATAL_IF(res < 0, "Unable to register native methods.");  
  78.   
  79.     return 0;  
  80. }     
  81.       
  82. extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)  
  83. {  
  84.     JNIEnv* env = NULL;  
  85.     jint result = -1;  
  86.   
  87.     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {  
  88.         LOGE("GetEnv failed!");  
  89.         return result;  
  90.     }  
  91.     LOG_ASSERT(env, "Could not retrieve the env!");  
  92.   
  93.     register_android_ScreenCap_ScreenCapNative(env);  
  94.   
  95.     return JNI_VERSION_1_4;  
  96. }     
  97.       
  98. /* namespace android */  

jni/Android.mk

  1. LOCAL_PATH:= $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3.   
  4. LOCAL_SRC_FILES := com_android_ScreenCap_ScreenCapNative.cpp  
  5.   
  6. LOCAL_C_INCLUDES += \  
  7.     $(JNI_H_INCLUDE)  
  8.   
  9. LOCAL_SHARED_LIBRARIES := \  
  10.     libnativehelper \  
  11.     libcutils \  
  12.     libutils \  
  13.     libbinder \  
  14.     libskia \  
  15.     libui \  
  16.     libsurfaceflinger_client  
  17.   
  18. LOCAL_C_INCLUDES += \  
  19.     external/skia/include/core \  
  20.     external/skia/include/effects \  
  21.     external/skia/include/images \  
  22.     external/skia/src/ports \  
  23.     external/skia/include/utils  
  24.   
  25. LOCAL_MODULE:= libscreencapjni  
  26. LOCAL_MODULE_TAGS := optional  
  27. LOCAL_PRELINK_MODULE := false  
  28.   
  29. include $(BUILD_SHARED_LIBRARY)      


看到有人问Java怎么调用JNI,贴出例子:

src/com/android/ScreenCap/ScreenCapNative.java

  1. /* zmyde2010@csdn */  
  2. package com.android.ScreenCap;  
  3.   
  4. import java.io.File;  
  5. import android.os.Environment;  
  6.   
  7. public class ScreenCapNative {  
  8.       
  9.     static {  
  10.         System.loadLibrary("screencapjni");  
  11.     };  
  12.       
  13.     private native static void nativeCaptureScreen(String file);  
  14.       
  15.     public static String startCaptureScreen() {  
  16.         String file_name = getUniqueFileName();  
  17.         if (file_name != null) {  
  18.             nativeCaptureScreen(file_name);  
  19.         }  
  20.         return file_name;  
  21.     }  
  22.       
  23.     private static String getUniqueFileName() {  
  24.         File file = null;  
  25.         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {  
  26.             file = createUniqueFile(Environment.getExternalStorageDirectory(),  
  27.                     "ScreenCap.PNG");  
  28.         } else if (Environment.getInternalStorageState().equals(Environment.MEDIA_MOUNTED)) {  
  29.             file = createUniqueFile(Environment.getInternalStorageDirectory(),  
  30.                     "ScreenCap.PNG");                  
  31.         }  
  32.           
  33.         return (file != null) ? file.getAbsolutePath() : null;  
  34.           
  35.     }  
  36.       
  37.     private static File createUniqueFile(File directory, String filename) {  
  38.         File file = new File(directory, filename);  
  39.         if (!file.exists()) {  
  40.             return file;  
  41.         }  
  42.         // Get the extension of the file, if any.  
  43.         int index = filename.lastIndexOf('.');  
  44.         String format;  
  45.         if (index != -1) {  
  46.             String name = filename.substring(0, index);  
  47.             String extension = filename.substring(index);  
  48.             format = name + "-%d" + extension;  
  49.         }  
  50.         else {  
  51.             format = filename + "-%d.PNG";  
  52.         }  
  53.         for (int i = 2; i < Integer.MAX_VALUE; i++) {  
  54.             file = new File(directory, String.format(format, i));  
  55.             if (!file.exists()) {  
  56.                 return file;  
  57.             }  
  58.         }  
  59.         return null;  
  60.     }     
  61.           
  62. }  


可以在你的Acitvity或Service里面调用 ScreenCapNative.startCaptureScreen();来截屏


4.0源码已经公布了,大家不要花时间研究2.3的截屏了


当然最好是系统级实现,响应某个组合键来截屏,像Android4.0

原文地址:http://blog.csdn.net/zmyde2010/article/details/6925498

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值