user3183842
user3183842

Reputation: 13

Cordova /Phonegap Native File Download Plugin with progressbar

Am making an android Phonegap app that Downloads mp3 files and stores it in the Music directory on the Device's Sd card.

I stumbled on a native android cordova plugin that handles the Files download.It even has a progressbar.

My problem is that.The Plugin after completing a File download always stores the File in the phone's internal storage and not in the Music directory on the Phone's Sd card.

i'd be grateful if someone can modify the plugin to save downloaded files directly into the music directory.

I posted the code in the Download.java file of the Plugin below.

package com.cmpsoft.mobile.plugin.download;

   import java.io.File;
   import java.io.FileNotFoundException;
   import java.io.FileOutputStream;
   import java.io.IOException;
   import java.io.InputStream;
   import java.net.HttpURLConnection;
   import java.net.MalformedURLException;
   import java.net.URL;

   import org.apache.cordova.CallbackContext;
   import org.apache.cordova.CordovaPlugin;
   import org.json.JSONArray;
   import org.json.JSONException;
   import android.annotation.SuppressLint;
   import android.app.AlertDialog;
   import android.app.Dialog;
   import android.app.AlertDialog.Builder;
   import android.content.Context;
   import android.content.DialogInterface;
   import android.content.Intent;
   import android.net.Uri;
   import android.os.Environment;
   import android.os.Handler;
   import android.os.Message;
   import android.view.Gravity;
   import android.view.ViewGroup.LayoutParams;
   import android.widget.LinearLayout;
   import android.widget.ProgressBar;
   import android.widget.TextView;
    import android.widget.Toast;

    @SuppressLint({ "DefaultLocale", "HandlerLeak" })
    public class DownLoad extends CordovaPlugin {

/ / The following layout parameters
   / / Identify the current situation of the control width and height FILL_PARENT =   occupy all parent controls, WRAP_CONTENT = only the contents of the package control / /   There are other effects such as left and right margins, where we use the default

@SuppressWarnings("deprecation")
private LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(
        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
private LinearLayout.LayoutParams LP_WW = new LinearLayout.LayoutParams(
        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

private String fileName;
private String path;
private boolean openFlag;

/ * Download * /
private static final int DOWNLOAD = 1;
/ * Download end * /
private static final int DOWNLOAD_FINISH = 2;
/ * Download save path * /
private String mSavePath;
/ * Record progress bar number * /
private int progress;
/ * Whether to cancel the update * /
private boolean cancelUpdate ;

private Context mContext;
/ * Update progress bar * /
private ProgressBar mProgress;
private Dialog mDownloadDialog;
private TextView textView;
/ * Open the file types * /
private final String[][] type_amp = {
        { ".3gp", "video/3gpp" },
        { ".apk", "application/vnd.android.package-archive" },
        { ".asf", "video/x-ms-asf" },
        { ".avi", "video/x-msvideo" },
        { ".bin", "application/octet-stream" },
        { ".bmp", "image/bmp" },
        { ".c", "text/plain" },
        { ".class", "application/octet-stream" },
        { ".conf", "text/plain" },
        { ".cpp", "text/plain" },
        { ".doc", "application/msword" },
        { ".docx",
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
        { ".xls", "application/vnd.ms-excel" },
        { ".xlsx",
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
        { ".exe", "application/octet-stream" },
        { ".gif", "image/gif" },
        { ".gtar", "application/x-gtar" },
        { ".gz", "application/x-gzip" },
        { ".h", "text/plain" },
        { ".htm", "text/html" },
        { ".html", "text/html" },
        { ".jar", "application/java-archive" },
        { ".java", "text/plain" },
        { ".jpeg", "image/jpeg" },
        { ".jpg", "image/jpeg" },
        { ".js", "application/x-javascript" },
        { ".log", "text/plain" },
        { ".m3u", "audio/x-mpegurl" },
        { ".m4a", "audio/mp4a-latm" },
        { ".m4b", "audio/mp4a-latm" },
        { ".m4p", "audio/mp4a-latm" },
        { ".m4u", "video/vnd.mpegurl" },
        { ".m4v", "video/x-m4v" },
        { ".mov", "video/quicktime" },
        { ".mp2", "audio/x-mpeg" },
        { ".mp3", "audio/x-mpeg" },
        { ".mp4", "video/mp4" },
        { ".mpc", "application/vnd.mpohun.certificate" },
        { ".mpe", "video/mpeg" },
        { ".mpeg", "video/mpeg" },
        { ".mpg", "video/mpeg" },
        { ".mpg4", "video/mp4" },
        { ".mpga", "audio/mpeg" },
        { ".msg", "application/vnd.ms-outlook" },
        { ".ogg", "audio/ogg" },
        { ".pdf", "application/pdf" },
        { ".png", "image/png" },
        { ".pps", "application/vnd.ms-powerpoint" },
        { ".ppt", "application/vnd.ms-powerpoint" },
        { ".pptx",
                "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
        { ".prop", "text/plain" }, { ".rc", "text/plain" },
        { ".rmvb", "audio/x-pn-realaudio" }, { ".rtf", "application/rtf" },
        { ".sh", "text/plain" }, { ".tar", "application/x-tar" },
        { ".tgz", "application/x-compressed" }, { ".txt", "text/plain" },
        { ".wav", "audio/x-wav" }, { ".wma", "audio/x-ms-wma" },
        { ".wmv", "audio/x-ms-wmv" },
        { ".wps", "application/vnd.ms-works" }, { ".xml", "text/plain" },
        { ".z", "application/x-compress" },
        { ".zip", "application/x-zip-compressed" }, { "", "*/*" } };

@Override
public boolean execute(String action, JSONArray args,
        CallbackContext callbackContext) throws JSONException {
    init(args.getString(0),args.getString(1),args.getBoolean(2));
    showDownloadDialog();
    return super.execute(action, args, callbackContext);
}

private void init(String path,String fileName,boolean openFlag){
    this.mContext = this.cordova.getActivity();
    this.path = path;
    this.fileName = fileName;
    this.openFlag = openFlag;
    this.cancelUpdate = false;
}

/ **
   * Display software download dialog
  * /
private void showDownloadDialog() {
    AlertDialog.Builder builder = new Builder(mContext);
    builder.setTitle("Downloading Music");
    / / Add a linear layout
    LinearLayout layout = new LinearLayout(mContext);
    layout.setLayoutParams(LP_FW);
    / / Set the child controls to center
    layout.setGravity(Gravity.CENTER);
    layout.setOrientation(LinearLayout.VERTICAL); 
            / / Controls on its way to the  vertical, horizontal default
            / / Create a progress bar
    mProgress = new ProgressBar(mContext, null,
            android.R.attr.progressBarStyleHorizontal);
    mProgress.setLayoutParams(LP_FW);
    layout.addView(mProgress);
    // 创建百分比现实textview
    textView = new TextView(mContext);
    textView.setLayoutParams(LP_WW);
    layout.addView(textView);
    builder.setView(layout);
    / / Cancel the update
    builder.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                                        / / Set the cancel state "̬
                    cancelUpdate = true;
                }
            });
    mDownloadDialog = builder.create();
    mDownloadDialog.show();
    / / Download file
    downloadFile();
}

/ **
   * According to the document type to get open
   *
   * @ Param file
   * @ Return
   * /
@SuppressLint("DefaultLocale")
private String getOpenType(File file) {
    String type = "*/*";
    String fName = file.getName();
    / / Get the extension delimiter before "." FName in position.
    int dotIndex = fName.lastIndexOf(".");
    if (dotIndex > 0) {
        return type;
    }
    / * Get the file extension * /
    String end = fName.substring(dotIndex, fName.length()).toLowerCase();
    if (end == "")
        return type;
    / / Find the corresponding file type MIME type matching table.
    for (int i = 0; i < type_amp.length; i++) {
        if (end.equals(type_amp[i][0]))
            type = type_amp[i][1];
    }
    return type;
}

/ **
   * Open the file
    * /
private void openFile() {
    File file  = new File(mSavePath,fileName);
    if (!file.exists()) {
        return;
    }
    / / Install APK files via Intent
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.setDataAndType(Uri.parse("file://" + file.toString()),
            getOpenType(file));
    try {
        mContext.startActivity(i);
    } catch (Exception e) {
        Toast.makeText(mContext, "Unable To Open" + file.getName(),
                Toast.LENGTH_SHORT).show();
    }

};

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        / / Downloading
        case DOWNLOAD:
            / / Downloading...
            mProgress.setProgress(progress);
            / / Set the percentage
            textView.setText(progress + "%");
            break;
        case DOWNLOAD_FINISH:
            / / Setup file
            if(openFlag){
                openFile();
            }
            break;
        default:
            break;
        }
    }

};

