简体   繁体   中英

PhoneGap 3.1 Android copy audio file from www folder to SD card

Here is the problem. I got an app that download audio files to the phone then play it back. All works without problem. But the little problem is - the customer wants to have something that play straight away when the other files are being download.

So I put an short audio in the www/files/ folder. That works without any issue with iOS. I just reference it (from media player) as

document.addEventListener('deviceready' , function() 
{
    var media = new Media('files/default.m4a' , function()
    {
        // this success call back never works!
    });
    setTimeout(function()
    {
         media.play();
    },100);
});

Now the problem is Android. Got a FileError.NOT_FOUND_ERR error. Looking at LogCat (From Android studio)

The path become

 /mnt/sdcard/files/default.m4a

It seems that Android couldn't handle a relative path like iOS (strange enough all the images or template are relative path in the js app. And they all work fine).

Been searching up and down a solution how do I copy just that one audio file to the sd card. no luck so far. The problem is I couldn't correctly find the absolute path to the original file. There are lots of example out there which is total BS. They hardcoded the path in! Android can be anything, in the emulator is /mnt/sdcard/ on my test device turns into /external/sdcard0

And that just from (java):

   String path  = Environment.getExternalStorageDirectory().getAbsolutePath();

I seen tons and tons of people got the same problem. But the solution out there are pretty out date. Or not really solve the first problem (which is finding out where is the original file in the first place). There must be one problem many people face right?

Thanks in advance.

PS I also try this

 this.getClass().getPackage().getName();

call from inside the onCreate method. That only got me partial but not the absolute path.

UPDATE

Here is the complete working code (for PhoneGap 3.1)

package YOUR_PACKAGE_NAME;

import android.os.Bundle;
import org.apache.cordova.*;

/* for the other two plugins */
import java.io.*;
import android.os.Environment;
import android.util.Log;
import android.content.res.AssetManager;

public class YourAppName extends CordovaActivity 
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        super.init();

        this.CopyAssets();

        super.loadUrl(Config.getStartUrl());
    }

    private void CopyAssets() {
        AssetManager assetManager = getAssets();
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(FILE_YOU_WANT_TO_COPY_IN_WWW); 
            out = new FileOutputStream(Environment.getExternalStorageDirectory()
                 .toString()
                + WHERE_YOU_WANT_TO_PUT_IT_PLUS_NAME);
            this.copyFile(in, out);
            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
        } catch (Exception e) {
            Log.e("tag", e.getMessage());
        }
    }

    private void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
    }
}

Try this :

    public class testsample extends DroidGap {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Set by <content src="index.html" /> in config.xml
            CopyAssets();
            super.setIntegerProperty("loadUrlTimeoutValue", 6000);
            super.loadUrl(Config.getStartUrl());
        }

        private void CopyAssets() {
            AssetManager assetManager = getAssets();

            InputStream in = null;
            OutputStream out = null;
            try {
                in = assetManager.open("www/img/logo.png"); // if files resides
                                                            // inside the "Files"
                                                            // directory itself

                // "www/img/logo.png"  is path of assets/www folder 

                out = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()
                        + "/"
                        + "logo.png");
                copyFile(in, out);
                in.close();
                in = null;
                out.flush();
                out.close();
                out = null;
            } catch (Exception e) {
                Log.e("tag", e.getMessage());
            }
        }

        private void copyFile(InputStream in, OutputStream out) throws IOException {
            byte[] buffer = new byte[1024];
            int read;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
        }
    }

Do't Forget to Add Permission on AndroidManifest.xml

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

A cleaner option is to install the org.apache.cordova.file-transfer plugin and transfer the file from "file:///android_asset/www/song.mp3" to /YourApp/song.mp3

cordova plugin add org.apache.cordova.file@1.1.0
cordova plugin add org.apache.cordova.file-transfer

And then:

//    Assumes variable fileURL contains a valid URL to a path on the device,
//    for example, cdvfile://localhost/persistent/path/to/downloads/

var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");

fileTransfer.download(
    uri,
    fileURL,
    function(entry) {
        console.log("download complete: " + entry.toURL());
    },
    function(error) {
        console.log("download error source " + error.source);
        console.log("download error target " + error.target);
        console.log("upload error code" + error.code);
    },
    false,
    {
        //headers: {
        //    "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
        //}
    }
);

More info here: https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md

This way you only wave to worry about your javascript

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM