service下载

在这里插入图片描述
通过Service来模拟下载,如果把下载任务放在Activity中执行,则按返回键退出后,下载任务也会结束;但如果放在Service中,退出Activity后下载仍可继续

1:actvity_main布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:orientation="vertical">
    <Button
        android:id="@+id/btn_down"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="开始下载"
        android:layout_marginTop="30dp"
        android:textSize="18sp"
        android:onClick="onClick"
        />

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:padding="10dp"
        android:max="100"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/txt_progress"
        android:layout_width="match_parent"
        android:layout_marginLeft="5dp"
        android:layout_height="wrap_content"
        />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/button_pause"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="暂停/继续" />

        <Button
            android:id="@+id/button_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="取消" />

    </LinearLayout>


    <TextView
        android:id="@+id/text_desc"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:padding="6dp"
        style="?android:textAppearanceSmall"
        />

    <Button
        android:id="@+id/btn_open"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="打开文件"
        android:layout_gravity="center_horizontal"
        android:padding="6dp"
        android:visibility="gone"
        />


</LinearLayout>

2:Downloader类

public class Downloader {
    String urlStr;// 下载链接
    String filePath;// 下载路径
    String fileName;// 下载文件名

    DownloadListener downloadListener;

    public void setDownloadListener(DownloadListener listener) {
        this.downloadListener = listener;
    }

    public Downloader(Context context, String url, String filePath, String fileName) {
        this.urlStr = url;
        this.filePath = filePath;
        this.fileName = fileName;
    }

    public Downloader(Context context, String url, String fileName) {
        this(context, url, "/download/", fileName);
    }

