6

How can I download some files from my web server in my android application and store them in application folder in root location or in a private folder in internal/external memory.

I can download files but i can't store them in private folder.

Already i write my download manger and i have some issues with showing notifications (like download percent) with it.

FarshidABZ
  • 3,860
  • 4
  • 32
  • 63

4 Answers4

3

I'm not exactly sure of what you want to do with "private folder"... but this is how I download files with a progress callback:

public class Downloader extends Thread implements Runnable{
    private String url;
    private String path;
    private DownloaderCallback listener=null;

    public Downloader(String path, String url){
        this.path=path;
        this.url=url;
    }

    public void run(){
        try {
            URL url = new URL(this.url);
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();

            String filename = urlConnection.getHeaderField("Content-Disposition");
            // your filename should be in this header... adapt the next line for your case
            filename = filename.substring(filename.indexOf("filename")+10, filename.length()-2);

            int total = urlConnection.getContentLength();
            int count;

            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(path+"/"+filename);

            byte data[] = new byte[4096];
            long current = 0;

            while ((count = input.read(data)) != -1) {
                current += count;
                if(listener!=null){
                    listener.onProgress((int) ((current*100)/total));
                }
                output.write(data, 0, count);
            }

            output.flush();

            output.close();
            input.close();

            if(listener!=null){
                listener.onFinish();
            }
        } catch (Exception e) {
            if(listener!=null)
                listener.onError(e.getMessage());
        }
    }

    public void setDownloaderCallback(DownloaderCallback listener){
        this.listener=listener;
    }

    public interface DownloaderCallback{
        void onProgress(int progress);
        void onFinish();
        void onError(String message);
    }
}

To use it:

Downloader dl = new Downloader("/path/to/save/file", "http://server.com/download");
dl.setDownloaderCallback(new DownloaderCallback{
    @Override
    void onProgress(int progress){

    }

    @Override
    void onFinish(){

    }

    @Override
    void onError(String message){

    }
});
dl.start();
Omar Aflak
  • 2,918
  • 21
  • 39
  • Thank for your answer, and how to show download progress in notifications ? when i try to show it, i have a bad lag on scrolling notification bar – FarshidABZ Apr 30 '16 at 09:54
  • Such a Structured Answer, which could be used as a common module. Thank you very much bro! – BharathRao Jan 22 '19 at 08:15
1

To download a file using the DownloadManager and save it to your app's private storage directory, you can pass null as the directory parameter in the setDestinationInExternalFilesDir method. This will ensure that the file is downloaded to your app's private file storage, which is not accessible to other apps or the user.

Example

val request = DownloadManager.Request(Uri.parse(fileUrl))
    .setDestinationInExternalFilesDir(context, null, fileName)

Complete Example
Here is a complete example of a function that downloads a file to your app's private folder, just pass to it the context, fileUrl, fileName and fileDescription, and you can modify it as your needs:

private fun downloadFile(
        context: Context,
        fileUrl: String,
        fileName: String,
        fileDescription: String
    ) {
        val request = DownloadManager.Request(Uri.parse(fileUrl))
            .setTitle(fileName)
            .setDescription(fileDescription)
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            .setDestinationInExternalFilesDir(context, null, "$fileName.${getFileExtension(fileUrl)}")

        val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as? DownloadManager
        downloadManager?.enqueue(request)
    }

This function is used to get the file extension to make it work without problems:

private fun getFileExtension(fileUrl: String): String {
    return MimeTypeMap.getFileExtensionFromUrl(fileUrl)
}

You can get a refrence to the private app file like this:

val privateDir = context.getExternalFilesDir(null)

Private folder path will be:

val path = "/storage/emulated/0/Android/data/com.your.package/files/"

Make sure to change "com.your.package" to your app package name.

Or you can get it from the file reference itself:

val path = privateDir?.absolutePath

Example
If you download a file "image.png", the path for the image will be:

val imagePath = "/storage/emulated/0/Android/data/com.your.package/files/image.png"
0

for your private mode you will have to encrypt the file and store it on sd card /internal. refer this

Community
  • 1
  • 1
Nilesh Deokar
  • 2,975
  • 30
  • 53
0

If you want your downloaded file in external storage, you can use.

String storagePath = Environment.getExternalStorageDirectory().getPath()+ "/Directory_name/";
//Log.d("Strorgae in view",""+storagePath);
File f = new File(storagePath);
if (!f.exists()) {
    f.mkdirs();
}
//storagePath.mkdirs();
String pathname = f.toString();
if (!f.exists()) {
    f.mkdirs();
}
//Log.d("Storage ",""+pathname);
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Uri uri = Uri.parse(image);
checkImage(uri.getLastPathSegment());
if (!downloaded) {
    DownloadManager.Request request = new DownloadManager.Request(uri);
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalPublicDir("/Directory_name", uri.getLastPathSegment());
    Long referese = dm.enqueue(request);
    Toast.makeText(getApplicationContext(), "Downloading...", Toast.LENGTH_SHORT).show();
}
Satan Pandeya
  • 3,747
  • 4
  • 27
  • 53
Vinesh Chauhan
  • 1,288
  • 11
  • 27
  • thanks, working perfectly. However we don't need 'String pathname = f.toString();' and downloaded should be set to true after download. – Amir Dora. Feb 26 '19 at 09:42