Android 截屏技术

忘是亡心i 2022-07-24 06:17 300阅读 0赞

虽然Android系统提供了以组合键的方式来截图,但是有时我们并不需要这么麻烦,而是想尽可能的简单的实现。基于这样的需求,前些天在开发应用时,碰到了屏幕截屏技术,没接触前以为很难,需要写各种代码,各种逻辑,接触后,发现实现关键代码就几行。但是并不满足于现状的我,很快就发现它并不能截取其他应用的界面,于是查了很多资料,还是很失望的,对手机的要求很高,要root,这大概就是市面上很多的截图应用为什么都需要root权限的原因。好吧,先写下应用内截图的几种方式吧,其实都大同小异。

activity_main.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:id="@+id/rootView"
  6. android:background="#98761f"
  7. tools:context="com.example.screenshoot.MainActivity" >
  8. <TextView
  9. android:id="@+id/textView1"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:text="@string/hello_world" />
  13. <Button
  14. android:id="@+id/bt1"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:layout_alignParentLeft="true"
  18. android:text="截屏技术1111"
  19. android:layout_below="@+id/textView1"
  20. android:layout_marginTop="16dp" />
  21. <Button
  22. android:id="@+id/bt2"
  23. android:layout_width="match_parent"
  24. android:layout_height="wrap_content"
  25. android:layout_alignLeft="@+id/bt"
  26. android:layout_below="@+id/bt1"
  27. android:layout_marginTop="30dp"
  28. android:text="截屏技术2222" />
  29. <Button
  30. android:id="@+id/bt3"
  31. android:layout_width="match_parent"
  32. android:layout_height="wrap_content"
  33. android:layout_alignParentLeft="true"
  34. android:layout_below="@+id/bt2"
  35. android:layout_marginTop="33dp"
  36. android:text="截屏技术3333" />
  37. </RelativeLayout>

