Your problem is that in the context of a shell, the path returned from Environment.getExternalStorageDirectory() will throw an error that the file or directory does not exist.
You need to change all file paths which you send to be run in a shell. Here is a static factory method you can use to get the correct File:
java
/**
* The external storage path is not readable by shell or root. This replaces {@link
* Environment#getExternalStorageDirectory()} with the environmental variable
* "EXTERNAL_STORAGE"
*
* @param file
* The file to check.
* @return The original file (if it does not start with {@link
* Environment#getExternalStorageDirectory()})
* or a file with the correct path.
*/
@SuppressLint("SdCardPath")
public static File fileForShell(File file) {
String externalStorage = Environment.getExternalStorageDirectory().getAbsolutePath();
if (!file.getAbsolutePath().startsWith(externalStorage)) {
return file;
}
String legacyStorage = System.getenv("EXTERNAL_STORAGE");
String path;
if (legacyStorage != null) {
path = file.getAbsolutePath().replaceFirst(externalStorage, legacyStorage);
} else {
path = file.getAbsolutePath().replaceFirst(externalStorage, "/sdcard");
}
return new File(path);
}
When you create the command just use the above method to get the correct file path.
java
File from = ...
File fileToUseInCommand = fileForShell(from);
...