Android的文件切割和合并,补全wav文件头

示例:

1、普通文件的拆分与合并:

 private void testFile() {File mWavFile = new File(getExternalFilesDir(null).getAbsolutePath() + "/test.wav");if (!mWavFile.exists()){Log.d("caowj", "文件不存在:" + mWavFile.getAbsolutePath());return;}List wavFileList = FileSplitUtils.fileSplit(mWavFile,getExternalFilesDir(null).getAbsolutePath(), 8 * 1024 * 1024);Log.d("caowj", "切割数量:" + wavFileList.size());File file2 = new File(getExternalFilesDir(null).getAbsolutePath() + "/1.wav");if(file2.exists()){List<File> list = new ArrayList<>();File file1 = new File(getExternalFilesDir(null).getAbsolutePath() + "/0.wav");File file3 = new File(getExternalFilesDir(null).getAbsolutePath() + "/2.wav");list.add(file1);list.add(file2);list.add(file3);File mergedFile = new File(getExternalFilesDir(null).getAbsolutePath() + "/merge.wav");try {if (!mergedFile.exists()){mergedFile.createNewFile();}FileSplitUtils.mergeFiles(list,mergedFile);}catch (Exception e){Log.d("caowj", "合并错误:"+e.getMessage());}}else {Log.d("caowj", "分段文件不存在");}}

2、音频文件的切割,给每个切割文件补上wav头信息:

File mWavFile = new File(getExternalFilesDir(null).getAbsolutePath() + "/test.wav");
List<File> wavFileList= FileSplitUtils.wavFileSplit(mWavFile, FileUtils.getRootDataFile(this).getAbsolutePath(),15*1024*1024);

说明:wav头文件需要计算 文件长度,切割后的文件长度有变化,导致wav头文件不同;导致最终的md5值计算结果不匹配。

参考:FileUtils#waveFileHeader 方法:

public static byte[] waveFileHeader(long totalAudioLen, int bitNum, long longSampleRate, byte channels) throws IOException {}

FileSplitUtils