MainActivity.java

  1. package com.example.screenshoot;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import android.app.Activity;
  7. import android.content.Context;
  8. import android.graphics.Bitmap;
  9. import android.graphics.Bitmap.Config;
  10. import android.graphics.Canvas;
  11. import android.graphics.Rect;
  12. import android.os.Bundle;
  13. import android.os.Environment;
  14. import android.util.Log;
  15. import android.view.View;
  16. import android.view.View.OnClickListener;
  17. import android.widget.Button;
  18. import android.widget.Toast;
  19. public class MainActivity extends Activity implements OnClickListener {
  20. private Button bt1, bt2, bt3;
  21. View rootView;
  22. @Override
  23. protected void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.activity_main);
  26. bt1 = (Button) findViewById(R.id.bt1);
  27. bt2 = (Button) findViewById(R.id.bt2);
  28. bt3 = (Button) findViewById(R.id.bt3);
  29. bt1.setOnClickListener(this);
  30. bt2.setOnClickListener(this);
  31. bt3.setOnClickListener(this);
  32. rootView= findViewById(R.id.rootView);
  33. }
  34. @Override
  35. public void onClick(View v) {
  36. switch (v.getId()) {
  37. case R.id.bt1:// View的getDrawingCache()方法
  38. View view = this.getWindow().getDecorView();
  39. //或者View view=v.getRootView();
  40. view.setPressed(false);//这样就不会截取到button被按下的状态
  41. view.setDrawingCacheEnabled(true);
  42. view.buildDrawingCache();
  43. Bitmap b1 = view.getDrawingCache();
  44. // 获取状态栏高度
  45. Rect frame = new Rect();
  46. this.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
  47. int statusBarHeight = frame.top;
  48. Log.i("TAG", "" + statusBarHeight);
  49. // 获取屏幕长和高
  50. int width = getResources().getDisplayMetrics().widthPixels;
  51. int height =getResources().getDisplayMetrics().heightPixels;
  52. // 去掉标题栏
  53. // Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
  54. Bitmap bitmap = Bitmap.createBitmap(b1, 0, statusBarHeight, width,
  55. height - statusBarHeight);
  56. saveMyBitmap("noTitle", bitmap);// 去掉标题栏的
  57. saveMyBitmap("hadTitle", b1);
  58. view.destroyDrawingCache();
  59. break;
  60. case R.id.bt2:
  61. // TODO Auto-generated method stub
  62. Bitmap newb = Bitmap.createBitmap(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels, Config.ARGB_8888);
  63. Canvas canvas = new Canvas(newb);
  64. rootView.draw(canvas);
  65. File file = new File(Environment.getExternalStorageDirectory()
  66. + "/" + "secondMethod.png");
  67. FileOutputStream f = null;
  68. try {
  69. f = new FileOutputStream(file);
  70. } catch (FileNotFoundException e) {
  71. // TODO Auto-generated catch block
  72. e.printStackTrace();
  73. }
  74. boolean b = newb.compress(Bitmap.CompressFormat.PNG, 100, f);
  75. try {
  76. f.flush();
  77. } catch (IOException e) {
  78. e.printStackTrace();
  79. }
  80. try {
  81. f.close();
  82. } catch (IOException e) {
  83. e.printStackTrace();
  84. }
  85. if (b) {
  86. // 截图成功
  87. Toast.makeText(this, "截图成功", 1).show();
  88. }
  89. break;
  90. case R.id.bt3:
  91. saveMyBitmap("thirdMethod", getViewBitmap(v));;
  92. break;
  93. default:
  94. break;
  95. }
  96. }
  97. /**
  98. * 保存bitmap到sd卡(本项目的file文件夹下)
  99. *
  100. * @param bitName
  101. * @param mBitmap
  102. */
  103. public void saveMyBitmap(String bitName, Bitmap mBitmap) {
  104. File f = new File(getFilesDir(), bitName + ".png");
  105. try {
  106. f.createNewFile();
  107. } catch (IOException e) {
  108. // TODO Auto-generated catch block
  109. // DebugMessage.put("在保存图片时出错:"+e.toString());
  110. e.printStackTrace();
  111. }
  112. FileOutputStream fOut = null;
  113. try {
  114. fOut = new FileOutputStream(f);
  115. } catch (FileNotFoundException e) {
  116. e.printStackTrace();
  117. }
  118. mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
  119. try {
  120. fOut.flush();
  121. } catch (IOException e) {
  122. e.printStackTrace();
  123. }
  124. try {
  125. fOut.close();
  126. } catch (IOException e) {
  127. e.printStackTrace();
  128. }
  129. }
  130. public static Bitmap getViewBitmap(View v) {
  131. v.clearFocus(); //
  132. v.setPressed(false); //
  133. // 能画缓存就返回false
  134. boolean willNotCache = v.willNotCacheDrawing();
  135. v.setWillNotCacheDrawing(false);
  136. int color = v.getDrawingCacheBackgroundColor();
  137. v.setDrawingCacheBackgroundColor(0);
  138. if (color != 0) {
  139. v.destroyDrawingCache();
  140. }
  141. v.buildDrawingCache();
  142. Bitmap cacheBitmap = v.getDrawingCache();
  143. if (cacheBitmap == null) {
  144. return null;
  145. }
  146. Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
  147. // Restore the view
  148. v.destroyDrawingCache();
  149. v.setWillNotCacheDrawing(willNotCache);
  150. v.setDrawingCacheBackgroundColor(color);
  151. return bitmap;
  152. }
  153. }

其中方法一和方法三其实很类似,都是利用Android SDK的截屏方法,利用View.getDrawingCache()方法。

而方法二是利用Cavans类的draw方法画出来。

有兴趣的可以参考以下文章

http://www.cnblogs.com/tgyf/p/4851092.html

http://blog.csdn.net/woshinia/article/details/11520403

如果有大神知道不用root的方法就能实现截取其他应用的方法,还请留言给个链接。

发表评论

表情:
评论列表 (有 0 条评论,300人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Android的几种实现

    Android截屏的几种实现 最近我们的APP要求需要截屏功能,网上看了看大致有一下几种实现的方式,由于我们的机器是特定的设备,(类似于广告机,已经ROOT),所以就...

    相关 Android 技术

    虽然Android系统提供了以组合键的方式来截图,但是有时我们并不需要这么麻烦,而是想尽可能的简单的实现。基于这样的需求,前些天在开发应用时,碰到了屏幕截屏技术,没接触前以为很