我是靠谱客的博主 要减肥水蜜桃,这篇文章主要介绍Android - 分享功能,截图并保存图片到本地相册(适配小米,现在分享给大家,希望可以做个参考。

分享需求:生成二维码,并拼接部分截图到分享弹窗。点击保存按钮则保存图片到本地。

步骤:创建弹窗 -> 生成二维码- > 拿到并拼接截图-展示 -> 获取读写权限 -> 保存bitmap到本地
![分享弹窗布局](https://img-blog.csdnimg.cn/92f9d0754a0e4ed0bb20a840b55bc35c.pn

0. 创建弹窗

dialog_share_live.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_pic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white">
<ImageView
android:id="@+id/iv_code"
android:layout_width="35dp"
android:layout_height="35dp"/>
<ImageView
android:id="@+id/iv_screen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"/>
</LinearLayout>
<TextView
android:id="@+id/tv_save"
android:layout_width="80dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="@string/save"
android:textSize="14dp"
android:textColor="@color/white"
android:background="@drawable/shape_dc3c23_23dp_rec"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"/>
</RelativeLayout>/>

avtivity.java

	private Bitmap shareQRCodeBitmap;
private AlertDialog shareDialog;
private Bitmap picBitmap;
private View view1;
private ImageView ivScreen;
private LinearLayout ll_pic;
private void shareScreen(){
view1 = mActivity.getLayoutInflater().inflate(R.layout.dialog_share_live,null);
ImageView ivCode = view1.findViewById(R.id.iv_code);//二维码
ivScreen = view1.findViewById(R.id.iv_screen);//截图
ll_pic = view1.findViewById(R.id.ll_pic);//需要下载的部分
//生成二维码
......
if(shareDialog == null){
shareDialog = new AlertDialog.Builder(mActivity).setView(view1).create();
shareDialog.setCancelable(true);
shareDialog.setCanceledOnTouchOutside(true);
}
//拼接截图
......
//展示弹窗
shareDialog.setView(view1);
shareDialog.show();
DisplayMetrics dm = new DisplayMetrics();
mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Window w = shareDialog.getWindow();
w.setLayout((int) (dm.widthPixels * 0.9), ViewGroup.LayoutParams.WRAP_CONTENT);
w.findViewById(R.id.tv_save).setOnClickListener(v -> {
//保存图片
......
});
w.findViewById(R.id.ll_pic).setOnClickListener(v->{
shareDialog.dismiss();
});
}
//请求权限的回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 10004:
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
//是否狠狠拒绝
boolean flag = ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i]);
ToastUtil.show(getString(flag?"Go to Settings to enable file storage permissions":"Please grant file storage permission first"));
return;
}
}
saveBitmapFile(mActivity,picBitmap);
break;
default:
break;
}
}

1. 生成二维码

  1. 导入依赖:
implementation 'com.google.zxing:core:3.3.0'
  1. 创建工具方法:UIUtil.java
	/**
* 根据地址生成二维码图片
*/
public static Bitmap createQrCode(String url,final int width,final int height) {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, String> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 0+"");//去除白边
try {
BitMatrix encode = qrCodeWriter.encode(url, BarcodeFormat.QR_CODE, width, height, hints);
int[] pixels = new int[width * height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (encode.get(j, i)) {
pixels[i * width + j] = 0x00000000;
} else {
pixels[i * width + j] = 0xffffffff;
}
}
}
Bitmap bitmap=Bitmap.createBitmap(width,height, Bitmap.Config.RGB_565);
bitmap.setPixels(pixels,0,width,0,0,width,height);
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
  1. 生成二维码:activity.java
 private void shareScreen(){
......
//生成二维码
if(shareQRCodeBitmap == null){
shareQRCodeBitmap = createQrCode(SHARE_LIVE_URL,UIUtil.dip2px(mActivity,35),UIUtil.dip2px(mActivity,35));
}
ivCode.setImageBitmap(shareQRCodeBitmap);
......
}

2. 截图

找到需要截图的容器:ll_main

 private void shareScreen(){
......
//拼接截图
//这种截图方式有缓存,且短视频和直播源画面空白,我们是用封面替代
ll_main.setDrawingCacheEnabled(true);
Bitmap bitmap = ll_main.getDrawingCache();
ivScreen.setImageBitmap(bitmap);
......
}

3. 保存图片到本地

  1. 创建工具方法 保存图片:UiUtils.java (可直接看最终法)

方式一:现有测试机里华为、魅族都ok,谷歌和小米不行,且无报错信息o(╥﹏╥)o

public static File saveBitmapFile(Activity activity,Bitmap bit) {
//先判断权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 10004);
return null;
}
}
if(bit == null){
return null;
}
if (bit.isRecycled()) {
return null;
}
String path = Environment.getExternalStorageDirectory().getPath();
if (Build.VERSION.SDK_INT > 29) {
path = activity.getExternalFilesDir(null).getAbsolutePath() ;
}
File file = new File(path, "share_live_"+System.currentTimeMillis()+".jpg");
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
//压缩Bitmap,不支持png图片的压缩
bit.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
// 把文件插入到系统图库
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
// 通知图库更新
activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
ToastUtil.show(activity.getString(R.string.save_success));
return file;
} catch (IOException e) {
e.printStackTrace();
ToastUtil.show(activity.getString(R.string.save_failed));
}
return null;
}

