安卓系统:如何将视频文件下载到SD卡?

17

我在一个网站上有一个 .MP4 格式的视频文件,我想通过点击链接允许用户将视频下载到他们的 SD 卡。有没有简单的方法可以做到这一点?我目前有这段代码,但它不起作用……不确定我做错了什么。感谢任何帮助!

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.util.ByteArrayBuffer;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class VideoManager extends Activity {
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);}



        private final String PATH = "/sdcard/download/";  //put the downloaded file here


        public void DownloadFromUrl(String VideoURL, String fileName) {  //this is the downloader method
                try {
                        URL url = new URL("http://www.ericmoyer.com/episode1.mp4"); //you can write here any link
                        File file = new File(fileName);

                        long startTime = System.currentTimeMillis();
                        Log.d("VideoManager", "download begining");
                        Log.d("VideoManager", "download url:" + url);
                        Log.d("VideoManager", "downloaded file name:" + fileName);
                        /* Open a connection to that URL. */
                        URLConnection ucon = url.openConnection();

                        /*
                         * Define InputStreams to read from the URLConnection.
                         */
                        InputStream is = ucon.getInputStream();
                        BufferedInputStream bis = new BufferedInputStream(is);

                        /*
                         * Read bytes to the Buffer until there is nothing more to read(-1).
                         */
                        ByteArrayBuffer baf = new ByteArrayBuffer(50);
                        int current = 0;
                        while ((current = bis.read()) != -1) {
                                baf.append((byte) current);
                        }

                        /* Convert the Bytes read to a String. */
                        FileOutputStream fos = new FileOutputStream(PATH+file);
                        fos.write(baf.toByteArray());
                        fos.close();
                        Log.d("VideoManager", "download ready in"
                                        + ((System.currentTimeMillis() - startTime) / 1000)
                                        + " sec");

                } catch (IOException e) {
                        Log.d("VideoManager", "Error: " + e);
                }

        }
}

你确定路径 /sdcard/download/ 存在吗?你可以通过 adb shell 创建它。 - Sameer Segal
2个回答

39

难道你没有出现内存不足的情况吗?我想视频文件非常大,你需要在写入文件之前对其进行缓冲。

我知道你的示例代码在互联网上很流行,但是它对于下载来说很糟糕!请使用以下代码:

private final int TIMEOUT_CONNECTION = 5000;//5sec
private final int TIMEOUT_SOCKET = 30000;//30sec


            URL url = new URL(imageURL);
            long startTime = System.currentTimeMillis();
            Log.i(TAG, "image download beginning: "+imageURL);

            //Open a connection to that URL.
            URLConnection ucon = url.openConnection();

            //this timeout affects how long it takes for the app to realize there's a connection problem
            ucon.setReadTimeout(TIMEOUT_CONNECTION);
            ucon.setConnectTimeout(TIMEOUT_SOCKET);


            //Define InputStreams to read from the URLConnection.
            // uses 3KB download buffer
            InputStream is = ucon.getInputStream();
            BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
            FileOutputStream outStream = new FileOutputStream(file);
            byte[] buff = new byte[5 * 1024];

            //Read bytes (and store them) until there is nothing more to read(-1)
            int len;
            while ((len = inStream.read(buff)) != -1)
            {
                outStream.write(buff,0,len);
            }

            //clean up
            outStream.flush();
            outStream.close();
            inStream.close();

            Log.i(TAG, "download completed in "
                    + ((System.currentTimeMillis() - startTime) / 1000)
                    + " sec");5

2
添加了 outStream.flush(); 语句后,解决了0字节文件的问题。 - Someone Somewhere
1
能否在视频正在下载的同时播放它?也就是说,假设one.mp4正在下载中,是否可以使用MediaPlayer在下载过程中播放同一个视频? - Scorpion
代码运行得非常好,但是否有办法从中间下载视频。也就是说,如果出现任何互联网连接问题,它会从头开始。如何避免这种情况。 - Kartheek Sarabu
我以前实现过那种功能...但目前不可获取源代码。我记得该功能依赖于服务器,即服务器必须支持从特定字节偏移量处下载。 - Someone Somewhere
1
很好的答案,我已经使用了代码,它没有错误。它可以从URL下载实时视频流,但文件损坏,只有几KB。 - Rahul Matte
显示剩余4条评论

24

不要将路径硬编码,特别是对于外部存储。在许多设备上,您的路径是错误的。使用Environment.getExternalStoragePath()来获取外部存储的根目录(可能是/sdcard/mnt/sdcard或其他内容)。

一定要使用从Environment.getExternalStoragePath()返回的File对象创建您的子目录。

最后,请不要仅仅说“但是它不起作用”。我们不知道在您的情况下,“但是它不起作用”意味着什么。没有这些信息,很难帮助您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接