public class FileSplitUtils {// 文件拆分,分段public static List<File> fileSplit(File targetFile, String splitFilePath, int splitSize) {if (targetFile == null || !targetFile.exists()) {return null;}List<File> fileList = new ArrayList<>();try {long fileLength = targetFile.length();//计算分割文件数量int count = (fileLength % splitSize == 0 ? (int) fileLength / splitSize : (int) (fileLength / splitSize) + 1);RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "r");for (int i = 0; i < count; i++) {randomAccessFile.seek(i * splitSize);File file = new File(splitFilePath, i + ".wav");if (file.exists()) {file.delete();} else {file.createNewFile();}fileList.add(file);FileOutputStream fos = new FileOutputStream(file);//读取文件并写入byte[] bytes = new byte[2 * 1024 * 1024];int len;if (bytes.length < splitSize) {//缓冲区小区分割的文件大小int writeCount = splitSize % bytes.length == 0 ? splitSize / bytes.length : (splitSize / bytes.length) + 1;for (int j = 0; j < writeCount; j++) {len = randomAccessFile.read(bytes);if (len == -1) {break;}if (j == writeCount - 1 && splitSize % bytes.length != 0) {fos.write(bytes, 0, splitSize % bytes.length);} else {fos.write(bytes, 0, len);}}} else {byte[] splitBytes = new byte[splitSize];len = randomAccessFile.read(splitBytes);fos.write(splitBytes, 0, len);}fos.close();}} catch (IOException e) {e.printStackTrace();}return fileList;}// 多文件合并public static void mergeFiles(List<File> files, File mergedFile) throws IOException {FileOutputStream fos = new FileOutputStream(mergedFile);for (File file : files) {FileInputStream fis = new FileInputStream(file);byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) > 0) {fos.write(buffer, 0, length);}fis.close();}fos.close();}// wav文件拆分,给每个新文件补上wav头文件public static List<File> wavFileSplit(File targetFile, String splitFilePath, int splitSize) {if (targetFile == null || !targetFile.exists()) {return null;}List<File> fileList = new ArrayList<>();try {long fileLength = targetFile.length() - 44;//System.out.println("srcFileLength = "+fileLength+" splitSize = "+splitSize);//计算分割文件数量int count = (fileLength % splitSize == 0 ? (int) fileLength / splitSize : (int) (fileLength / splitSize) + 1);//System.out.println("count = "+count);RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "r");for (int i = 0; i < count; i++) {randomAccessFile.seek(i * splitSize + 44);//去除wav头44字节File file = new File(splitFilePath, i + ".wav");if (file.exists()) {file.delete();} else {file.createNewFile();}fileList.add(file);FileOutputStream fos = new FileOutputStream(file);//写入wav头if (fileLength % splitSize == 0) {fos.write(FileUtils.waveFileHeader(splitSize, 16, 8000, (byte) 1));} else {if (i == count - 1 && splitSize % bytes.length != 0) {fos.write(FileUtils.waveFileHeader(fileLength % splitSize, 16, 8000, (byte) 1));} else {fos.write(FileUtils.waveFileHeader(splitSize, 16, 8000, (byte) 1));}}//读取文件并写入byte[] bytes = new byte[2 * 1024 * 1024];int len = 0;if (bytes.length < splitSize) {//缓冲区小区分割的文件大小int writeCount = splitSize % bytes.length == 0 ? splitSize / bytes.length : (splitSize / bytes.length) + 1;//System.out.println("writeCount = "+writeCount);for (int j = 0; j < writeCount; j++) {len = randomAccessFile.read(bytes);if (len == -1) {break;}if (j == writeCount - 1) {fos.write(bytes, 0, splitSize % bytes.length);} else {fos.write(bytes, 0, len);}}} else {byte[] splitBytes = new byte[splitSize];len = randomAccessFile.read(splitBytes);fos.write(splitBytes, 0, len);}fos.close();}} catch (IOException e) {e.printStackTrace();}return fileList;}public static void wavFileMerge(List<File> wavFileList, File mergeFile) {if (mergeFile == null) {return;}FileOutputStream fos = null;try {if (!mergeFile.exists()) {if (!mergeFile.getParentFile().exists()) {mergeFile.getParentFile().mkdirs();}mergeFile.createNewFile();}fos = new FileOutputStream(mergeFile);long mergeFileSize = 0;for (File wavFile : wavFileList) {mergeFileSize += wavFile.length() - 44;}//System.out.println("mergeFileSize = "+mergeFileSize);fos.write(FileUtils.waveFileHeader(mergeFileSize, 16, 8000, (byte) 1));for (File wavFile : wavFileList) {RandomAccessFile randomAccessFile = new RandomAccessFile(wavFile, "r");randomAccessFile.seek(44);byte[] bytes = new byte[1024 * 1024];int len = 0;while ((len = randomAccessFile.read(bytes)) != -1) {fos.write(bytes, 0, len);}}} catch (IOException e) {e.printStackTrace();} finally {if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}
}

