There is a code:

public class Unzipper { private static String LOG_TAG = Unzipper.class.getSimpleName(); public static void unzip(final File file, final File destination) throws ZipException, IOException { new Thread() { public void run() { long START_TIME = System.currentTimeMillis(); long FINISH_TIME = 0; long ELAPSED_TIME = 0; try { ZipInputStream zin = new ZipInputStream(new FileInputStream(file)); String workingDir = destination.getAbsolutePath()+"/"; byte buffer[] = new byte[4096]; int bytesRead; ZipEntry entry = null; while ((entry = zin.getNextEntry()) != null) { if (entry.isDirectory()) { File dir = new File(workingDir, entry.getName()); if (!dir.exists()) { dir.mkdir(); } Log.i(LOG_TAG, "[DIR] "+entry.getName()); } else { FileOutputStream fos = new FileOutputStream(workingDir + entry.getName()); while ((bytesRead = zin.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } fos.close(); Log.i(LOG_TAG, "[FILE] "+entry.getName()); } } zin.close(); FINISH_TIME = System.currentTimeMillis(); ELAPSED_TIME = FINISH_TIME - START_TIME; Log.i(LOG_TAG, "COMPLETED in "+(ELAPSED_TIME/1000)+" seconds."); } catch (Exception e) { Log.e(LOG_TAG, "FAILED"); } }; }.start(); } 

Here I press the button

 if ( initialize() ) { zipFile = new File(destination, + MyFile); try { Unzipper.unzip(zipFile, destination); } catch (ZipException e) { } catch (IOException e) { } } else { } 

AND...

 public boolean initialize() { boolean result = false; File sdcard = Environment.getExternalStorageDirectory(); if ( sdcard != null ) { destination = sdcard; if ( !destination.exists() ) { if ( destination.mkdir() ) { result = true; } } else { result = true; } } return result; } 

Everything is actually unpacked in / mnt / sdcard /

I also need an external (inserted) memory card. And, if you manually register / mnt / extSdCard , then everything works, but on other devices the path to the card is different / storage / sdcard0 / / mnt / MisroSD /

A universal way that would work on all devices from 4.4 android .

    2 answers 2

    I'm afraid that everything is difficult. Depends on manufacturer.

    There is such a thing as default memory — that is what getExternalStorageDirectory() returns. In theory, if there is a CD card and built-in memory, then the default memory points to the CD card, and if removed, then the built-in memory.

    But it is in theory. In practice, it all depends on the vendor and you definitely cannot get the path to the memory card.

    See also this article and the official documentation for getExternalStorageDirectory () , it is quite extensive there. In particular, it states that you can try to get the path to the secondary storage using getExternalFilesDirs(String) , getExternalCacheDirs() and getExternalMediaDirs() .

      I did it like this:

      1) Here I find out what we have mounted:

       private String getSDcardPath() { String exts = Environment.getExternalStorageDirectory().getPath(); String sdCardPath = null; try { FileReader fr = new FileReader(new File("/proc/mounts")); BufferedReader br = new BufferedReader(fr); String line; while((line = br.readLine())!=null) { if(line.contains("secure") || line.contains("asec")) continue; if(line.contains("fat")) { String[] pars = line.split("\\s"); if(pars.length<2) continue; if(pars[1].equals(exts)) continue; sdCardPath =pars[1]; break; } } fr.close(); br.close(); return sdCardPath; } catch (Exception e){} return sdCardPath; } 

      2) So I get the result:

       String EXTERNAL_PATH = getSDcardPath() +"/"; 

      Result 1: /mnt/media_rw/extSdCard/ on one device.

      Result 2: /mnt/media_rw/MicroSD/ on another device.

      But on another device there is no memory card along this path, but there is: /storage/MicroSD/ , just like on the first device: /storage/extSdCard/

      3) I make universality as I wanted:

       String EXTERNAL_PATH = getSDcardPath() +"/"; String EXTERNAL_PATH_REPLACE = EXTERNAL_PATH.replace ("/mnt/media_rw", "/storage"); 

      Tested on 4 different devices with root and allowed writing to a memory card.