android 截屏功能分析

1、当前Activity

通过ViewgetDrawingCache()方法获取View中的图像。

private Bitmapview2Bitmap(ViewparamView)

{

Log.e("ScreenShot","saveFileThread view2Bitmap(Viewview)");

  paramView.setDrawingCacheEnabled(true);

  paramView.buildDrawingCache();

  BitmaplocalBitmap1 = paramView.getDrawingCache();

  BitmaplocalBitmap2 = null;

  if (localBitmap1 !=null)

  {

     localBitmap2= Bitmap.createBitmap(localBitmap1);

  }

  paramView.destroyDrawingCache();

  return localBitmap2;

}

 

缺点:

此方法只限当前视图

此方法不能截取状态栏

此方法不能截取视频播放区域,截取的图片中的播放区域为全黑



2Service截屏


通过反射实现截屏。获取窗口所有的顶级视图,然后取最上层的视图获取图片。


获取窗口所有顶级视图


private View[]getWindowDecorViews()throws Exception


{


 View[] views;


 if (android.os.Build.VERSION.SDK_INT >= 14


          &&android.os.Build.VERSION.SDK_INT < 17)


 {


    views =getWindowDecorViewsApi14_16();


 } elseif (android.os.Build.VERSION.SDK_INT >= 17)


 {


    views =getWindowDecorViewsApiUp17();


 } else


 {


    views =getWindowDecorViewsDownApi15();


 }


  return views;


}


 


private View[] getWindowDecorViewsDownApi15()throws Exception


{


Class<?> windowManager = Class


           .forName("android.view.WindowManagerImpl");


Field viewsField = windowManager.getDeclaredField("mViews");


FieldinstanceField = windowManager.getDeclaredField("mWindowManager");


viewsField.setAccessible(true);


instanceField.setAccessible(true);


Object instance = instanceField.get(null);


View[] viewarray = (View[]) viewsField.get(instance);


return sortViews(viewarray);


}


 


private View[] getWindowDecorViewsApi14_16()throws Exception


{


Class<?> windowManager = Class


           .forName("android.view.WindowManagerImpl");


Field viewsField = windowManager.getDeclaredField("mViews");


Field instanceField = windowManager.getDeclaredField("sWindowManager");


viewsField.setAccessible(true);


instanceField.setAccessible(true);


Object instance = instanceField.get(null);


View[] viewarray = (View[]) viewsField.get(instance);


return sortViews(viewarray);


}


 


private View[]getWindowDecorViewsApiUp17()throwsException


{


  Class<?>windowManager = Class


           .forName("android.view.WindowManagerGlobal");


  FieldviewsField = windowManager.getDeclaredField("mViews");


  FieldinstanceField = windowManager


           .getDeclaredField("sDefaultWindowManager");


  viewsField.setAccessible(true);


  instanceField.setAccessible(true);


  Objectinstance = instanceField.get(null);


  View[]viewarray = (View[]) viewsField.get(instance);


  return viewarray;//sortViews(viewarray);


}


取前端的视图转图


private Bitmap view2Bitmap(View paramView)


{


  Log.e("ScreenShot","saveFileThread view2Bitmap(Viewview)");


  paramView.setDrawingCacheEnabled(true);


  paramView.buildDrawingCache();


  BitmaplocalBitmap1 = paramView.getDrawingCache();


  BitmaplocalBitmap2 = null;


  if (localBitmap1 !=null)


  {


     localBitmap2= Bitmap.createBitmap(localBitmap1);


  }


  paramView.destroyDrawingCache();


  return localBitmap2;


}


 


private Bitmap view2Bitmap(View[] paramArrayOfView)


{


  CanvaslocalCanvas = null;


  PaintlocalPaint = null;


  Bitmapnewbitmap = null;


  int[]arrayOfInt = newint[2];


  if(paramArrayOfView.length > 0)


  {


   ViewlocalView = paramArrayOfView[paramArrayOfView.length - 1];


  BitmaplocalBitmap = view2Bitmap(localView);


  newbitmap= localBitmap;


  }


return newbitmap;


}

 



缺点:


此方法不能截取状态栏


此方法不能截取视频播放区域,截取的图片中的播放区域为全黑




3、读取dev/graphics/fb0


读取此文件获取图片,需获得root权限。


读取图形设备文件


publicstaticfinalStringgetPermission="chmod 777 /dev/graphics/fb0\n";


publicstaticfinalStringgivePermission="chmod 660 /dev/graphics/fb0\n";


publicstaticBitmap getScreenBitmap(Context context) throws Exception {


  SystemManager.RootCommand(getPermission);


  init(context);


  byte[] piex =newbyte[width * height *deepth];


  InputStreamstream = newFileInputStream(new File(file_name));


  DataInputStreamdStream = newDataInputStream(stream);


  dStream.readFully(piex);


  dStream.close();


  stream.close();


  SystemManager.RootCommand(givePermission);


  int[] data =convertToColor(piex);


   return Bitmap.createBitmap(data,width,height, Bitmap.Config.ARGB_8888);


}


 


转图


  publicstaticint[] convertToColor_4byte(byte[] piex) {


     int[] colors =newint[width * height];


     int len = piex.length;


     for (int i = 0; i < len; i +=4) {


        int b = (piex[i] &0xFF);


        int g = (piex[i + 1] &0xFF);


        int r = (piex[i + 2] &0xFF);


        int a = (piex[i + 3] &0xFF);


        colors[i/ 4] = (a << 24) + (r << 16) + (g << 8) + b;


     }


     return colors;


  }


 


缺点:


此方法不能截取视频播放区域,截取的图片中的播放区域为全黑




4、系统截屏


Android4.0系统上,提供截屏功能,但截屏的方法是@hide标记的,暂不支持App端直接调用。如果要使用,需在Android源码环境下进行编译,为app赋予systemshare uidplatform签名,就可以实现截屏的功能。


关键步骤:


1)在AndroidManifest.xml中加入android:sharedUserId="android.uid.system"属性


2)在Android.mk中加入platform签名属性,并在源码环境下编译。或者将相关jar包引入到Eclipse中做第3方库引用,并将生成的apk重新打上platform签名


缺点:


源码下编译需platform签名属性,编译好的apk只有在原始的Android系统或者是自己编译的系统中才可以用,不能移植。


综上所述,要实现应用外的截屏功能,只能获取root权限,读取dev/graphics/fb0图形设备文件,目前第三方截屏应用及QQ截屏都是采取此种方法,但视频播放区域都不能截图。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值