FileUtils

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Locale;public class FileUtils {/*** TAG for log messages.*/private static final String TAG = "FileUtils";public static File createDataFilePath(long time) {File path = new File(Constants.FILE_PATH_DATA + "/" + DateUtils.getFormatDate(time, Constants.TIME_FORMAT_FILE));if (!path.exists()) {path.mkdirs();}return path;}public static File createDataFilePath(String time) {File path = new File(Constants.FILE_PATH_DATA + "/" + DateUtils.getFormatDate(time, Constants.TIME_FORMAT_FILE));if (!path.exists()) {path.mkdirs();}return path;}public static File createPcmFile(String path, String fileName) {File pcmFilePath = new File(path);File pcmFile = new File(pcmFilePath.getAbsolutePath(), fileName);try {if (!pcmFilePath.exists()) {pcmFilePath.mkdirs();}if (!pcmFile.exists()) {pcmFile.createNewFile();}} catch (IOException e) {e.printStackTrace();}return pcmFile;}public static File createRawPcmFile(String path, long timeMillis) {String fileName = "raw_" + DateUtils.getFormatDate(timeMillis, Constants.TIME_FORMAT_FILE) + ".pcm";return createPcmFile(path, fileName);}public static File createSpkPcmFile(String path, long timeMillis) {String fileName = "spk_" + DateUtils.getFormatDate(timeMillis, Constants.TIME_FORMAT_FILE) + ".pcm";return createPcmFile(path, fileName);}public static File createMicPcmFile(String path, long timeMillis) {String fileName = "mic_" + DateUtils.getFormatDate(timeMillis, Constants.TIME_FORMAT_FILE) + ".pcm";return createPcmFile(path, fileName);}public static File createWavFile(String timeMillis) {String fileName = DateUtils.getFormatDate(timeMillis, Constants.TIME_FORMAT_FILE) + ".wav";File wavFilePath = createDataFilePath(timeMillis);File wavFile = new File(wavFilePath.getAbsolutePath(), fileName);try {if (!wavFilePath.exists()) {wavFilePath.mkdirs();}if (!wavFile.exists()) {wavFile.createNewFile();}} catch (IOException e) {e.printStackTrace();}return wavFile;}public static File getWavFileByTime(String createTime) {long time = DateUtils.formatTimeToLong(createTime, Constants.TIME_FORMAT_UTC);String fileName = DateUtils.getFormatDate(time, Constants.TIME_FORMAT_FILE) + ".wav";File wavFilePath = new File(Constants.FILE_PATH_DATA + "/" + DateUtils.getFormatDate(time, Constants.TIME_FORMAT_FILE));File wavFile = new File(wavFilePath.getAbsolutePath(), fileName);return wavFile;}public static File createTempImg(Context context) {File file = new File(context.getExternalCacheDir(), "output_img.jpg");if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}}return file;}public static File createTempFile(Context context, String fileName) {File file = new File(context.getExternalCacheDir(), fileName);return file;}public static File createFaceFile(Context context) {String fileName = SpManager.getUserId() + ".png";//Constants.FILE_NAME_FACE;File tempPath = getRootDataFile(context);File faceFile = new File(tempPath.getAbsolutePath(), fileName);LoggerUtil.d(faceFile.getAbsolutePath());try {if (!tempPath.exists()) {tempPath.mkdirs();}if (faceFile.exists()) {faceFile.delete();}faceFile.createNewFile();} catch (IOException e) {e.printStackTrace();}return faceFile;}public static File getCropFaceFile(Context context) {return new File(getRootDataFile(context), SpManager.getUserId() + Constants.FILE_NAME_FACE_CROP);}public static File getRootDataFile(Context context) {return context.getFilesDir();}public static File createCropFaceTempFile(Context context) {String fileName = SpManager.getUserId() + Constants.FILE_NAME_FACE_CROP;File tempPath = getRootDataFile(context);File faceFile = new File(tempPath.getAbsolutePath(), fileName);LoggerUtil.d(faceFile.getAbsolutePath());try {if (!tempPath.exists()) {tempPath.mkdirs();}if (faceFile.exists()) {faceFile.delete();}faceFile.createNewFile();} catch (IOException e) {e.printStackTrace();}return faceFile;}public static FileOutputStream getFileOutputStream(File file) {try {return new FileOutputStream(file);} catch (FileNotFoundException e) {e.printStackTrace();}return null;}public static boolean checkNewFirmZipExist(int newFirmVersion, String md5) {String fileName = "mintti_" + AppUtils.unParseDeviceType(SpManager.getDeviceType())+ "_v" + newFirmVersion + ".zip";File zipFile = new File(Constants.FILE_PATH_ZIP, fileName);if (zipFile.exists()) {if (getFileMd5(zipFile).equals(md5)) {return true;} else {zipFile.delete();}}return false;}public static File getNewFirmZipFile(int newFirmVersion) {String fileName = "mintti_" + AppUtils.unParseDeviceType(SpManager.getDeviceType())+ "_v" + newFirmVersion + ".zip";File zipFile = new File(Constants.FILE_PATH_ZIP, fileName);if (!zipFile.exists()) {zipFile.getParentFile().mkdirs();}return zipFile;}public static File getNewSoftFile(Context context, String versionName) {String fileName = versionName + ".apk";File file = createTempFile(context, fileName);return file;}public static File getBinFile() {File[] files = new File(Constants.FILE_PATH_ZIP).listFiles();for (File file : files) {if (file.getName().endsWith("bin")) {return file;}}return null;}//将文件转换成Byte数组public static byte[] getPcmBytesByWav(File file) {
//        File file = new File(pathStr);try {FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);byte[] b = new byte[1024];int n;while ((n = fis.read(b)) != -1) {bos.write(b, 0, n);}fis.close();byte[] data = bos.toByteArray();bos.close();byte[] pcmByte = Arrays.copyOfRange(data, 44, data.length);return pcmByte;} catch (Exception e) {e.printStackTrace();}return null;}/*** 获取文件的MD5值** @param file 文件路径* @return md5*/public static String getFileMd5(File file) {MessageDigest messageDigest;//MappedByteBuffer byteBuffer = null;FileInputStream fis = null;try {messageDigest = MessageDigest.getInstance("MD5");if (file == null) {return "";}if (!file.exists()) {return "";}int len = 0;fis = new FileInputStream(file);//普通流读取方式byte[] buffer = new byte[1024 * 1024 * 10];while ((len = fis.read(buffer)) > 0) {//该对象通过使用 update()方法处理数据messageDigest.update(buffer, 0, len);}BigInteger bigInt = new BigInteger(1, messageDigest.digest());String md5 = bigInt.toString(16);while (md5.length() < 32) {md5 = "0" + md5;}return md5;} catch (Exception e) {e.printStackTrace();} finally {try {if (fis != null) {fis.close();fis = null;}} catch (IOException e) {e.printStackTrace();}}return "";}/*** pcm文件转wav文件** @param inFile  源文件路径* @param outFile 目标文件路径*/public static void pcmToWav(File inFile, File outFile) {FileInputStream in;FileOutputStream out;long totalAudioLen;byte[] data = new byte[1024 * 1024];try {in = new FileInputStream(inFile);out = new FileOutputStream(outFile);totalAudioLen = inFile.length();out.write(waveFileHeader(totalAudioLen, 16, 8000, (byte) 1));int len = 0;while ((len = in.read(data)) != -1) {out.write(data, 0, len);}in.close();out.close();} catch (IOException e) {e.printStackTrace();}}public static long getAudioDuration(File wavFile) {long fileLength = wavFile.length();long pcmLength = fileLength - 44;long pcmDuration = pcmLength / 16;return pcmDuration;}public static void deleteZipFileDir() {File file = new File(Constants.FILE_PATH_ZIP);if (file.exists()) {File[] fileList = file.listFiles();for (File subFile : fileList) {subFile.delete();}}}public static File drawable2File(Context context, Drawable drawable) {try {Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();File file = createTempFile(context, System.currentTimeMillis() + ".jpg");if (!file.exists()) {file.createNewFile();}FileOutputStream fos = new FileOutputStream(file);bitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos);fos.close();return file;} catch (IOException e) {e.printStackTrace();}return null;}/*** wav头** @param totalAudioLen  pcm文件长度* @param bitNum         采样位数,16位或8位* @param longSampleRate 采样率* @param channels       通道数* @return* @throws IOException*/public static byte[] waveFileHeader(long totalAudioLen, int bitNum, long longSampleRate, byte channels) throws IOException {byte[] header = new byte[44];long totalDataLen = totalAudioLen + 36;long byteRate = bitNum * longSampleRate * channels / 8;header[0] = 'R'; // RIFFheader[1] = 'I';header[2] = 'F';header[3] = 'F';header[4] = (byte) (totalDataLen & 0xff);//数据大小header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);header[8] = 'W';//WAVEheader[9] = 'A';header[10] = 'V';header[11] = 'E';//FMT Chunkheader[12] = 'f'; // 'fmt 'header[13] = 'm';header[14] = 't';header[15] = ' ';//过渡字节//数据大小header[16] = 16; // 4 bytes: size of 'fmt ' chunkheader[17] = 0;header[18] = 0;header[19] = 0;//编码方式 10H为PCM编码格式header[20] = 1; // format = 1header[21] = 0;//通道数header[22] = channels;header[23] = 0;//采样率,每个通道的播放速度header[24] = (byte) (longSampleRate & 0xff);header[25] = (byte) ((longSampleRate >> 8) & 0xff);header[26] = (byte) ((longSampleRate >> 16) & 0xff);header[27] = (byte) ((longSampleRate >> 24) & 0xff);//音频数据传送速率,采样率*通道数*采样深度/8header[28] = (byte) (byteRate & 0xff);header[29] = (byte) ((byteRate >> 8) & 0xff);header[30] = (byte) ((byteRate >> 16) & 0xff);header[31] = (byte) ((byteRate >> 24) & 0xff);// 确定系统一次要处理多少个这样字节的数据,确定缓冲区,通道数*采样位数header[32] = (byte) (bitNum * channels / 8);header[33] = 0;//每个样本的数据位数header[34] = 16;header[35] = 0;//Data chunkheader[36] = 'd';//dataheader[37] = 'a';header[38] = 't';header[39] = 'a';header[40] = (byte) (totalAudioLen & 0xff);header[41] = (byte) ((totalAudioLen >> 8) & 0xff);header[42] = (byte) ((totalAudioLen >> 16) & 0xff);header[43] = (byte) ((totalAudioLen >> 24) & 0xff);return header;}//获取文件名不带后缀public static String getFileNameNoEx(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot > -1) && (dot < (filename.length()))) {return filename.substring(0, dot);}}return filename;}public static String formatFileSize(long length) {DecimalFormat df = new DecimalFormat("#.00");//""String fileSizeString = "";if (length < 1024) {fileSizeString = df.format((double) length) + "B";} else if (length < 1048576) {fileSizeString = df.format((double) length / 1024) + "K";} else if (length < 1073741824) {fileSizeString = df.format((double) length / 1048576) + "M";} else {fileSizeString = df.format((double) length / 1073741824) + "G";}return fileSizeString;}/*** @param uri The Uri to check.* @return Whether the Uri authority is ExternalStorageProvider.* @author paulburke*/public static boolean isExternalStorageDocument(Uri uri) {return "com.android.externalstorage.documents".equals(uri.getAuthority());}/*** @param uri The Uri to check.* @return Whether the Uri authority is DownloadsProvider.* @author paulburke*/public static boolean isDownloadsDocument(Uri uri) {return "com.android.providers.downloads.documents".equals(uri.getAuthority());}/*** @param uri The Uri to check.* @return Whether the Uri authority is MediaProvider.* @author paulburke*/public static boolean isMediaDocument(Uri uri) {return "com.android.providers.media.documents".equals(uri.getAuthority());}/*** @param uri The Uri to check.* @return Whether the Uri authority is Google Photos.*/public static boolean isGooglePhotosUri(Uri uri) {return "com.google.android.apps.photos.content".equals(uri.getAuthority());}/*** Get the value of the data column for this Uri. This is useful for* MediaStore Uris, and other file-based ContentProviders.** @param context       The context.* @param uri           The Uri to query.* @param selection     (Optional) Filter used in the query.* @param selectionArgs (Optional) Selection arguments used in the query.* @return The value of the _data column, which is typically a file path.* @author paulburke*/public static String getDataColumn(Context context, Uri uri, String selection,String[] selectionArgs) {Cursor cursor = null;final String column = "_data";final String[] projection = {column};try {cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,null);if (cursor != null && cursor.moveToFirst()) {final int column_index = cursor.getColumnIndexOrThrow(column);return cursor.getString(column_index);}} catch (IllegalArgumentException ex) {Log.i(TAG, String.format(Locale.getDefault(), "getDataColumn: _data - [%s]", ex.getMessage()));} finally {if (cursor != null) {cursor.close();}}return null;}/*** Get a file path from a Uri. This will get the the path for Storage Access* Framework Documents, as well as the _data field for the MediaStore and* other file-based ContentProviders.<br>* <br>* Callers should check whether the path is local before assuming it* represents a local file.** @param context The context.* @param uri     The Uri to query.* @author paulburke*/public static String getPath(final Context context, final Uri uri) {final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;// DocumentProviderif (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {if (isExternalStorageDocument(uri)) {final String docId = DocumentsContract.getDocumentId(uri);final String[] split = docId.split(":");final String type = split[0];if ("primary".equalsIgnoreCase(type)) {return Environment.getExternalStorageDirectory() + "/" + split[1];}// TODO handle non-primary volumes}// DownloadsProviderelse if (isDownloadsDocument(uri)) {final String id = DocumentsContract.getDocumentId(uri);if (!TextUtils.isEmpty(id)) {try {final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));return getDataColumn(context, contentUri, null, null);} catch (NumberFormatException e) {Log.i(TAG, e.getMessage());return null;}}}// MediaProviderelse if (isMediaDocument(uri)) {final String docId = DocumentsContract.getDocumentId(uri);final String[] split = docId.split(":");final String type = split[0];Uri contentUri = null;if ("image".equals(type)) {contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;} else if ("video".equals(type)) {contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;} else if ("audio".equals(type)) {contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;}final String selection = "_id=?";final String[] selectionArgs = new String[]{split[1]};return getDataColumn(context, contentUri, selection, selectionArgs);}}// MediaStore (and general)else if ("content".equalsIgnoreCase(uri.getScheme())) {// Return the remote addressif (isGooglePhotosUri(uri)) {return uri.getLastPathSegment();}return getDataColumn(context, uri, null, null);}// Fileelse if ("file".equalsIgnoreCase(uri.getScheme())) {return uri.getPath();}return null;}/*** Copies one file into the other with the given paths.* In the event that the paths are the same, trying to copy one file to the other* will cause both files to become null.* Simply skipping this step if the paths are identical.*/public static void copyFile(@NonNull String pathFrom, @NonNull String pathTo) throws IOException {if (pathFrom.equalsIgnoreCase(pathTo)) {return;}FileChannel outputChannel = null;FileChannel inputChannel = null;try {inputChannel = new FileInputStream(new File(pathFrom)).getChannel();outputChannel = new FileOutputStream(new File(pathTo)).getChannel();inputChannel.transferTo(0, inputChannel.size(), outputChannel);inputChannel.close();} finally {if (inputChannel != null) inputChannel.close();if (outputChannel != null) outputChannel.close();}}public static Uri copyFile(Context context, Uri uri, File targetFile) {try {InputStream inputStream = context.getContentResolver().openInputStream(uri);FileOutputStream fos = new FileOutputStream(targetFile);byte[] buffer = new byte[1024];int len = 0;while ((len = inputStream.read(buffer)) != -1) {fos.write(buffer, 0, len);}fos.close();inputStream.close();Log.e("FileUtils", "copyFile: ");return getFileUri(context, targetFile);} catch (IOException e) {e.printStackTrace();}return null;}public static Uri getFileUri(Context context, File file) {Uri contentUri = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {contentUri = FileProvider.getUriForFile(context, "com.kl.mintti", file);//setImgFace(contentUri);} else {contentUri = Uri.fromFile(file);}Log.e("FileUtils", "getFileUri: " + contentUri);return contentUri;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多人聊天作业

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

如何评估数据资产的价值?哪种方法更容易实现?

今年可以称之为数据年&#xff0c;从去年年底党中央发布《数据20条》&#xff0c;对数据领域的一系列的制度建设做了提纲起领的作用。在财经领域今年的下半年&#xff0c;密集出台一系列跟数据资产相关的政策&#xff0c;包括8月21日发布的《企业数据资源会计处理的暂行规定》以…

最小生成树算法与二分图算法

文章目录 概述 P r i m Prim Prim 算法 - 稠密图 - O ( n 2 ) O(n^2) O(n2)思路概述时间复杂度分析AcWing 858. Prim算法求最小生成树CODE K r u s k a l Kruskal Kruskal 算法 - 稀疏图 - O ( m l o g m ) O(mlogm) O(mlogm)思路解析时间复杂度分析AcWing 859. Kruskal算法求…

后端返回数据前端保留两位小数

一.背景 在平时工作中尤其是银行金融类佘涉及到数据计算问题&#xff0c;数据统计又不能显示太多小数点&#xff0c;很多时候需求不一样&#xff0c;对数据的精度要求也不一样&#xff0c;下面是我在工作中用到的方法总结记录一下。 二.不同需求对应的方法 toFixed() 方法 to…

探索HarmonyOS_开发软件安装

随着华为推出HarmonyOS NEXT 宣布将要全面启用鸿蒙原声应用&#xff0c;不在兼容安卓应用&#xff0c; 现在开始探索鸿蒙原生应用的开发。 HarmonyOS应用开发官网 - 华为HarmonyOS打造全场景新服务 鸿蒙官网 开发软件肯定要从这里下载 第一个为微软系统(windows)&#xff0c;第…

逆向修改Unity的安卓包资源并重新打包

在上一篇文章中,我已经讲过如何逆向获取unity打包出来的源代码和资源了,那么这一节我将介绍如何将解密出来的源代码进行修改并重新压缩到apk中。 其实在很多时候,我们不仅仅想要看Unity的源码,我们还要对他们的客户端源码进行修改和调整,比如替换资源,替换服务器连接地址…

MSSQL注入入门讲解:保护你的数据库免受攻击

MSSQL注入入门讲解&#xff1a;保护你的数据库免受攻击 引言&#xff1a; MSSQL注入是一种常见的网络攻击方式&#xff0c;通过利用应用程序对用户输入的不正确处理&#xff0c;攻击者可以执行恶意代码并获取敏感数据。本篇博客将详细介绍MSSQL注入的原理、常见的攻击技术以及…

【C/C++】函数参数默认值

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

深度学习实战64-黑白照片着色的模型应用,快速部署实现黑白图片快速上色的功能

大家好,我是微学AI,今天给大家介绍一下深度学习实战64-黑白照片着色的模型应用,快速部署实现黑白图片快速上色的功能。图片上色是一个具有多模态不确定性和高度不适定性的挑战性问题。直接训练深度神经网络通常会导致错误的语义颜色和低色彩丰富度。虽然基于Transformer的方…

人工智能AIGC培训讲师叶梓介绍及AI强化学习培训提纲

叶梓&#xff0c;上海交通大学计算机专业博士毕业&#xff0c;高级工程师。主研方向&#xff1a;数据挖掘、机器学习、人工智能。历任国内知名上市IT企业的AI技术总监、资深技术专家&#xff0c;市级行业大数据平台技术负责人。个人主页&#xff1a;大数据人工智能AI培训讲师叶…

9大高效的前端测试工具与框架!

在每个Web应用程序中&#xff0c;作为用户直接可见的应用程序外观&#xff0c;“前端”包括&#xff1a;图形化的用户界面、相应的功能、及其整体站点的可用性。我们可以毫不夸张地说&#xff1a;如果前端无法正常工作&#xff0c;您将无法“拉新”网站的潜在用户。这也正是我们…

Java8新特性CompletableFuture详解

一、概述 CompletableFuture 是Java 8 中引入的 Java Future API的扩展&#xff0c;用于 Java 中的异步编程&#xff0c;它可以使我们的任务运行在与主线程分离的其他线程中&#xff0c;并通过回调在主线程中得到异步任务执行状态&#xff0c;包括是否完成&#xff0c;是否异常…

【Node.js】如何修复“错误:错误:0308010c:digital envelope routines::不受支持”

作为一名开发人员&#xff0c;在项目中遇到错误是很常见的。在这篇博客文章中&#xff0c;我们将讨论一个困扰开发人员的特定错误&#xff0c;尤其是那些使用Node.js的开发人员。有问题的错误是“错误&#xff1a;错误&#xff1a;0308010c:数字信封例程&#xff1a;&#xff1…

MySQL:update set的坑

目录 一、问题描述 二、为何会出现这样的问题&#xff1f; 三、正确的方案 一、问题描述 我在修改mysql数据表时&#xff0c;看到下面的现象。 我表中原始数据如下&#xff1a; 执行了下面的修改&#xff0c;显示执行成功。 update user_function_record_entity set open_…

MySQL_1. mysql数据库介绍

shell脚本差不多快完结了接下来会为大家更新MySQL系列的相关的基础知识笔记&#xff0c;希望对大家有所帮助&#xff0c;好废话不多说&#xff0c;接下来开始正题&#xff01; 1.mysql数据库介绍 mysql 是一款安全、跨平台、高效的&#xff0c;并与 PHP、Java 等主流编程语言…

AI写作工具有哪些?原创我AI写作工具推荐

人工智能&#xff08;AI&#xff09;的广泛应用不仅改变了我们的工作方式&#xff0c;也对文学创作领域产生了深远的影响。其中&#xff0c;AI写作技术在提高工作效率和文章创作方面发挥着越来越重要的角色。然而&#xff0c;伴随着这一技术的兴起&#xff0c;一个备受关注的问…

机器学习实验五:集成学习

系列文章目录 机器学习实验一&#xff1a;线性回归机器学习实验二&#xff1a;决策树模型机器学习实验三&#xff1a;支持向量机模型机器学习实验四&#xff1a;贝叶斯分类器机器学习实验五&#xff1a;集成学习机器学习实验六&#xff1a;聚类 文章目录 系列文章目录一、实验…

Eureka的使用说明

Eureka是一个服务管理的平台&#xff0c;主要是管理多个模块之间的使用。eureka分为客户端和客户端&#xff0c;下面我们直接使用&#xff1a; 1.eureka server 服务管理的使用 1. 导入相关依赖 <dependency><groupId>org.springframework.cloud</groupId>…

docker基本管理和相关概念

1、docker是什么&#xff1f; docker是开源的应用容器引擎。基于go语言开发的&#xff0c;运行在Linux系统当中开源轻量级的“虚拟机”。 docker可以在一台主机上轻松的为任何应用创建一个轻量级的&#xff0c;可移植的&#xff0c;自给自足的容器。docker的宿主机是Linux系统…