private static final String ALGORITHM = "AES";
=========================文件加密=================================
/*** 文件加密* @param secretKey 文件加密密鑰* @param oldFiles 原始文件列表,需要加密的* @param newFiles 構造加密后的文件列表*(選擇多個或者單個)多個文件加密*/ @RequiresApi(api = Build.VERSION_CODES.O) public void newEncryptFiles(String secretKey, List<File> oldFiles, List<File> newFiles) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {// 使用密鑰字符串生成秘密密鑰SecretKey secretKeySpec = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);// 獲取 AES 加密算法的實例Cipher cipher = Cipher.getInstance(ALGORITHM);// 使用秘密密鑰初始化密碼 cipher,設置為加密模式cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);//循環復制文件curr = 1;for (int i = 0; i < oldFiles.size(); i++) {File oldFile = oldFiles.get(i);File newFile = newFiles.get(i);long m = oldFiles.get(i).length();int n = (int)(m/100);int s = 0;//每一份的進度// 創建輸入流,讀取源文件try (InputStream inputStream = new FileInputStream(oldFile);// 創建輸出流,寫入加密文件OutputStream outputStream = new FileOutputStream(newFile);// 創建密碼輸出流,連接到輸出流,并使用密碼 cipher 進行加密CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher)) {// 緩沖區大小byte[] buffer = new byte[4096];int bytesRead;// 讀取源文件內容到緩沖區while ((bytesRead = inputStream.read(buffer)) != -1) {// 將加密后的數據寫入加密文件cipherOutputStream.write(buffer, 0, bytesRead);s += 1024;if(s >= n){//進度+1handler.sendEmptyMessage(MSG_COPY_RUNNING);prog ++;s = 0;}}}}}
=========================文件解密=========================
SecretKey secretKeySpec = new SecretKeySpec("sin-17214455-@@@".getBytes(), ALGORITHM); Cipher cipher = null; try {cipher = Cipher.getInstance(ALGORITHM + "/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);//獲取源加密文件或文件夾路徑File encryptFile= new File(item.getPath() + File.separator + item.getEncrypted_name());//獲取目標解密文件或文件夾路徑,解密過后生成的名稱original_nameFile newFile = new File(item.getNewPath(), "original_name");// 創建輸入流,讀取加密文件FileInputStream inputStream = new FileInputStream(encryptFile);// 創建輸出流,寫入解密文件FileOutputStream outputStream = new FileOutputStream(newFile);// 創建密碼輸出流,連接到輸出流,并使用密碼 cipher 進行加密CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);// 緩沖區大小byte[] buffer = new byte[4096];int bytesRead;// 讀取源文件內容到緩沖區while ((bytesRead = cipherInputStream.read(buffer)) != -1) {// 將加密后的數據寫入解密文件outputStream.write(buffer, 0, bytesRead);}outputStream.close();inputStream.close();cipherInputStream.close();if (!newFile.exists()) {newFile.createNewFile();}if (!newFile.getParentFile().exists()) {newFile.getParentFile().mkdirs();} ??//解密到這里就結束了打開文件,這里就根據自己的需求而定。下面是我自己的一個需求。// 打開文件,調用系統的打開選擇的圖片,text文件或者其他 FileUtil.openFile(view.getContext(), newFile, ext); } catch (IOException e) {throw new RuntimeException(e); } catch (NoSuchFileToOpenException e) {ToastUtil.errorToast(view.getContext(), e.getMessage());throw new RuntimeException(e); } catch (NoSuchPaddingException e) {throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) {throw new RuntimeException(e); } catch (InvalidKeyException e) {throw new RuntimeException(e); }
/*** 調用系統應用打開文件* @param context context* @param file file對象* @param ext 擴展名()* @throws NoSuchFileToOpenException 沒有文件異常*/ public static void openFile(Context context, File file,String ext) throws NoSuchFileToOpenException {if(! file.exists()){throw new NoSuchFileToOpenException("文件不存在");}//根據擴展名,適配相應的typeString type = getType(ext);Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);Uri contentUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", file);intent.setDataAndType(contentUri,type);} else {Uri uri = Uri.fromFile(file);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setDataAndType(uri,type);}context.startActivity(intent); }
/*** 根據擴展名適配打開類型* @param ext 文件擴展名* @return 打開類型*/ public static String getType(String ext) {switch (ext){case "3gp":return "video/3gpp";case "apk":return "application/vnd.android.package-archive";case "asf":return "video/x-ms-asf";case "avi":return "video/x-msvideo";case "bin":return "application/octet-stream";case "bmp":return "image/bmp";case "c":return "text/plain";case "class":return "application/octet-stream";case "conf":return "text/plain";case "cpp":return "text/plain";case "doc":return "application/msword";case "docx":return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";case "xls":return "application/vnd.ms-excel";case "xlsx":return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case "exe":return "application/octet-stream";case "gif":return "image/gif";case "gtar":return "application/x-gtar";case "gz":return "application/x-gzip";case "h":return "text/plain";case "htm":return "text/html";case "html":return "text/html";case "jar":return "application/java-archive";case "java":return "text/plain";case "jpeg":return "image/jpeg";case "jpg":return "image/jpeg";case "js":return "application/x-javascript";case "log":return "text/plain";case "m3u":return "audio/x-mpegurl";case "m4a":return "audio/mp4a-latm";case "m4b":return "audio/mp4a-latm";case "m4p":return "audio/mp4a-latm";case "m4u":return "video/vnd.mpegurl";case "m4v":return "video/x-m4v";case "mov":return "video/quicktime";case "mp2":return "audio/x-mpeg";case "mp3":return "audio/x-mpeg";case "mp4":return "video/mp4";case "mpc":return "application/vnd.mpohun.certificate";case "mpe":return "video/mpeg";case "mpeg":return "video/mpeg";case "mpg":return "video/mpeg";case "mpg4":return "video/mp4";case "mpga":return "audio/mpeg";case "msg":return "application/vnd.ms-outlook";case "ogg":return "audio/ogg";case "pdf":return "application/pdf";case "png":return "image/png";case "pps":return "application/vnd.ms-powerpoint";case "ppt":return "application/vnd.ms-powerpoint";case "pptx":return "application/vnd.openxmlformats-officedocument.presentationml.presentation";case "prop":return "text/plain";case "rc":return "text/plain";case "rmvb":return "audio/x-pn-realaudio";case "rtf":return "application/rtf";case "sh":return "text/plain";case "tar":return "application/x-tar";case "tgz":return "application/x-compressed";case "txt":return "text/plain";case "wav":return "audio/x-wav";case "wma":return "audio/x-ms-wma";case "wmv":return "audio/x-ms-wmv";case "wps":return "application/vnd.ms-works";case "xml":return "text/plain";case "z":return "application/x-compress";case "zip":return "application/x-zip-compressed";case "":default:return "*/*";} }
在AndroidManiFest注冊fileprovider
<providerandroid:name="androidx.core.content.FileProvider"android:authorities="${applicationId}.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /> </provider>
在res目錄下的xml里面創建files-path
<?xml version="1.0" encoding="utf-8"?> <paths><files-pathname="files"path="." /><cache-pathname="cache"path="." /> <!-- <external-path--> <!-- name="external_storage"--> <!-- path="." />--><external-pathname="file_safe_root_path"path="." /><external-files-pathname="external_files"path="." /><external-cache-pathname="external_cache"path="." /><external-media-pathname="external_media"path="." /><root-pathname="root"path="." /></paths>