package com.netease.nim.uikit.common.util.storage;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.IOException;
/** package */
class ExternalStorage {
/**
* 外部存储根目录
*/
private String sdkStorageRoot = null;
private static ExternalStorage instance;
private static final String TAG = "ExternalStorage";
private boolean hasPermission = true; // 是否拥有存储卡权限
private Context context;
private ExternalStorage() {
}
synchronized public static ExternalStorage getInstance() {
if (instance == null) {
instance = new ExternalStorage();
}
return instance;
}
public void init(Context context, String sdkStorageRoot) {
this.context = context;
// 判断权限
hasPermission = checkPermission(context);
if (!TextUtils.isEmpty(sdkStorageRoot)) {
File dir = new File(sdkStorageRoot);
if (!dir.exists()) {
dir.mkdirs();
}
if (dir.exists() && !dir.isFile()) {
this.sdkStorageRoot = sdkStorageRoot;
if (!sdkStorageRoot.endsWith("/")) {
this.sdkStorageRoot = sdkStorageRoot + "/";
}
}
}
if (TextUtils.isEmpty(this.sdkStorageRoot)) {
loadStorageState(context);
}
createSubFolders();
}
private void loadStorageState(Context context) {
String externalPath = Environment.getExternalStorageDirectory().getPath();
this.sdkStorageRoot = externalPath + "/" + context.getPackageName() + "/";
}
private void createSubFolders() {
boolean result = true;
File root = new File(sdkStorageRoot);
if (root.exists() && !root.isDirectory()) {
root.delete();
}
for (StorageType storageType : StorageType.values()) {
result &= makeDirectory(sdkStorageRoot + storageType.getStoragePath());
}
if (result) {
createNoMediaFile(sdkStorageRoot);
}
}
/**
* 创建目录
*
* @param path
* @return
*/
private boolean makeDirectory(String path) {
File file = new File(path);
boolean exist = file.exists();
if (!exist) {
exist = file.mkdirs();
}
return exist;
}
protected static String NO_MEDIA_FILE_NAME = ".nomedia";
private void createNoMediaFile(String path) {
File noMediaFile = new File(path + "/" + NO_MEDIA_FILE_NAME);
try {
if (!noMediaFile.exists()) {
noMediaFile.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 文件全名转绝对路径(写)
*
* @param fileName
* 文件全名(文件名.扩展名)
* @return 返回绝对路径信息
*/
public String getWritePath(String fileName, StorageType fileType) {
return pathForName(fileName, fileType, false, false);
}
private String pathForName(String fileName, StorageType type, boolean dir,
boolean check) {
String directory = getDirectoryByDirType(type);
StringBuilder path = new StringBuilder(directory);
if (!dir) {
path.append(fileName);
}
String pathString = path.toString();
File file = new File(pathString);
if (check) {
if (file.exists()) {
if ((dir && file.isDirectory())
|| (!dir && !file.isDirectory())) {
return pathString;
}
}
return "";
} else {
return pathString;
}
}
/**
* 返回指定类型的文件夹路径
*
* @param fileType
* @return
*/
public String getDirectoryByDirType(StorageType fileType) {
return sdkStorageRoot + fileType.getStoragePath();
}
/**
* 根据输入的文件名和类型,找到该文件的全路径。
* @param fileName
* @param fileType
* @return 如果存在该文件,返回路径,否则返回空
*/
public String getReadPath(String fileName, StorageType fileType) {
if (TextUtils.isEmpty(fileName)) {
return "";
}
return pathForName(fileName, fileType, false, true);
}
public boolean isSdkStorageReady() {
String externalRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
if (this.sdkStorageRoot.startsWith(externalRoot)) {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
} else {
return true;
}
}
/**
* 获取外置存储卡剩余空间
* @return
*/
public long getAvailableExternalSize() {
return getResidualSpace(sdkStorageRoot);
}
/**
* 获取目录剩余空间
* @param directoryPath
* @return
*/
private long getResidualSpace(String directoryPath) {
try {
StatFs sf = new StatFs(directoryPath);
long blockSize = sf.getBlockSize();
long availCount = sf.getAvailableBlocks();
long availCountByte = availCount * blockSize;
return availCountByte;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
/**
* SD卡存储权限检查
*/
private boolean checkPermission(Context context) {
if (context == null) {
Log.e(TAG, "checkMPermission context null");
return false;
}
// M permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String p1 = Manifest.permission.WRITE_EXTERNAL_STORAGE;
String p2 = Manifest.permission.READ_EXTERNAL_STORAGE;
// M 先看看有没有读写权限
if (context.checkSelfPermission(p1) != PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(p2) != PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "without permission to access storage");
return false;
}
}
return true;
}
/**
* 有效性检查
*/
public void checkStorageValid() {
if (hasPermission) {
return; // M以下版本&授权过的M版本不需要检查
}
hasPermission = checkPermission(context); // 检查是否已经获取权限了
if (hasPermission) {
Log.i(TAG, "get permission to access storage");
// 已经重新获得权限,那么重新检查一遍初始化过程
createSubFolders();
}
}
}