Android 截屏技术
虽然Android系统提供了以组合键的方式来截图,但是有时我们并不需要这么麻烦,而是想尽可能的简单的实现。基于这样的需求,前些天在开发应用时,碰到了屏幕截屏技术,没接触前以为很难,需要写各种代码,各种逻辑,接触后,发现实现关键代码就几行。但是并不满足于现状的我,很快就发现它并不能截取其他应用的界面,于是查了很多资料,还是很失望的,对手机的要求很高,要root,这大概就是市面上很多的截图应用为什么都需要root权限的原因。好吧,先写下应用内截图的几种方式吧,其实都大同小异。
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootView"
android:background="#98761f"
tools:context="com.example.screenshoot.MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/bt1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="截屏技术1111"
android:layout_below="@+id/textView1"
android:layout_marginTop="16dp" />
<Button
android:id="@+id/bt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/bt"
android:layout_below="@+id/bt1"
android:layout_marginTop="30dp"
android:text="截屏技术2222" />
<Button
android:id="@+id/bt3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/bt2"
android:layout_marginTop="33dp"
android:text="截屏技术3333" />
</RelativeLayout>
MainActivity.java
package com.example.screenshoot;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private Button bt1, bt2, bt3;
View rootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt1 = (Button) findViewById(R.id.bt1);
bt2 = (Button) findViewById(R.id.bt2);
bt3 = (Button) findViewById(R.id.bt3);
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
bt3.setOnClickListener(this);
rootView= findViewById(R.id.rootView);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt1:// View的getDrawingCache()方法
View view = this.getWindow().getDecorView();
//或者View view=v.getRootView();
view.setPressed(false);//这样就不会截取到button被按下的状态
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// 获取状态栏高度
Rect frame = new Rect();
this.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
Log.i("TAG", "" + statusBarHeight);
// 获取屏幕长和高
int width = getResources().getDisplayMetrics().widthPixels;
int height =getResources().getDisplayMetrics().heightPixels;
// 去掉标题栏
// Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
Bitmap bitmap = Bitmap.createBitmap(b1, 0, statusBarHeight, width,
height - statusBarHeight);
saveMyBitmap("noTitle", bitmap);// 去掉标题栏的
saveMyBitmap("hadTitle", b1);
view.destroyDrawingCache();
break;
case R.id.bt2:
// TODO Auto-generated method stub
Bitmap newb = Bitmap.createBitmap(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels, Config.ARGB_8888);
Canvas canvas = new Canvas(newb);
rootView.draw(canvas);
File file = new File(Environment.getExternalStorageDirectory()
+ "/" + "secondMethod.png");
FileOutputStream f = null;
try {
f = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
boolean b = newb.compress(Bitmap.CompressFormat.PNG, 100, f);
try {
f.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
f.close();
} catch (IOException e) {
e.printStackTrace();
}
if (b) {
// 截图成功
Toast.makeText(this, "截图成功", 1).show();
}
break;
case R.id.bt3:
saveMyBitmap("thirdMethod", getViewBitmap(v));;
break;
default:
break;
}
}
/**
* 保存bitmap到sd卡(本项目的file文件夹下)
*
* @param bitName
* @param mBitmap
*/
public void saveMyBitmap(String bitName, Bitmap mBitmap) {
File f = new File(getFilesDir(), bitName + ".png");
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
// DebugMessage.put("在保存图片时出错:"+e.toString());
e.printStackTrace();
}
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap getViewBitmap(View v) {
v.clearFocus(); //
v.setPressed(false); //
// 能画缓存就返回false
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
// Restore the view
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
}
其中方法一和方法三其实很类似,都是利用Android SDK的截屏方法,利用View.getDrawingCache()方法。
而方法二是利用Cavans类的draw方法画出来。
有兴趣的可以参考以下文章
http://www.cnblogs.com/tgyf/p/4851092.html
http://blog.csdn.net/woshinia/article/details/11520403
如果有大神知道不用root的方法就能实现截取其他应用的方法,还请留言给个链接。
还没有评论,来说两句吧...