以下是使用 Android Service 实现文件下载功能的完整代码示例:

MainActivity.java

package com.example.sh3;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.Manifest;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private DownloadService.DownloadBinder downloadBinder;
    private boolean isContinue = false;
    private boolean isDownload = false;
    private TextView downloadProgress;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (DownloadService.DownloadBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startDownload = findViewById(R.id.start_download);
        Button pauseDownload = findViewById(R.id.pause_download);
        Button cancelDownload = findViewById(R.id.cancel_download);
        downloadProgress = findViewById(R.id.download_progress);

        pauseDownload.setEnabled(true);
        cancelDownload.setEnabled(false);
        startDownload.setOnClickListener(this);
        pauseDownload.setOnClickListener(this);
        cancelDownload.setOnClickListener(this);
        Intent intent = new Intent(this, DownloadService.class);
        startService(intent);//启动服务
        bindService(intent,connection,BIND_AUTO_CREATE);//绑定服务
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }
    }

    @Override
    public void onClick(View v) {
        EditText edittext=(EditText) findViewById(R.id.edit);
        String url,site;
        url=edittext.getText().toString();
        // Toast.makeText(this, site, Toast.LENGTH_SHORT).show();
        if(url.equals(''))
            url= 'https://www.imooc.com/mobile/mukewang.apk';
        // editText.setText(url);

        if (downloadBinder == null) {
            return;
        }
        Button startDownload = findViewById(R.id.start_download);
        Button pauseDownload = findViewById(R.id.pause_download);
        Button cancelDownload = findViewById(R.id.cancel_download);
        int id = v.getId();
        if (id == R.id.start_download) {
            downloadBinder.startDownload(url);
            isDownload = true;
            startDownload.setEnabled(false);
            pauseDownload.setEnabled(true);
            cancelDownload.setEnabled(true);
            downloadProgress.setVisibility(View.VISIBLE); // 显示下载进度
        } else if (id == R.id.pause_download) {
            if (isDownload) {
                if (!isContinue) {
                    downloadBinder.pauseDownload();
                    pauseDownload.setText('继续下载');
                    pauseDownload.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                    isContinue = true;
                } else {
                    downloadBinder.startDownload(url);
                    pauseDownload.setText('暂停下载');
                    pauseDownload.setBackgroundColor(getResources().getColor(R.color.colorGray));
                    isContinue = false;
                }
            } else {
                Toast.makeText(this, '请先点击下载', Toast.LENGTH_SHORT).show();
            }
        } else if (id == R.id.cancel_download) {
            downloadBinder.cancelDownload();
            startDownload.setEnabled(true);
            pauseDownload.setEnabled(true);
            cancelDownload.setEnabled(false);
            pauseDownload.setBackgroundColor(getResources().getColor(R.color.colorGray));
            downloadProgress.setVisibility(View.GONE); // 隐藏下载进度
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 1:
                if(grantResults.length>0&&grantResults[0]!=PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(this,'拒绝权限无法使用程序',Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }

    private void updateDownloadProgress(int progress) {
        downloadProgress.setText('下载进度:' + progress + '%');
    }
}

DownloadService.java

package com.example.sh3;

import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class DownloadService extends Service {

    private DownloadTask downloadTask;
    private String downloadUrl;
    private int lastProgress;

    private DownloadBinder binder = new DownloadBinder();

    class DownloadBinder extends Binder {

        public void startDownload(String url) {
            if (downloadTask == null) {
                downloadUrl = url;
                downloadTask = new DownloadTask();
                downloadTask.execute(downloadUrl);
            }
        }

        public void pauseDownload() {
            if (downloadTask != null) {
                downloadTask.pauseDownload();
            }
        }

        public void cancelDownload() {
            if (downloadTask != null) {
                downloadTask.cancelDownload();
            }
        }

        public void updateDownloadProgress(int progress) {
            if (downloadTask != null) {
                downloadTask.updateDownloadProgress(progress);
            }
        }

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    private class DownloadTask extends AsyncTask<String, Integer, Integer> {

        private boolean isPaused = false;
        private boolean isCanceled = false;

        @Override
        protected Integer doInBackground(String... params) {
            InputStream is = null;
            RandomAccessFile savedFile = null;
            File file = null;
            try {
                long downloadedLength = 0; // 记录已下载的文件长度
                String downloadUrl = params[0];
                String fileName = downloadUrl.substring(downloadUrl.lastIndexOf('/'));
                String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
                file = new File(directory + fileName);
                if (file.exists()) {
                    downloadedLength = file.length();
                }
                long contentLength = getContentLength(downloadUrl);
                if (contentLength == 0) {
                    return 0; // 下载文件长度为0,下载失败
                } else if (contentLength == downloadedLength) {
                    return 1; // 下载文件长度等于已下载的文件长度,下载成功
                }
                HttpURLConnection connection = (HttpURLConnection) new URL(downloadUrl).openConnection();
                connection.setRequestMethod('GET');
                connection.setRequestProperty('Range', 'bytes=' + downloadedLength + '-');
                connection.setConnectTimeout(8000);
                connection.setReadTimeout(8000);
                is = connection.getInputStream();
                savedFile = new RandomAccessFile(file, 'rw');
                savedFile.seek(downloadedLength);
                byte[] b = new byte[1024];
                int total = 0;
                int len;
                while ((len = is.read(b)) != -1) {
                    if (isPaused) {
                        return 2; // 下载暂停
                    } else if (isCanceled) {
                        file.delete();
                        return 3; // 下载取消
                    } else {
                        total += len;
                        savedFile.write(b, 0, len);
                        int progress = (int) ((total + downloadedLength) * 100 / contentLength);
                        publishProgress(progress);
                    }
                }
                connection.disconnect();
                return 1; // 下载成功
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (is != null) {
                        is.close();
                    }
                    if (savedFile != null) {
                        savedFile.close();
                    }
                    if (isCanceled && file != null) {
                        file.delete();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return 0; // 下载失败
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            int progress = values[0];
            if (progress > lastProgress) {
                Log.d('DownloadService', 'Download progress: ' + progress + '%');
                lastProgress = progress;
            }
        }

        @Override
        protected void onPostExecute(Integer status) {
            switch (status) {
                case 0:
                    Log.d('DownloadService', 'Download failed');
                    break;
                case 1:
                    Log.d('DownloadService', 'Download success');
                    break;
                case 2:
                    Log.d('DownloadService', 'Download paused');
                    break;
                case 3:
                    Log.d('DownloadService', 'Download canceled');
                    break;
                default:
                    break;
            }
        }

        public void pauseDownload() {
            isPaused = true;
        }

        public void cancelDownload() {
            isCanceled = true;
        }

        public void updateDownloadProgress(int progress) {
            publishProgress(progress);
        }

        private long getContentLength(String downloadUrl) {
            try {
                HttpURLConnection connection = (HttpURLConnection) new URL(downloadUrl).openConnection();
                connection.setRequestMethod('GET');
                connection.setConnectTimeout(8000);
                connection.setReadTimeout(8000);
                connection.connect();
                if (connection.getResponseCode() == 200) {
                    return connection.getContentLength();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
    }
}

activity_main.xml

<RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android'
    xmlns:tools='http://schemas.android.com/tools'
    android:layout_width='match_parent'
    android:layout_height='match_parent'
    android:paddingLeft='16dp'
    android:paddingTop='16dp'
    android:paddingRight='16dp'
    android:paddingBottom='16dp'
    tools:context='.MainActivity'>

    <EditText
        android:id='@+id/edit'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:hint='请输入下载链接' />

    <Button
        android:id='@+id/start_download'
        android:layout_width='wrap_content'
        android:layout_height='wrap_content'
       
        android:text='开始下载' />

    <Button
        android:id='@+id/pause_download'
        android:layout_width='wrap_content'
        android:layout_height='wrap_content'
        android:layout_below='@+id/start_download'
        android:text='暂停下载' />

    <Button
        android:id='@+id/cancel_download'
        android:layout_width='wrap_content'
        android:layout_height='wrap_content'
        android:layout_below='@+id/pause_download'
        android:text='取消下载' />

    <TextView
        android:id='@+id/download_progress'
        android:layout_width='wrap_content'
        android:layout_height='wrap_content'
        android:layout_below='@+id/cancel_download'
        android:text='下载进度:0%' />

</RelativeLayout>

代码说明

  1. MainActivity

    • 申请写外部存储权限
    • 创建一个 ServiceConnection 对象用于绑定服务
    • 创建三个按钮:开始下载、暂停下载和取消下载
    • 设置按钮点击监听器,分别调用服务中的对应方法
  2. DownloadService

    • 创建一个 DownloadBinder 类,用于暴露服务的方法给 Activity
    • 创建一个 DownloadTask 类,继承自 AsyncTask,用于执行下载操作
    • 在 DownloadTask 中实现下载逻辑,包括:
      • 获取下载链接和文件名
      • 创建文件并写入数据
      • 计算下载进度并更新 UI
      • 处理下载暂停、取消等操作
  3. activity_main.xml

    • 包含一个 EditText 用于输入下载链接
    • 包含三个 Button 用于控制下载
    • 包含一个 TextView 用于显示下载进度

使用方法

  1. 在 EditText 中输入要下载的链接
  2. 点击 '开始下载' 按钮开始下载
  3. 点击 '暂停下载' 按钮暂停下载
  4. 点击 '继续下载' 按钮继续下载
  5. 点击 '取消下载' 按钮取消下载

注意

  • 需要在 AndroidManifest.xml 中声明 DownloadService 和相应的权限
  • 需要在代码中添加对下载进度和状态的处理逻辑
  • 下载文件存储在手机的 /storage/emulated/0/Download 目录下
Android 下载服务示例:使用 Service 实现文件下载功能

原文地址: https://www.cveoy.top/t/topic/Nh7 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录