方式二:换个访问路径,谷歌行,小米不行,报错:ENOENT (No such file or directory)

ERROR FileNotFoundException:/storage/emulated/0/Android/data/com.xxx.live/files/DCIM/Camera、share_live_1677650698438.jpg: open failed: ENOENT (No such file or directory)

public static File saveBitmapFile(Activity activity,Bitmap bit) {
//先判断权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 10004);
return null;
}
}
if(bit == null){
return null;
}
if (bit.isRecycled()) {
return null;
}
String path = Environment.getExternalStorageDirectory().getPath();// Meizu 、Oppo
//1.路径
if (Build.BRAND.equals("Xiaomi")) { // 小米手机brand.equals("xiaomi")
path = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" ;
} else if (Build.BRAND.equalsIgnoreCase("Huawei")) {
path = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" ;
}
File file = new File(path, "share_live_"+System.currentTimeMillis()+".jpg");
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
//压缩Bitmap,不支持png图片的压缩,PNG格式的不能显示在相册中
bit.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
// 把文件插入到系统图库
if(Build.VERSION.SDK_INT >= 29){
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}else{
MediaStore.Images.Media.insertImage(activity.getContentResolver(), file.getAbsolutePath(), "", null);
}
// 通知图库更新
activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
ToastUtil.show(activity.getString(R.string.save_success));
return file;
}catch (FileNotFoundException e) {
e.printStackTrace();
ToastUtil.show(activity.getString(R.string.save_failed));
} catch (IOException e) {
e.printStackTrace();
ToastUtil.show(activity.getString(R.string.save_failed));
} catch (Exception e) {
e.printStackTrace();
ToastUtil.show(activity.getString(R.string.save_failed));
}
return null;
}

最终法:插入一张图片到图库中,再刷新 都通过(用这个就行)

public static File saveBitmapFile(Activity activity,Bitmap bit) {
//先判断权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 10004);
return null;
}
}
if(bit == null){
return null;
}
if (bit.isRecycled()) {
return null;
}
try {
String result = MediaStore.Images.Media.insertImage(activity.getContentResolver(), bit, "share_live_"+System.currentTimeMillis()+".jpeg", "share_live");
Intent scannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(result));
activity.sendBroadcast(scannerIntent);
ToastUtil.show(activity.getString(R.string.save_success));
}catch (Exception e) {
Log.e("Exception", "ltt saveBitmapFile0 Exception:" + e.getMessage().toString());
e.printStackTrace();
ToastUtil.show(activity.getString(R.string.save_failed));
}
return null;
}

虽然还是不知道为啥用前面两种方法小米会找不到路径,先记录下来…

  1. 获取bitmap对象,需要保存的是ll_pic,不需要按钮
 private void shareScreen(){
......
//保存图片
if(picBitmap==null){
picBitmap = convertViewToBitmap(ll_pic);
}
if(saveBitmapFile(mActivity,picBitmap)!=null){
shareDialog.dismiss();
}
.......
}

UIUtils.java

	/**
* 获取view的Bitmap
*/
public static Bitmap convertViewToBitmap(View view){
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}

ok结束


另外增加需求:系统分享图片到第三方

将图片保存在缓存中,再分享出去。

  1. UIUtils.java
	/**
* 保存图片到缓存
*/
public static String saveTitmapToCache(Context context , Bitmap bitmap){
// 默认保存在应用缓存目录里 Context.getCacheDir()
File file=new File(context.getCacheDir(),System.currentTimeMillis()+".png");
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bos);
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return file.getPath();
}
/**
* 调用系统分享图片
*/
public static boolean sharePictureFile(Activity activity, Bitmap bitmap) {
//先判断权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 10005);
return false;
}
}
//压缩前要防止 Can’t compress a recycled bitmap
if (bitmap.isRecycled()) {
return false;
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
//
Bitmap bitmap = Bitmap.createBitmap(((BitmapDrawable) context.getDrawable(R.mipmap.xxx)).getBitmap());
String imgpath = saveTitmapToCache(getApplicationContext(), bitmap);
if(!TextUtils.isEmpty(imgpath)){
Uri uri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileProvider", new File(imgpath));
intent.setDataAndType(uri, "image/*");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/*");
activity.startActivity(Intent.createChooser(intent, "Share to..."));
}
return true;
}
  1. activiity.java
	w.findViewById(R.id.tv_share).setOnClickListener(v -> {
//分享到第三方
if(picBitmap==null){
picBitmap = convertViewToBitmap(ll_pic);
}
if(sharePictureFile(mActivity,picBitmap)){
shareDialog.dismiss();
}
});

另外增加需求:系统分享链接(文本)到第三方

activity.java

	w.findViewById(R.id.tv_url).setOnClickListener(v -> {
//分享链接
ShareUtil.shareText(mActivity,"",);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "分享链接");
context.startActivity(Intent.createChooser(intent, "title"));
});

ok,三种分享方式都做完了(分享图片、文字到第三方、保存图片)

最后

以上就是要减肥水蜜桃最近收集整理的关于Android - 分享功能,截图并保存图片到本地相册(适配小米的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部