现在有一个需求是要求截屏,下载自己二维码,拼接图片,在分享,截屏俩种方式,代码如下。如有疑问(993987402)
private JointBitmap view;
private ImageView mView;
// 加载成功
private static final int LOAD_SUCCESS = 1;
// 加载失败
private static final int LOAD_ERROR = -1;
// 用于异步的显示图片
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
//下载成功
case 1:
// 获取图片的文件对象
File file = new File(Environment.getExternalStorageDirectory(), "pic.jpg");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(fis);
// image.setImageBitmap(bitmap);
setNewBimap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
//下载失败
case 0:
Log.d("TAG","失败了");
Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permissionHelper = PermissionHelper.getInstance(this);
mView= (ImageView) findViewById(R.id.image_view);
findViewById(R.id.main_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setPermission();
}
});
}
/**
* 请求权限
*/
private void setPermission(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//请求权限
setPommisions();
view();
}else{
//不需要
permissionsAllowed();
}
}
/**
* 请求权限
*/
private void setPommisions(){
//setForceAccepting 是否强制让用户接受权限
permissionHelper.setForceAccepting(false).request(PERMISSIONS_STORAGE);
}
/**
* 权限申请
*/
private PermissionHelper permissionHelper;
public String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};
/**
* 不用申请权限(6.0权限以下)
*/
private void permissionsAllowed(){
view();
}
/**
* 获取权限返回是否通过
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
permissionHelper.onActivityForResult(requestCode);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
permissionHelper.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
/**
* 下面是所有的定义的接口类的方法。
* @param permissionName
* 第一个是代表不用申请权限许可的
*/
@Override
public void onPermissionGranted(@NonNull String[] permissionName) {
permissionsAllowed();
}
@Override
public void onPermissionPreGranted(@NonNull String permissionsName) {
permissionsAllowed();
}
/**
* 关于权限被拒绝(拒绝的时候再次 申请)
* @param permissionName
*/
@Override
public void onPermissionDeclined(@NonNull String[] permissionName) {
}
/**
* 许可需要说明
* @param permissionName
*/
@Override
public void onPermissionNeedExplanation(@NonNull String permissionName) {
}
/**
* 在权限上被拒绝
* @param permissionName
*/
@Override
public void onPermissionReallyDeclined(@NonNull String permissionName) {
}
/**
* 不限制权限
*/
@Override
public void onNoPermissionNeeded() {
}
/**
* 截屏显示
*/
private Bitmap screenshot() {
// 获取屏幕
View dView = getWindow().getDecorView();
dView.setDrawingCacheEnabled(true);
dView.buildDrawingCache();
Bitmap bmp = dView.getDrawingCache();
if (bmp != null) {
try {
// 获取内置SD卡路径
String sdCardPath = Environment.getExternalStorageDirectory().getPath();
// 图片文件路径
String filePath = sdCardPath + File.separator + "screenshot.png";
File file = new File(filePath);
FileOutputStream os = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
}
}
return bmp;
}
/**
* 组合图片拼接
* @param bit2
*/
private void setNewBimap(Bitmap bit2){
Bitmap bm =screenshot();
// 将图片显示到ImageView中
view = new JointBitmap(this, bm, bit2);
Bitmap bitmap = view.newBitmap(bm, bit2);//imageView_joint
if (bitmap != null) {
try {
// 获取内置SD卡路径
String sdCardPath = Environment.getExternalStorageDirectory().getPath();
// 图片文件路径
String filePath = sdCardPath + File.separator + "sharepicure.png";
File file = new File(filePath);
FileOutputStream os = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
}
}
mView.setImageBitmap(bitmap);
}
/**
* 点击下载图片
*/
public void view(){
// 开启新的线程用于下载图片
new Thread(new Runnable() {
public void run() {
getPicture();
}
}).start();
}
//下载图片的主方法
private void getPicture() {
URL url = null;
InputStream is = null;
FileOutputStream fos = null;
try {
//构建图片的url地址
url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504262170401&di=e8bcb963760c37dc7fd5ddee48cb40cd&imgtype=0&src=http%3A%2F%2Fwww.zhlzw.com%2FUploadFiles%2FArticle_UploadFiles%2F201204%2F20120412123921838.jpg");
//开启连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置超时的时间,5000毫秒即5秒
conn.setConnectTimeout(5000);
//设置获取图片的方式为GET
conn.setRequestMethod("GET");
//响应码为200,则访问成功
if (conn.getResponseCode() == 200) {
//获取连接的输入流,这个输入流就是图片的输入流
is = conn.getInputStream();
//构建一个file对象用于存储图片
File file = new File(Environment.getExternalStorageDirectory(), "pic.jpg");
fos = new FileOutputStream(file);
int len = 0;
byte[] buffer = new byte[1024];
//将输入流写入到我们定义好的文件中
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
//将缓冲刷入文件
fos.flush();
//告诉handler,图片已经下载成功
mHandler.sendEmptyMessage(1);
}
} catch (Exception e) {
//告诉handler,图片已经下载失败
mHandler.sendEmptyMessage(0);
e.printStackTrace();
} finally {
//在最后,将各种流关闭
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (Exception e) {
mHandler.sendEmptyMessage(0);
e.printStackTrace();
}
}
}这个事拼接图片;
private Bitmap bitmap;
public JointBitmap(Context context, Bitmap bit1, Bitmap bit2) {
super(context);
// bitmap = newBitmap(bit1,bit2);
}
/**
* 拼接图片
*
* @param bit1
* @param bit2
* @return 返回拼接后的Bitmap
*/
public Bitmap newBitmap(Bitmap bit1, Bitmap bit2) {
int width = bit1.getWidth();
int height = bit1.getHeight() + bit2.getHeight();
//创建一个空的Bitmap(内存区域),宽度等于第一张图片的宽度,高度等于两张图片高度总和
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
//将bitmap放置到绘制区域,并将要拼接的图片绘制到指定内存区域
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bit1, 0, 0, null);
canvas.drawBitmap(bit2, 0, bit1.getHeight(), null);
return bitmap;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, 0, 0, null);
bitmap.recycle();
}
public JointBitmap(Context context) {
super(context);
}
public JointBitmap(Context context, AttributeSet attrs) {
super(context, attrs);
}
public JointBitmap(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}5.0以上截屏大家都这么做。
private static final String TAG ="otouzi";
private static final int REQUEST_CODE = 100;
private static String STORE_DIRECTORY;
private static int IMAGES_PRODUCED;
private static final String SCREENCAP_NAME = "screencap";
private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private static MediaProjection sMediaProjection;
private MediaProjectionManager mProjectionManager;
private ImageReader mImageReader;
private Handler mHandler;
private Display mDisplay;//显示
private VirtualDisplay mVirtualDisplay;
private int mDensity;
private int mWidth;
private int mHeight;
private int mRotation;
private OrientationChangeCallback mOrientationChangeCallback;
private String path;
private ImageView imageView;
private ImageView text_imageView2;
private Bitmap mBitmap;//ImageLoate本地的图片
private Handler mHandlerWolder=new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what==1){
setImageview();
}
}
};
/****************************************** Activity Lifecycle methods ************************/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testview);
/**
* 系统向用户请求屏幕录制的相关权限,首先获取MediaProjectionManager,
* 和其他的Manager一样通过 Context.getSystemService() 传入参数MEDIA_PROJECTION_SERVICE获得实例。
*/
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
imageView= (ImageView) findViewById(R.id.text_imageView);
text_imageView2= (ImageView) findViewById(R.id.text_imageView2);
// 开始
Button startButton = (Button)findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startProjection();
}
});
// stop projection
Button stopButton = (Button)findViewById(R.id.stopButton);
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopProjection();
}
});
String mImageViewPath="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1503047905115&di=624821829abdf2761d3c276834a6366e&imgtype=0" +
"&src=http%3A%2F%2Fwww.zhlzw.com%2FUploadFiles%2FArticle_UploadFiles%2F201204%2F20120412123914329.jpg";
// mBitmap=ImageLoader.getInstance().loadImageSync(mImageViewPath);
// start capture handling thread
new Thread() {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}.start();
}
/**
* 设置图片
*/
private boolean mFlag=false;
private void setImageview(){
boolean isSdCardExist = Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);// 判断sdcard是否存在
if (isSdCardExist) {
// textView1.setText("sd卡是存在的。以下是sdcard下的img25.jpg!");File.separator
String filepath = STORE_DIRECTORY +"/myscreen_" + IMAGES_PRODUCED + ".png";
File file = new File(filepath);
if (file.exists()) {
Bitmap bm = BitmapFactory.decodeFile(filepath);
// 将图片显示到ImageView中
/**
* 这里使用BitmapFactory.decodeStream(InputStream is);方法加载图片可以有效的防止
* 当内存过大时出现内存溢出的情况
*/
if (mFlag=true){
imageView.setImageBitmap(bm);
}
}
} else {
// textView1.setText("sd卡不存在!");
}
}
/**
* 截图成功保存成bitmap
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
FileOutputStream fos = null;
Bitmap bitmap = null;
try {
image = mImageReader.acquireLatestImage();
if (image != null) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * mWidth;
bitmap=takeScreenShot(TestActivity.this,mWidth + rowPadding / pixelStride);//修改的
// create bitmap原来的
//bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
// write bitmap to a file
fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
stopProjection();
//IMAGES_PRODUCED++;
Log.e(TAG, "captured image: " + IMAGES_PRODUCED);
mHandlerWolder.sendEmptyMessage(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos!=null) {
try {
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (bitmap!=null) {
bitmap.recycle();
}
if (image!=null) {
image.close();
}
}
}
}
/**
* 去掉标题栏
*/
public static Bitmap takeScreenShot(Activity activity, int mWidth) {
// View是你需要截图的View
View view = activity.getWindow().getDecorView();
// view.setDrawingCacheEnabled(true);
view.setDrawingCacheEnabled(false);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// 获取状态栏高度
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
// 获取屏幕长和高
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
//用bitmap的高度,不用屏幕的高度,不然有可能报错,因为有的手机(魅族手机)底部有占高度
height=b1.getHeight();
// 去掉标题栏
// Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
Bitmap b = Bitmap.createBitmap(mWidth, height-statusBarHeight-100, Bitmap.Config.ARGB_8888);
view.destroyDrawingCache();
return b;
}
private class OrientationChangeCallback extends OrientationEventListener {
public OrientationChangeCallback(Context context) {
super(context);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public void onOrientationChanged(int orientation) {
synchronized (this) {
final int rotation = mDisplay.getRotation();
if (rotation != mRotation) {
mRotation = rotation;
try {
// clean up
if(mVirtualDisplay != null) mVirtualDisplay.release();
if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
// re-create virtual display depending on device width / height
createVirtualDisplay();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 截屏改变方向
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private class MediaProjectionStopCallback extends MediaProjection.Callback {
@Override
public void onStop() {
Log.e("ScreenCapture", "stopping projection.");
mHandler.post(new Runnable() {
@Override
public void run() {
if(mVirtualDisplay != null) mVirtualDisplay.release();
if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
if(mOrientationChangeCallback != null) mOrientationChangeCallback.disable();
sMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);
}
});
}
}
/**
* 如果授权成功,通过MediaProjectionManager.getMediaProjection(int resultCode, Intent resultData)
* 获取MediaProjection实例,通过MediaProjection.createVirtualDisplay(String name, int width, int height, int dpi, int flags, Surface surface,
* VirtualDisplay.Callback callback, Handler handler)
* 创建VirtualDisplay实例。实际上在上述方法中传入的surface参数,是真正用来截屏或者录屏的。
* @param data
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);//主要的类获取这个类
if (sMediaProjection != null) {
STORE_DIRECTORY = Environment.getExternalStorageDirectory().getAbsolutePath() + "/screenshots/";//内存卡地址
File storeDirectory = new File(STORE_DIRECTORY);
if (!storeDirectory.exists()) {
boolean success = storeDirectory.mkdirs();
if(!success) {
Log.e(TAG, "failed to create file storage directory.");
return;
}else {
Log.e(TAG,"成功");
}
}
//获取屏幕大小等
DisplayMetrics metrics = getResources().getDisplayMetrics();
mDensity = metrics.densityDpi;
mDisplay = getWindowManager().getDefaultDisplay();
//设置宽高
createVirtualDisplay();
/**
*截屏顺序,改变回调
*/
mOrientationChangeCallback = new OrientationChangeCallback(this);
if (mOrientationChangeCallback.canDetectOrientation()) {
mOrientationChangeCallback.enable();
}
// 截屏开始,注册回调接口
sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);
}
}
}
/**
* 第二部
* 接着调用MediaProjectionManager.createScreenCaptureIntent()弹出dialog询问用户是否授权应用捕捉屏幕,
* 同时覆写onActivityResult()获取授权结果
* **/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void startProjection() {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
}
/**
* 停止
*/
private void stopProjection() {
mHandler.post(new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
if (sMediaProjection != null) {
sMediaProjection.stop();
}
}
});
}
/**
* 宽高显示截屏大小
* 截屏这里用到ImageReader类,这个类的getSurface()方法获取到surface直接传入MediaProjection.createVirtualDisplay()方法中,
* 此时就可以执行截取。通过ImageReader.acquireLatestImage()方法即可获取当前屏幕的Image,经过简单处理之后即可保存为Bitmap。
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void createVirtualDisplay() {
// get width and height
Point size = new Point();
mDisplay.getSize(size);
mWidth = size.x;
mHeight = size.y;
//创建截取类
mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
//编译器
mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
//回调
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
}
}
随时随地看视频