Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅在WiFi上在后台下载大文件_Java_Android_Download_Android Service_Android Wifi - Fatal编程技术网

Java 仅在WiFi上在后台下载大文件

Java 仅在WiFi上在后台下载大文件,java,android,download,android-service,android-wifi,Java,Android,Download,Android Service,Android Wifi,因此,我试图实现的是创建一个服务,将一个约200 MB的大文件下载到应用程序的内部目录。它应该恢复,而不是在被取消时重新启动,并在系统重新启动后自动恢复。它有时应该写在属性文件中,仅使用WiFi连接下载 为此,我创建了一个IntentService,这是一个合适的解决方案吗?启动后由Frgament的UI或BroadcastReceiver启动: @Override public void onHandleIntent(final Intent intent) {

因此,我试图实现的是创建一个服务,将一个约200 MB的大文件下载到应用程序的内部目录。它应该恢复,而不是在被取消时重新启动,并在系统重新启动后自动恢复。它有时应该写在属性文件中,仅使用WiFi连接下载

为此,我创建了一个IntentService,这是一个合适的解决方案吗?启动后由Frgament的UI或BroadcastReceiver启动:

@Override
     public void onHandleIntent(final Intent intent) {
            c.registerReceiver(receiver, new IntentFilter(
                            ConnectivityManager.CONNECTIVITY_ACTION));
            c.registerReceiver(receiver, new IntentFilter(
                            WifiManager.NETWORK_STATE_CHANGED_ACTION));
            receiver.onReceive(null, null); // To start the download the first time
}
最后一行调用处理下载过程的BroadcastReceiver。这就是我试图确保一次只有一个正在进行的下载的方式:

BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        boolean allowed = isConnectionAllowed();

        if (allowed && !thread.isAlive()) {

            thread.start();

        } else if (allowed && thread.isAlive()) {

            thread.notify(); // Can this cause any problems in this  case?

        } else if (!allowed && thread.isAlive()) {

            try {

                thread.wait();

            } catch (InterruptedException e) {
                if (StartActivity.DEV_MODE)
                    Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
            }
        }
    }
};
而下载itsev在一个单独的线程中运行

为了确保WiFi连接保持活跃,我使用WifiLock类

注意:我在一些情况下缩短了代码,但我已经成功地编写了代码

所以我不确定这是否是解决我问题的好办法:

我应该为此使用IntentService还是普通服务? 使用线程的解决方案好吗?它会工作吗? HttpURLConnection不会过期吗? 我可以用那种方式访问线程吗?推荐等待并通知 我知道这是很多代码,但这是我能得到的最接近的。我希望有人知道一个解决方案,因为我找不到任何有用的主题,只有在使用谷歌和StackOverflow的WiFi下载

提前感谢,, 费利克斯


如果需要全班同学,请发表评论

OK。”浏览次数:32次。我做错什么了吗?有什么信息丢失吗?这离题了吗?请评论以获取反馈。有什么建议吗?有什么想法吗?@felixd:这个问题解决了吗?@HarishKoona不幸的是,还没有。你有概念吗?我可能会在将来某个时候开始发奖金,但我现在没有那么大的声誉。
private Thread thread = new Thread() {
    @SuppressWarnings("resource")
    @Override
    public void run() {

        HttpURLConnection connection = null;
        BufferedInputStream input = null;
        RandomAccessFile output = null;

        try {

            long already_downloaded = 0;

            URL url = new URL(getSource());
            File outputFileCache = new File(getDestination());
            connection = (HttpURLConnection) url.openConnection();

            if (outputFileCache.exists()) {
                connection.setAllowUserInteraction(true);
                connection.setRequestProperty("Range", "bytes="
                        + outputFileCache.length() + "-");
            }

            connection.setConnectTimeout(14000);
            connection.setReadTimeout(20000);
            connection.connect();

            if (connection.getResponseCode() / 100 != 2)
                throw new Exception("Invalid response code!");

            else {
                String connectionField = connection
                        .getHeaderField("content-range");

                if (connectionField != null) {
                    String[] connectionRanges = connectionField.substring(
                            "bytes=".length()).split("-");
                    already_downloaded = Long.valueOf(connectionRanges[0]);
                }

                if (connectionField == null && outputFileCache.exists())
                    outputFileCache.delete();

                long fileLength = connection.getContentLength()
                        + already_downloaded;
                input = new BufferedInputStream(connection.getInputStream());
                output = new RandomAccessFile(outputFileCache, "rw");
                output.seek(already_downloaded);

                byte data[] = new byte[1024];
                int count = 0;
                int progress = 0;
                int progress_last_value = 0;

                while ((count = input.read(data, 0, 1024)) != -1
                        && progress != 100) {
                    already_downloaded += count;
                    output.write(data, 0, count);

                    progress = (int) ((already_downloaded * 100) / fileLength);
                    if (progress != progress_last_value) {
                                // Update notification
                    }
                }
            }

        } catch (MalformedURLException e) {
            if (StartActivity.DEV_MODE)
                Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
        } catch (IOException e) {
            if (StartActivity.DEV_MODE)
                Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
        } catch (Exception e) {
            if (StartActivity.DEV_MODE)
                Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));

        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
                if (connection != null)
                    connection.disconnect();
            } catch (IOException e) {
                if (StartActivity.DEV_MODE)
                    Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
            }
        }

        // notify the Fragment using a `LocalBroadcast`.
    }
};