/ **
   * Download file
   * /
private void downloadFile() {
    / / Start a new thread to download file
    new DownloadFileThread().start();

}
class DownloadFileThread extends Thread {
    @Override
    public void run() {
        try {
/ / Determine whether there is an SD card, and whether the     read and write permissions
                URL url = new URL(path);
                / / Create connection
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                conn.connect();
                / / Get the file size
                int length = conn.getContentLength();
                / / Create an input stream
                InputStream is = conn.getInputStream();

                FileOutputStream fos = getOutStream(fileName);
                int count = 0;
                / / Cache
                byte buf[] = new byte[1024];
                / / Write to a file
                do {
                    int numread = is.read(buf);
                    count += numread;
        / / Calculate the position of the progress bar
                    progress = (int) (((float) count / length) * 100);
                    / / Update progress
                    mHandler.sendEmptyMessage(DOWNLOAD);
                    if (numread <= 0) {
                        / / Download is complete
                        mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
                        break;
                    }
                    / / Write to file
                    fos.write(buf, 0, numread);
                } while (!cancelUpdate);/ / Click Cancel to stop  downloading.
                fos.close();
                is.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
        / / Cancel the download dialog box displays
        mDownloadDialog.dismiss();
    }

}
/**
    * @param fileName
    * @return
    * @throws FileNotFoundException
   */
@SuppressWarnings("deprecation")
@SuppressLint("WorldReadableFiles")
private FileOutputStream getOutStream(String fileName) throws FileNotFoundException{
    if (Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED)) {
        String sdpath = Environment.getExternalStorageDirectory()
                + "/";
        mSavePath = sdpath + "download";
        File file = new File(mSavePath);
        / / Determine the file directory exists
        if (!file.exists()) {
            file.mkdir();
        }
        File saveFile = new File(mSavePath, fileName);
        return new FileOutputStream(saveFile);
    }else{
        mSavePath = mContext.getFilesDir().getPath();/ / Get the system directory to store files /data/data/<package name>/files  
        return mContext.openFileOutput(fileName , Context.MODE_WORLD_READABLE);
    }
}

}

Upvotes: 0

Views: 1422

Answers (1)

Simon MacDonald
Simon MacDonald

Reputation: 23273

The quick and easy fix is to replace:

String sdpath = Environment.getExternalStorageDirectory()
            + "/";

with

String sdpath = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_MUSIC)
            + "/";

However, I'd love to update this plugin so you can specify the apps internal storage or external storage. If external storage you should have the options for Music, Pictures, Movies, Podcasts or Downloads.

If the source is up on Github somewhere let me know.

Upvotes: 0

Related Questions