I need to create a folder and unzip a document in the external storage. On certain devices, like an Honor 10, Samsung J7 and Xiaomi Mi A2 it works flawlessly, but on other devices, like Huawei Mate 20 and Samsung S8 neither the creation of the folder nor the unzipping work.
These are the requested permissions in the AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
They are outside the <application>
tag
In the MainActivity I request the permissions
private boolean checkPermissions() {
if (ActivityCompat.checkSelfPermission(ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
return true;
}
requestPermissions();
return false;
}
private void requestPermissions() {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_ID
);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == LOCATION_PERMISSION_ID) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setFiles();
}
}
}
After Permission has been granted I execute setFiles(); which creates the folder, a .nomedia file and unzips videos.zip into the created folder
public void setFiles(){
createFolder();
unzip();
}
private void createFolder() {
//Create Folder
File folder = new File(Environment.getExternalStorageDirectory().toString()+"/.videoFiles");
folder.mkdirs();
//Save the path as a string value
extStorageDirectory = folder.toString();
createNomedia();
}
private void createNomedia() {
String filepath = extStorageDirectory;
File file = new File(filepath+ "/.nomedia");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean unzip() {
String zipFile = Environment.getExternalStorageDirectory().toString() + "/videos.zip";
try{
FileUnzipper.unzip(zipFile, extStorageDirectory);
unzipComplete = true;
} catch (IOException ex){
Log.e("unzipping", "unzip Exception" + ex);
unzipComplete = false;
}
}
This is the FileUnzipper class:
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static android.content.ContentValues.TAG;
public class FileUnzipper{
final static int BUFFER_SIZE = 2048;
public static void unzip(String zipFile, String location) throws IOException {
int size;
byte[] buffer = new byte[BUFFER_SIZE];
try {
if ( !location.endsWith(File.separator) ) {
location += File.separator;
}
File f = new File(location);
if(!f.isDirectory()) {
f.mkdirs();
}
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile), BUFFER_SIZE));
try {
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
String path = location + ze.getName();
File unzipFile = new File(path);
if (ze.isDirectory()) {
if(!unzipFile.isDirectory()) {
unzipFile.mkdirs();
}
} else {
// check for and create parent directories if they don't exist
File parentDir = unzipFile.getParentFile();
if ( null != parentDir ) {
if ( !parentDir.isDirectory() ) {
parentDir.mkdirs();
}
}
// unzip the file
FileOutputStream out = new FileOutputStream(unzipFile, false);
BufferedOutputStream fout = new BufferedOutputStream(out, BUFFER_SIZE);
try {
while ( (size = zin.read(buffer, 0, BUFFER_SIZE)) != -1 ) {
fout.write(buffer, 0, size);
}
zin.closeEntry();
}
finally {
fout.flush();
fout.close();
}
}
}
}
finally {
zin.close();
}
}
catch (Exception e) {
Log.e(TAG, "Unzip exception", e);
}
}
}
Now on some devices this all works, the folder and the .nomedia File are created and videos.zip is unzipped, on other devices I get this:
E/ContentValues: Unzip exception
java.io.FileNotFoundException: /storage/emulated/0/videos.zip: open failed: EACCESS (Permission denied)
at libcore.io.IOBridge.open(IoBridge.java:496)
at java.io.FileInputStream.<init>(FileInputStream.java:159)
at java.io.FileInputStream.<init>(FileInputStream.java:115)
at com.example.test.FileUnzipper.unzip(FileUnzipper.java:32)
FileUnzipper.java:32 is ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile), BUFFER_SIZE));
I can't work out why it doesn't work on some devices and I don't know how to fix it...