    /**
     * 开始下载
     */
    public void start() {
        URL url = null;
        try {
            url = new URL(urlStr);
            HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
            urlCon.setDoInput(true);
            urlCon.setRequestMethod("GET");
            urlCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

            // 建立连接
            urlCon.connect();
            int length = urlCon.getContentLength();
            downloadListener.onStart(length);

            if (urlCon.getResponseCode() == 200) {

                File path = Environment.getExternalStoragePublicDirectory(filePath);
                File file = new File(path, fileName);
                BufferedInputStream is = new BufferedInputStream(urlCon.getInputStream());
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
                byte[] buffer = new byte[10240];
                int len = 0;
                int receivedBytes = 0;
                label: while (true) {
                    // 这里如果暂停下载,并没有真正的销毁线程,而是处于等待状态
                    // 但如果这时候用户退出了,要做处理,比如取消任务;或做其他处理

                    if (isPause)
                        downloadListener.onPause();
                    if (isCancel) {
                        downloadListener.onCancel();
                        break label;
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    while (!isPause && (len = is.read(buffer)) > 0) {
                        out.write(buffer, 0, len);
                        receivedBytes += len;
                        downloadListener.onProgress(receivedBytes);
                        if (receivedBytes == length) {
                            downloadListener.onSuccess(file);
                            break label;
                        }
                        if (isCancel) {
                            downloadListener.onCancel();
                            file.delete();
                            break label;
                        }
                    }
                }

                is.close();
                out.close();
            } else {
                Log.e("jlf", "ResponseCode:" + urlCon.getResponseCode() + ", msg:" + urlCon.getResponseMessage());
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
            downloadListener.onFail();
        } catch (IOException e) {
            e.printStackTrace();
            downloadListener.onFail();
        }
    }

    private boolean isPause;

    public void pause() {
        isPause = true;
    }

    public void resume() {
        isPause = false;
        isCancel = false;
        downloadListener.onResume();
    }

    private boolean isCancel;

    public void cancel() {
        isCancel = true;
    }

}

3:DownloadListener类

package com.bwie.progressbar;

import java.io.File;


public interface DownloadListener {

    void onStart(int fileByteSize);

    void onPause();

    void onResume();

    void onProgress(int receivedBytes);

    void onFail();

    void onSuccess(File file);

    void onCancel();

}

4:DownloadService类

public class DownloadService extends Service {
    static final int Flag_Init = 0; // 初始状态
    static final int Flag_Down = 1; // 下载状态
    static final int Flag_Pause = 2; // 暂停状态
    static final int Flag_Done = 3; // 完成状态
    String url;//下载地址
    String filetype;//文件类型
    private int progress = 0;// 下载进度
    public int getProgress() {
        return progress;
    }
    private int flag;// 下载状态标志
    public int getFlag() {
        return flag;
    }
    DownThread mThread;
    Downloader downloader;
    private static DownloadService instance;
    public static DownloadService getInstance() {
        return instance;
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.i("xuxu", "service.........onCreate");
        instance = this;
        flag = Flag_Init;
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startId) {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String msg = intent.getExtras().getString("flag");//通过标识判断下载状态
        url = intent.getExtras().getString("url");
        filetype=intent.getExtras().getString("filetype");
        if (mThread == null){
            mThread = new DownThread();
        }
        if(downloader == null)
        {
            downloader = new Downloader(this, url, filetype);
        }
        downloader.setDownloadListener(downListener);

        if (msg.equals("start"))
        {
            startDownload();
        }
        else if (msg.equals("pause"))
        {
            downloader.pause();
        }
        else if (msg.equals("resume"))
        {
            downloader.resume();
        }
        else if (msg.equals("stop"))
        {
            downloader.cancel();
            stopSelf();
        }

        return super.onStartCommand(intent, flags, startId);
    }

    private void startDownload() {
        if (flag == Flag_Init || flag == Flag_Pause) {
            if (mThread != null && !mThread.isAlive()) {
                mThread = new DownThread();
            }
            mThread.start();
        }
    }

    @Override
    public void onDestroy() {
        Log.e("xuxu", "service...........onDestroy");
        try {
            flag = 0;
            mThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mThread = null;
        super.onDestroy();
    }

    class DownThread extends Thread {

        @Override
        public void run() {

            if (flag == Flag_Init || flag == Flag_Done) {
                flag = Flag_Down;
            }

            downloader.start();
        }
    }

    /**
     * 下载监听
     */
    private DownloadListener downListener = new DownloadListener() {

        int fileSize;
        Intent intent = new Intent();

        @Override
        public void onSuccess(File file) {
            intent.setAction(MainActivity.ACTION_DOWNLOAD_SUCCESS);
            intent.putExtra("progress", 100);
            intent.putExtra("file", file);
            sendBroadcast(intent);
        }

        @Override
        public void onStart(int fileByteSize) {
            fileSize = fileByteSize;
            flag = Flag_Down;
        }

        @Override
        public void onResume() {
            flag = Flag_Down;
        }

        @Override
        public void onProgress(int receivedBytes) {
            if(flag == Flag_Down)
            {
                progress = (int)((receivedBytes / (float)fileSize) * 100);
                intent.setAction(MainActivity.ACTION_DOWNLOAD_PROGRESS);
                intent.putExtra("progress", progress);
                sendBroadcast(intent);

                if (progress == 100) {
                    flag = Flag_Done;
                }
            }
        }

        @Override
        public void onPause() {
            flag = Flag_Pause;
        }

        @Override
        public void onFail() {
            intent.setAction(MainActivity.ACTION_DOWNLOAD_FAIL);
            sendBroadcast(intent);
            flag = Flag_Init;
        }

        @Override
        public void onCancel(){
            progress = 0;
            flag = Flag_Init;
        }
    };

}

5:MainActivity

public class MainActivity extends AppCompatActivity {
    public static final String ACTION_DOWNLOAD_PROGRESS = "my_download_progress";// 下载中
    public static final String ACTION_DOWNLOAD_SUCCESS = "my_download_success";// 成功
    public static final String ACTION_DOWNLOAD_FAIL = "my_download_fail";// 失败
    String url = "https://dlie.sogoucdn.com/se/sogou_explorer_8.5_1218.exe";// 下载链接
    ProgressBar progBar;// 下载进度条
    MyReceiver receiver;// 广播
    TextView textView;// 显示下载路径
    Button btnOpen;// 打开文件
    private TextView txtProgress;
    private int FileLength;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        progBar = (ProgressBar) findViewById(R.id.progressBar1);
        textView = (TextView) findViewById(R.id.text_desc);
        btnOpen = (Button) findViewById(R.id.btn_open);
        etContent = findViewById(R.id.et_content);
        txtProgress = (TextView) findViewById(R.id.txt_progress);
        if (DownloadService.getInstance() != null) {
            progBar.setProgress(DownloadService.getInstance().getProgress());// 获取DownloadService下载进度
        }
        receiver = new MyReceiver();
    }
    @Override
    protected void onStart() {
        super.onStart();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_DOWNLOAD_PROGRESS);
        filter.addAction(ACTION_DOWNLOAD_SUCCESS);
        filter.addAction(ACTION_DOWNLOAD_FAIL);
        registerReceiver(receiver, filter);// 注册广播
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(receiver);// 注销广播
    }

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_down:// 开始下载
                startDownloadService();
                break;
            case R.id.button_pause:// 暂停下载
                pauseDownloadService();
                break;
            case R.id.button_cancel:// 取消下载
                stopDownloadService();
                break;

            default:
                break;
        }
    }

    /**
     * 开始下载
     */
    void startDownloadService() {
        if (DownloadService.getInstance() != null
                && DownloadService.getInstance().getFlag() != DownloadService.Flag_Init) {
            Toast.makeText(this, "已经在下载", Toast.LENGTH_LONG).show();
            return;
        }
        Intent it = new Intent(this, DownloadService.class);
        it.putExtra("flag", "start");
        it.putExtra("url", url);
        it.putExtra("filetype", ".doc");// 文件后缀名(注意要确认你下载的文件类型)
        startService(it);
    }

    /**
     * 暂停下载
     */
    void pauseDownloadService() {
        String flag = null;
        int f = DownloadService.getInstance().getFlag();
        if (DownloadService.getInstance() != null) {
            // 如果当前已经暂停,则恢复
            if (f == DownloadService.Flag_Pause) {
                flag = "resume";
            } else if (f == DownloadService.Flag_Down) {
                flag = "pause";
            } else {
                return;
            }
        }
        Intent it = new Intent(this, DownloadService.class);
        it.putExtra("flag", flag);
        startService(it);
    }

    /**
     * 取消下载
     */
    void stopDownloadService() {
        Intent it = new Intent(this, DownloadService.class);
        it.putExtra("flag", "stop");
        startService(it);
        progBar.setProgress(0);
    }

    class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ACTION_DOWNLOAD_PROGRESS)) {// 下载中显示进度
                int pro = intent.getExtras().getInt("progress");
                progBar.setProgress(pro);
                int x=pro;
                txtProgress.setText("当前下载进度"+x+"%");


            } else if (action.equals(ACTION_DOWNLOAD_SUCCESS)) {// 下载成功
                Toast.makeText(MainActivity.this, "下载成功", Toast.LENGTH_SHORT).show();
                final File f = (File) intent.getExtras().getSerializable("file");
                btnOpen.setVisibility(View.VISIBLE);
                textView.setText("文件已保存在:" + f.getAbsolutePath());
                btnOpen.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        openFile(f);
                    }
                });
            } else if (action.equals(ACTION_DOWNLOAD_FAIL)) {// 下载失败
                Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
            }
        }

    }

    /**
     * 打开文件
     *
     * @param f
     */
    private void openFile(File f) {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(android.content.Intent.ACTION_VIEW);
        // String type = "audio";
        String type = "application/msword";// 文件类型(word文档)
        intent.setDataAndType(Uri.fromFile(f), type);
        startActivity(intent);
    }

    /**
     * 监听返回操作
     */
    @Override
    public void onBackPressed() {
        if (DownloadService.getInstance() != null) {
            final int f = DownloadService.getInstance().getFlag();
            // XXX:暂停状态下退出???
            if (f == DownloadService.Flag_Down || f == DownloadService.Flag_Pause) {
                new AlertDialog.Builder(this).setTitle("确定退出程序?").setMessage("你有未完成的下载任务")
                        .setNegativeButton("取消下载", new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                stopDownloadService();
                                MainActivity.super.onBackPressed();
                            }
                        }).setPositiveButton("后台下载", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        if (f == DownloadService.Flag_Pause) {
                            Intent it = new Intent(MainActivity.this, DownloadService.class);
                            it.putExtra("flag", "resume");
                            startService(it);
                        }

                        MainActivity.super.onBackPressed();
                    }
                }).create().show();
                return;
            }
            DownloadService.getInstance().stopSelf();//退出停止下载(也可不用则后台下载)
        }
        super.onBackPressed();
    }

}

6:AndroidManifest.xml清单文件中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.bwie.progressbar">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
      

## <service android:name=".DownloadService"></service>

    </application>

</manifest>

猜你喜欢

转载自blog.csdn.net/weixin_43117800/article/details/86531239