DIRECTORY_DCIM
DIRECTORY_MUSIC
DIRECTORY_DOWNLOADS
DIRECTORY_DOCUMENTS
DIRECTORY_PICTURES等。
在Android11以上已经不能直接newFile(),Android10.0可以通过在AndroidManifest.xml application加上android:requestLegacyExternalStorage="true"还能继续访问外部存储。Android11.0开始只能将文件先存在自己的app(Android.data.com.xxx.xxx)的目录下。
所以就有需求将图片文件从沙盒拷贝到外部共享存储区域
上代码:
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
public class SaveUtils {
private static final String TAG = "SaveImagevideoUtils";
/**
* 将图片保存到系统相册
*/
public static boolean saveImgToAlbum(Context context, String imageFile) {
Log.d(TAG, "saveImgToAlbum() imageFile = [" + imageFile + "]");
try {
ContentResolver localContentResolver = context.getContentResolver();
File tempFile = new File(imageFile);
ContentValues localContentValues = getImageContentValues(tempFile, System.currentTimeMillis());
Uri uri = localContentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, localContentValues);
copyFileAfterQ(context, localContentResolver, tempFile, uri);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取图片的ContentValue
*/
public static ContentValues getImageContentValues(File paramFile, long timestamp) {
ContentValues localContentValues = new ContentValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
localContentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/Camera");
}
localContentValues.put(MediaStore.Images.Media.TITLE, paramFile.getName());
localContentValues.put(MediaStore.Images.Media.DISPLAY_NAME, paramFile.getName());
localContentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
localContentValues.put(MediaStore.Images.Media.DATE_TAKEN, timestamp);
localContentValues.put(MediaStore.Images.Media.DATE_MODIFIED, timestamp);
localContentValues.put(MediaStore.Images.Media.DATE_ADDED, timestamp);
localContentValues.put(MediaStore.Images.Media.ORIENTATION, 0);
localContentValues.put(MediaStore.Images.Media.DATA, paramFile.getAbsolutePath());
localContentValues.put(MediaStore.Images.Media.SIZE, paramFile.length());
return localContentValues;
}
/**
* 将视频保存到系统相册
*/
public static boolean saveVideoToAlbum(Context context, String videoFile) {
Log.d(TAG, "saveVideoToAlbum() videoFile = [" + videoFile + "]");
try {
ContentResolver localContentResolver = context.getContentResolver();
File tempFile = new File(videoFile);
ContentValues localContentValues = getVideoContentValues(tempFile, System.currentTimeMillis());
Uri localUri = localContentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, localContentValues);
copyFileAfterQ(context, localContentResolver, tempFile, localUri);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static void copyFileAfterQ(Context context, ContentResolver localContentResolver, File tempFile, Uri localUri) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
//拷贝文件到相册的uri,android11及以上得这么干,否则不会显示。可以参考ScreenMediaRecorder的save方法
OutputStream os = localContentResolver.openOutputStream(localUri, "w");
Files.copy(tempFile.toPath(), os);
os.close();
tempFile.deleteOnExit();
}
}
/**
* 获取视频的contentValue
*/
public static ContentValues getVideoContentValues(File paramFile, long timestamp) {
ContentValues localContentValues = new ContentValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
localContentValues.put(MediaStore.Video.Media.RELATIVE_PATH, "DCIM/Camera");
}
localContentValues.put(MediaStore.Video.Media.TITLE, paramFile.getName());
localContentValues.put(MediaStore.Video.Media.DISPLAY_NAME, paramFile.getName());
localContentValues.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
localContentValues.put(MediaStore.Video.Media.DATE_TAKEN, timestamp);
localContentValues.put(MediaStore.Video.Media.DATE_MODIFIED, timestamp);
localContentValues.put(MediaStore.Video.Media.DATE_ADDED, timestamp);
localContentValues.put(MediaStore.Video.Media.DATA, paramFile.getAbsolutePath());
localContentValues.put(MediaStore.Video.Media.SIZE, paramFile.length());
return localContentValues;
}
}
传入context和Filename,通过ContentValues进行操作其实现在基本都是用ContentValues
最后记得申请权限,后边补充
再来一个获取路径的方法,在这个路径下面进行存储等操作
if (Build.VERSION.SDK_INT < 29) {
path = Environment.getExternalStorageDirectory() + "/" + 名称;
} else {
//10以后
path = activity.getExternalFilesDir("").getAbsolutePath() + 名称;
}