I have an issue in my application that I am not able to copy file to SD card in a particular folder. There is a error occurs in the process shown as "permission denied" even after setting the user permission in AndroidManifest.xml file
Button Click
copyBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try{
String pp = dataModels.get(getAdapterPosition()).getName();
File sdCardRoot1 = Environment.getExternalStorageDirectory();
File src = new File(sdCardRoot1, "/.MoreData/closed/" +pp);
String[] ff = StorageUtil.getStorageDirectories(context);
File filess = new File(ff[1]);
File dir = new File(filess, "/" + "new folder/"+pp+".jpg");
Log.e("videoAdapter3", String.valueOf(dir));
new USBCopyFileTask(context).execute(src, dir);
}catch (Exception e){
Log.e("videoAdapter", e.getMessage());
}
}
});
StorageUtil.class
package com.example.xpertech_android.more_movies_app.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class StorageUtil {
// Primary physical SD-CARD (not emulated)
private static final String EXTERNAL_STORAGE = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by File.pathSeparator, i.e: ":", ";"
private static final String SECONDARY_STORAGES = System.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARD
private static final String EMULATED_STORAGE_TARGET = System.getenv("EMULATED_STORAGE_TARGET");
// PhysicalPaths based on phone model
@SuppressLint("SdCardPath")
@SuppressWarnings("SpellCheckingInspection")
private static final String[] KNOWN_PHYSICAL_PATHS = new String[]{
"/storage/sdcard0",
"/storage/sdcard1", //Motorola Xoom
"/storage/extsdcard", //Samsung SGS3
"/storage/sdcard0/external_sdcard", //User request
"/mnt/extsdcard",
"/mnt/sdcard/external_sd", //Samsung galaxy family
"/mnt/sdcard/ext_sd",
"/mnt/external_sd",
"/mnt/media_rw/sdcard1", //4.4.2 on CyanogenMod S3
"/removable/microsd", //Asus transformer prime
"/mnt/emmc",
"/storage/external_SD", //LG
"/storage/ext_sd", //HTC One Max
"/storage/removable/sdcard1", //Sony Xperia Z1
"/data/sdext",
"/data/sdext2",
"/data/sdext3",
"/data/sdext4",
"/sdcard1", //Sony Xperia Z
"/sdcard2", //HTC One M8s
"/storage/microsd" //ASUS ZenFone 2
};
/**
* Returns all available storages in the system (include emulated)
* <p/>
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standard way to get it.
*
* @return paths to all available storages in the system (include emulated)
*/
public static String[] getStorageDirectories(Context context) {
// Final set of paths
final Set<String> availableDirectoriesSet = new HashSet<>();
if (!TextUtils.isEmpty(EMULATED_STORAGE_TARGET)) {
// Device has an emulated storage
availableDirectoriesSet.add(getEmulatedStorageTarget());
} else {
// Device doesn't have an emulated storage
availableDirectoriesSet.addAll(getExternalStorage(context));
}
// Add all secondary storages
Collections.addAll(availableDirectoriesSet, getAllSecondaryStorages());
String[] storagesArray = new String[availableDirectoriesSet.size()];
return availableDirectoriesSet.toArray(storagesArray);
}
private static Set<String> getExternalStorage(Context context) {
final Set<String> availableDirectoriesSet = new HashSet<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Solution of empty raw emulated storage for android version >= marshmallow
// because the EXTERNAL_STORAGE become something like: "/Storage/A5F9-15F4",
// so we can't access it directly
File[] files = getExternalFilesDirs(context, null);
for (File file : files) {
if (file != null) {
String applicationSpecificAbsolutePath = file.getAbsolutePath();
String rootPath = applicationSpecificAbsolutePath.substring(
0,
applicationSpecificAbsolutePath.indexOf("Android/data")
);
availableDirectoriesSet.add(rootPath);
}
}
} else {
if (TextUtils.isEmpty(EXTERNAL_STORAGE)) {
availableDirectoriesSet.addAll(getAvailablePhysicalPaths());
} else {
// Device has physical external storage; use plain paths.
availableDirectoriesSet.add(EXTERNAL_STORAGE);
}
}
return availableDirectoriesSet;
}
private static String getEmulatedStorageTarget() {
String rawStorageId = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
// External storage paths should have storageId in the last segment
// i.e: "/storage/emulated/storageId" where storageId is 0, 1, 2, ...
final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
final String[] folders = path.split(File.separator);
final String lastSegment = folders[folders.length - 1];
if (!TextUtils.isEmpty(lastSegment) && TextUtils.isDigitsOnly(lastSegment)) {
rawStorageId = lastSegment;
}
}
if (TextUtils.isEmpty(rawStorageId)) {
return EMULATED_STORAGE_TARGET;
} else {
return EMULATED_STORAGE_TARGET + File.separator + rawStorageId;
}
}
private static String[] getAllSecondaryStorages() {
if (!TextUtils.isEmpty(SECONDARY_STORAGES)) {
// All Secondary SD-CARDs split into array
return SECONDARY_STORAGES.split(File.pathSeparator);
}
return new String[0];
}
/**
* Filter available physical paths from known physical paths
*
* @return List of available physical paths from current device
*/
private static List<String> getAvailablePhysicalPaths() {
List<String> availablePhysicalPaths = new ArrayList<>();
for (String physicalPath : KNOWN_PHYSICAL_PATHS) {
File file = new File(physicalPath);
if (file.exists()) {
availablePhysicalPaths.add(physicalPath);
}
}
return availablePhysicalPaths;
}
private static File[] getExternalFilesDirs(Context context, String type) {
if (Build.VERSION.SDK_INT >= 19) {
return context.getExternalFilesDirs(type);
} else {
return new File[]{context.getExternalFilesDir(type)};
}
}
}
USBCopyFileTask
package com.example.xpertech_android.more_movies_app.util;
import android.app.Dialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.ProgressBar;
import com.example.xpertech_android.more_movies_app.R;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.constraintlayout.widget.ConstraintLayout;
public class USBCopyFileTask extends AsyncTask<File, Integer, File> {
Context context;
Dialog dialog;
AppCompatTextView textView;
ProgressBar progressBar;
ConstraintLayout layout;
public USBCopyFileTask(Context context) {
this.context = context;
}
@Override
protected File doInBackground(File... files) {
File source, destination;
source = files[0];
destination = files[1];
publishProgress(50); // update progress to 50%
Log.e("videoAdapter", String.valueOf(files[1]));
try {
Log.e("videoAdapterUSB", "try");
int progress;
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(destination);
// Transfer bytes from in to out
final long expectedBytes = source.length(); // This is the number of bytes we expected to copy..
long totalBytesCopied = 0; // This will track the total number of bytes we've copied
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
totalBytesCopied += len;
progress = (int) Math.round(((double) totalBytesCopied / (double) expectedBytes) * 100);
publishProgress(progress);
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
Log.e("videoAdapter", e.getMessage());
}
return null;
}
@Override
protected void onPreExecute() {
dialog = new Dialog(context);
dialog.setContentView(R.layout.progresslayout);
textView = dialog.findViewById(R.id.txtDownloadingMusic);
progressBar = dialog.findViewById(R.id.progressBarMovie);
layout = dialog.findViewById(R.id.progressLayoutnew);
textView.setText("Coping");
dialog.setCancelable(false);
progressBar.setIndeterminate(false);
progressBar.setMax(100);
layout.setVisibility(View.VISIBLE);
dialog.show();
Window window = dialog.getWindow();
window.setLayout(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
}
@Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
dialog.dismiss();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
}
}
Logcat
2021-01-15 17:27:44.399 6833-7342/luck.materialdesign.tabsnavigator E/videoAdapter: /storage/0C69-1809/CAREER WOMAN PART TWO.@iQlSXRgI2JykcsBWtFMTJvkinR5fV_JdU6iQ--HVNCI=
!1&204.jpg (Permission denied)
can anyone help me to resolve this issue ??