最近项目中提出新需求,要求长按屏幕任何位置,出现一个圆圈,同时开始截屏,并上传到服务器。
实现思路,首先,应该自定义一个view,重写onTouch事件,根据触摸的位置,进行画圆。
接下来就是进行保存图片。
效果如图:
package cn.doolii.user.view;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import cn.doolii.usershopping.R;
import cn.doolii.usershopping.utils.dialog.CustomDialog;
//自定义绘图类
public class BallView extends View {
private Paint paint; //定义画笔
private float cx = -150; //圆点默认X坐标
private float cy = -150; //圆点默认Y坐标
private int radius = 150;
//定义颜色数组
private int colorArray[] = {Color.WHITE,Color.BLACK,Color.BLACK,Color.GREEN,Color.YELLOW, Color.RED};
private int paintColor = colorArray[0]; //定义画笔默认颜色
private int screenW; //屏幕宽度
private int screenH; //屏幕高度
Context context;
Activity ac;
private CustomDialog dialog;
CallBack callBack;
public BallView(Context context,Activity ac,CallBack callBack) {
super(context);
//初始化画笔
initPaint();
this.context=context;
this.callBack=callBack;
this.ac=ac;
}
public BallView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
initPaint();
}
public BallView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void initPaint(){
paint = new Paint();
//设置消除锯齿
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);//设置为空心
//设置画笔颜色
paint.setColor(getResources().getColor(R.color.circle));
PathEffect effects = new DashPathEffect(new float[]{5,5,5,5},1);
paint.setPathEffect(effects);
}
//重写onDraw方法实现绘图操作
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//将屏幕设置为白色
// canvas.drawColor(Color.WHITE);
//修正圆点坐标
// revise();
//随机设置画笔颜色
// setPaintRandomColor();
//绘制小圆作为小球
canvas.drawCircle(cx, cy, radius, paint);
}
private void showDialog() {
CustomDialog.Builder customBuilder = new CustomDialog.Builder(
context);
customBuilder
.setTitle("惠逛街")
.setMessage("截屏吗?")
.setNegativeButton("否",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
})
.setPositiveButton("是", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// ScreenShot.shoot(ac);
// ScreenShotMedal.loadBitmapFromView(BallView.this);
// Bitmap b= captureScreen(ac);
// saveFile(b, Environment.getExternalStorageDirectory()+”/shopping/cache/image/” + System.currentTimeMillis() + “.png”);
callBack.call(cx, cy);
dialog.dismiss();
}
});
dialog = customBuilder.create();
dialog.show();
}
public interface CallBack{
void call(float cx,float cy);
}
public void saveFile(Bitmap bitmap, String filename) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filename);
if (fileOutputStream != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap captureScreen(Activity activity) {
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
Bitmap bmp=activity.getWindow().getDecorView().getDrawingCache();
return bmp;
}
//为画笔设置随机颜色
private void setPaintRandomColor(){
Random rand = new Random();
int randomIndex = rand.nextInt(colorArray.length);
paint.setColor(colorArray[randomIndex]);
}
//修正圆点坐标
private void revise(){
if(cx <= radius){
cx = radius;
}else if(cx >= (screenW-radius)){
cx = screenW-radius;
}
if(cy <= radius){
cy = radius;
}else if(cy >= (screenH-radius)){
cy = screenH-radius;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 按下
cx = (int) event.getX();
cy = (int) event.getY();
// 通知重绘
postInvalidate(); //该方法会调用onDraw方法,重新绘图
handler.sendEmptyMessageDelayed(0, 200);// 每50毫秒发送
break;
case MotionEvent.ACTION_MOVE:
// 移动
cx = (int) event.getX();
cy = (int) event.getY();
// 通知重绘
postInvalidate();
break;
case MotionEvent.ACTION_UP:
// 抬起
cx = (int) event.getX();
cy = (int) event.getY();
// 通知重绘
postInvalidate();
break;
}
/*
* 备注1:此处一定要将return super.onTouchEvent(event)修改为return true,原因是:
* 1)父类的onTouchEvent(event)方法可能没有做任何处理,但是返回了false。
* 2)一旦返回false,在该方法中再也不会收到MotionEvent.ACTION_MOVE及MotionEvent.ACTION_UP事件。
*/
//return super.onTouchEvent(event);
return true;
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
//将触摸位置传回到 activity 然后activity截屏之前 先根据此位置 划出圆圈
callBack.call(cx, cy);
//不弹出对话框 直接截图
// showDialog();
break;
default:
break;
}
}
};
}
下面是调用截屏的方法:
public void shot(View view,final Activity ac,final Context context,final String type,final String targetId){
this.ac=ac;
this.context=context;
this.type=type;
this.targetId=targetId;
Log.i(“mkl”, targetId);
if (view instanceof ListView||view instanceof GridView|| view instanceof PullToRefreshListView|| view instanceof MyListView|| view instanceof MyGridView) {
if (null == BallPopupWindow || !BallPopupWindow.isShowing()) {
showTitle();
BallView ballView = new BallView(context, ac, new BallView.CallBack() {
@Override
public void call(float cx, float cy) {
captureScreen(ac, cx, cy);
//当点击任何地方 开始截屏时 先关掉标题 提示对话框
if (titlePopupWindow != null && !titlePopupWindow.isShowing())
titlePopupWindow.dismiss();
handler.sendEmptyMessageDelayed(0, 100);// 延迟1秒 弹出对话框
}
});
BallPopupWindow = new PopupWindow(ballView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
backgroundAlpha(0.8f);
BallPopupWindow.setOnDismissListener(new poponDismissListener());
//设置点击窗口外边窗口消失
BallPopupWindow.setOutsideTouchable(false);
// 设置此参数获得焦点,否则无法点击
BallPopupWindow.setFocusable(true);
// popupWindow.setBackgroundDrawable(new BitmapDrawable()); //comment by danielinbiti,如果添加了这行,那么标注1和标注2那两行不用加,加上这行的效果是点popupwindow的外边也能关闭
ballView.setFocusable(true);//comment by danielinbiti,设置view能够接听事件,标注1
ballView.setFocusableInTouchMode(true); //comment by danielinbiti,设置view能够接听事件 标注2
// ballView.setOnKeyListener(new View.OnKeyListener() {
// @Override
// public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
// if (arg1 == KeyEvent.KEYCODE_BACK) {
// if (BallPopupWindow != null&&BallPopupWindow.isShowing()) {
// BallPopupWindow.dismiss();
// }
// }
// return false;
// }
// });
BallPopupWindow.showAtLocation(ac.findViewById(R.id.container), Gravity.CENTER, 0, 0);
setAlpha(ac);
ac.findViewById(R.id.container).setAlpha(1f);
}
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0://延迟 弹窗
if (BallPopupWindow != null && BallPopupWindow.isShowing())
BallPopupWindow.dismiss();
showPopup();
break;
default:
break;
}
}
};
}else{
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (null == BallPopupWindow || !BallPopupWindow.isShowing()) {
showTitle();
BallView ballView = new BallView(context, ac, new BallView.CallBack() {
@Override
public void call(float cx, float cy) {
captureScreen(ac, cx, cy);
//当点击任何地方 开始截屏时 先关掉标题 提示对话框
if (titlePopupWindow!=null&&!titlePopupWindow.isShowing())
titlePopupWindow.dismiss();
handler.sendEmptyMessageDelayed(0, 100);// 延迟1秒 弹出对话框
}
});
BallPopupWindow = new PopupWindow(ballView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
backgroundAlpha(0.8f);
BallPopupWindow.setOnDismissListener(new poponDismissListener());
BallPopupWindow.showAtLocation(ac.findViewById(R.id.container), Gravity.CENTER, 0, 0);
setAlpha(ac);
ac.findViewById(R.id.container).setAlpha(1f);
}
return true;
}
});
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0://延迟 弹窗
if (BallPopupWindow!=null&&BallPopupWindow.isShowing())
BallPopupWindow.dismiss();
showPopup();
break;
default:
break;
}
}
};
}
}
/*
*
* 截屏
* */
public Bitmap captureScreen(Activity activity,float cx,float cy) {
//View组件显示的内容可以通过cache机制保存为bitmap
// cache开启
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
//将view转为bitmap 然后将bitmap封装到画布中 开始画画
bmp=activity.getWindow().getDecorView().getDrawingCache();
Canvas canvas = new Canvas(bmp);
canvas.drawColor(getResources().getColor(R.color.trans));
Paint paint = new Paint();
//设置消除锯齿
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);//设置为空心
paint.setColor(getResources().getColor(R.color.circle));
PathEffect effects = new DashPathEffect(new float[]{5,5,5,5},1);
paint.setPathEffect(effects);
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
Log.i(“statusBarHeight—-“, statusBarHeight + “”);
canvas.drawCircle(cx, cy+statusBarHeight, 150, paint);
//保存到本地 便于后期上传图片
saveFile(bmp, Environment.getExternalStorageDirectory() + "/usershopping/cache/screenshot.png");
//开子线程压缩图片
new Thread(new Runnable() {
@Override
public void run() {
bmp= ImageTools.convertToBitmap(Environment.getExternalStorageDirectory() + "/usershopping/cache/screenshot.png", 600, 600);//根据路径获取 宽为600 高为600的图片
//保存到本地 便于后期上传图片
saveFile(bmp, Environment.getExternalStorageDirectory() + "/user/cache/screenshot.png");
}
}).start();
//清除 cache
activity.getWindow().getDecorView().destroyDrawingCache();
return bmp;
}
public void saveFile(Bitmap bitmap, String filename) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filename);
if (fileOutputStream != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
代码下载地址:
http://download.csdn.net/download/lzq520210/9659683