重点关于android 12的sd卡读写以及Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)的使用
首先要有对sd卡读写的权限 android 12 申请权限大全
<uses-permission android:name="android.permission.INTERNET" /> <!-- 网络权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 允许访问SD卡的权限 -->
<!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" /> <!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 读取网络状态 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
然后需要在AndroidManifest.xml文件中<application 加入
android:requestLegacyExternalStorage=“true”
其次在activity中动态申请权限
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted, request it
int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
} else {
// Permission has already been granted, read the file
video = ImageSaverUtil.readImageFromSDCard("video");
}
}
package com.example.zhuoyuadvert.utils;
import static org.greenrobot.eventbus.EventBus.TAG;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
public class ImageSaverUtil {
private static ReentrantLock lock = new ReentrantLock();
// 写入sd卡需要保证线程使用
public static void saveImageToInternalStorage(Context context, List<String> imageUrl, String folderName, String name) {
new Thread(() -> {
lock.lock();
String savedImagePath = null;
if (Build.VERSION.SDK_INT >= 29) {
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), folderName);
if (!folder.exists()) {
folder.mkdirs();
} else {
deleteFiles(folder);
}
for (int i = 0; i < imageUrl.size(); i++) {
try {
// Get the input stream from the URL
InputStream inputStream = new URL(imageUrl.get(i)).openStream();
// Create a request to save the image to the app's internal storage
File imageFile = new File(folder, folderName + System.currentTimeMillis() + name);
OutputStream outputStream = new FileOutputStream(imageFile);
// Copy the image from the input stream to the output stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// Close the streams
outputStream.close();
inputStream.close();
savedImagePath = imageFile.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
}
// Use the Scoped Storage APIs on Android 12 and higher
Log.d("ImageSaver", "Saved image to path: " + savedImagePath);
}
lock.unlock();
}).start();
}
//每次写入前有需要可以先把文件清空
private static boolean deleteFiles(File file) {
try {
if (file.isDirectory()) {
//判断是否是文件夹
File[] files = file.listFiles();//遍历文件夹里面的所有的
for (int i = 0; i < files.length; i++) {
Log.e(TAG, "删除文件>>>>>> " + files[i].toString());
deleteFiles(files[i]); //删除
}
} else {
boolean delete = file.delete();
System.out.println(delete);
}
System.gc();//系统回收垃圾
return true;
} catch (Exception e) {
Log.e(TAG, "删除报错!!!: " + e.toString());
return false;
}
}
//读取sd卡内容
public static List<String> readImageFromSDCard( String folderName) {
List<String> bitmaps = new ArrayList<>();
try {
// Get path
// Create a request to save the image to the app's internal storage
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), folderName);
File[] files = folder.listFiles();
List<String> imagePaths = new ArrayList<>();
if (files != null) {
for (int i = 0; i < files.length; i++) {
imagePaths.add(files[i].getPath());
File imageFile = new File(files[i].getPath());
//Bitmap image = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
bitmaps.add(imageFile.getAbsolutePath());
}
}
return bitmaps;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}