• 最佳下载实例


    Download。interface

    package lbstest.example.com.lbs.ServiceBestPractice;
    
    /**
     * 功能:对下载过程中的各种状态进行监听
     * Created by bummer on 2017/7/26.
     */
    
    public interface DownloadListener {
        void onProgress(int progress); //用于通知当前的下载进度
        void onSuccess();              //用于通知下载成功事件
        void onFailed();               //用于通知下载失败事件
        void onPaused();               //用于通知下载暂停事件
        void onCanceled();             //用于通知下载取消事件
    }
    

    DownloadTask.java

    package lbstest.example.com.lbs.ServiceBestPractice;
    
    import android.os.AsyncTask;
    import android.os.Environment;
    import android.util.Log;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.RandomAccessFile;
    
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    
    /**
     * Created by bummer on 2017/7/26.
     */
    
    /**
     * params AsyncTask 中的三个泛型参数
     * String 需要传入一个字符串给给后台任务
     * Integer 整型数据表示进度显示的单位
     * Integer 整型数据反馈执行的结果
     */
    public class DownloadTask extends AsyncTask <String,Integer,Integer>{
    
        public final static int TYPE_SUCCESS = 0; //表示下载成功
        public final static int TYPE_FAILED = 1;  //表示下载失败
        public final static int TYPE_PAUSED = 2;  //表示下载暂停
        public final static int TYPE_CANCELED = 3;//表示下载取消
    
        private DownloadListener listener;
    
        private boolean isCanceled = false;
    
        private boolean isPaused = false;
    
        private int lastProgress;
        //在DownloadTask的构造函数中传入一个刚定义的DownloadListener参数,我们待会会将下载的状态通过这个状态进行回调
        public DownloadTask(DownloadListener listener) {
            this.listener = listener;
        }
    
        /**
         *   功能:后台执行的具体的下载逻辑
         *
         * @param params
         * @return
         */
        @Override
        protected Integer doInBackground(String... params) {
            InputStream is = null;
            RandomAccessFile savedFile = null;
            File file = null;
    
            try {
                long downloadLength = 0; //记录下载文件长度
    //            从参数中获得了下载的URL地址
                String downloadUrl = params[0];
    //            并根据URL地址解析出了下载的文件名
                String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
    //            将指定的文件下载到Environment.DIRECTORY_DOWNLOADS目录,也就是SD卡的Download目录
                String directory = Environment.getExternalStoragePublicDirectory
                        (Environment.DIRECTORY_DOWNLOADS).getPath();
                file = new File(directory + fileName);
                Log.d("File","file is"+file+"  "+"directory is "+directory+"  "+"fileName is"+fileName);
                //判断Download中是否已经存在要下载的文件了
                if (file.exists()){
                    //如果存在则读取已下载的字节数 这样后面就能实现断点续传的功能
                    downloadLength = file.length();
                }
                //调用getContentLength()方法获得文件的总长度
                long contentLength = getContentLength(downloadUrl);
                if (contentLength == 0){
                    //如果文件长度为0,说明文件有问题
                    return TYPE_FAILED;
                }else if (contentLength == downloadLength){
                    //已下载字节和文件总字节相等,说明已经下载完成了
                    return TYPE_SUCCESS;
                }
                //使用OKhttp发送网络请求
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder()
                        //断点下载,指定从哪个字节开始下载
                        .addHeader("RANGE","bytes="+downloadLength + "-")
                        .url(downloadUrl)
                        .build();
                Response response = client.newCall(request).execute();
                //读取服务器响应的数据,并使用java的IO流的方式,不断从网络上读取数据,不断写入到本地
                if(response != null){
                    is = response.body().byteStream();
                    savedFile = new RandomAccessFile(file,"rw");
                    savedFile.seek(downloadLength); //跳过已下载的字节
                    byte[] b = new byte[1024];
                    int total = 0;
                    int len;
                    while ((len = is.read(b))!= -1){
                        if(isCanceled){ //判断用户有没有触发取消按钮
                            return TYPE_CANCELED;
                        }else if (isPaused){ //判断你用户有没有触发暂停按钮
                            return TYPE_PAUSED;
                        }else {
                            total += len;
                            savedFile.write(b,0,len);
                            //计算已下载的百分比
                            int progress = (int)((total + downloadLength)*100/contentLength);
                            //调用publicProgress方法进行通知
                            publishProgress(progress);
                        }
                    }
                    response.body().close();
                    return TYPE_SUCCESS;
                }
            } 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 TYPE_FAILED;
        }
    
        /**
         * 功能:界面上更新当前的下载逻辑
         * @param values
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            //从参数中获得当前下载进度
            int progress = values[0];
            if(progress > lastProgress){
                //和上一次进度进行对比,如果有变化
    
                //调用listener.onProgress通知下载进度进行更新
                listener.onProgress(progress);
                lastProgress = progress;
            }
        }
    
        /**
         *  功能:用于通知最后的下载结果
         * @param status
         */
    
        @Override
        protected void onPostExecute(Integer status) {
            //将参数中传入的下载状态进行回调,下载成功就调用DownloadListener.onSuccess()方法,
            // 取消下载就调用onCanceled()方法
            switch (status){
                case TYPE_SUCCESS:
                    listener.onSuccess();
                    break;
                case TYPE_FAILED:
                    listener.onFailed();
                    break;
                case TYPE_PAUSED:
                    listener.onPaused();
                    break;
                case TYPE_CANCELED:
                    listener.onCanceled();
                    break;
                default:
                    break;
            }
        }
        public void pauseDownload(){
            isPaused = true;
        }
        public void cancelDownload(){
            isCanceled = true;
        }
        private long getContentLength(String downloadUrl) throws IOException{
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url(downloadUrl)
                    .build();
            Response response = client.newCall(request).execute();
            if(response != null && response.isSuccessful()){
                long contentLength = response.body().contentLength();
                response.close();
                return contentLength;
            }
            return 0;
        }
    }
    

    DownloadService.java

    package lbstest.example.com.lbs.ServiceBestPractice;
    
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Intent;
    import android.graphics.BitmapFactory;
    import android.os.Binder;
    import android.os.Environment;
    import android.os.IBinder;
    import android.support.v4.app.NotificationCompat;
    import android.widget.Toast;
    
    import java.io.File;
    
    import lbstest.example.com.lbs.R;
    
    public class DownloadService extends Service {
    
        DownloadTask downloadTask;
    
        private String downloadUrl;
    
        private DownloadListener listener = new DownloadListener() {
            @Override
            public void onProgress(int progress) {
                getNotificationManager().notify(1,getNotification("Downloading...",
                        progress));
            }
    
            @Override
            public void onSuccess() {
                downloadTask = null;
                //下载成功将前台服务通知关闭,并创建一个下载成功的通知
                stopForeground(true);
                getNotificationManager().notify(1,getNotification("Download Success",
                        -1));
                Toast.makeText(DownloadService.this,"Download Success",
                        Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onFailed() {
              downloadTask = null;
                //下载失败时将前台服务关闭,并创建一个下载失败的通知
                stopForeground(true);
                //触发通知,这样就可以在下拉状态栏中实时看到下载进度
                getNotificationManager().notify(1,getNotification("Download Failed",-1));
                Toast.makeText(DownloadService.this,"Download Failed",Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onPaused() {
                downloadTask = null;
                Toast.makeText(DownloadService.this,"Download Pause",Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onCanceled() {
                downloadTask = null;
                stopForeground(true);
                Toast.makeText(DownloadService.this,"Download Canceled",Toast.LENGTH_SHORT).show();
            }
        };
        /**
         * 让DownloadService 可以和活动进行通信
         */
        private DownloadBinder mBinder = new DownloadBinder();
    
        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;
        }
    
    
        public class DownloadBinder extends Binder{
            //用于开始下载
            public void startDownload(String Url){
                //创建一个downloadTask实例,
                if(downloadTask == null){
                    downloadUrl = Url;
                    downloadTask = new DownloadTask(listener); //把刚才的DownloadListener作为参数传入
                    downloadTask.execute(downloadUrl);
                    //让服务成为前台服务 ,在状态栏创建一个持续运行的通知
                    startForeground(1,getNotification("Downloading......",0));
                    Toast.makeText(DownloadService.this,"Downloading......",Toast.LENGTH_SHORT).show();
    
                }
            }
            //用于暂停下载
            public void pauseDownload(){
                if (downloadTask != null) {
                    downloadTask.pauseDownload();
                }
            }
            //用于取消下载
            public void cancelDownload(){
                if (downloadTask != null) {
                    downloadTask.cancelDownload();
                }else {
                    //取消下载将正在下载的文件删除掉
                    if (downloadUrl != null) {
                        //取消下载时需将文件删除,并将通知进行关闭
                        String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
                        String directory = Environment.getExternalStoragePublicDirectory
                                (Environment.DIRECTORY_DOWNLOADS).getPath();
                        File file = new File(directory + fileName);
                        if(file.exists()){
                            file.delete();
                        }
                        getNotificationManager().cancel(1);
                        stopForeground(true);
                        Toast.makeText(DownloadService.this,"Canceled",Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
        private Notification getNotification(String title, int progress){
            Intent intent = new Intent(this,Main4Activity.class);
            PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),
                    R.mipmap.ic_launcher));
            builder.setContentIntent(pi);
            builder.setContentTitle(title);
            if(progress > 0){
                //当progress 大于或等于0时才需要显示下载进度
                builder.setContentText(progress + "%");
                builder.setProgress(100,progress,false);
            }
            return builder.build();
        }
    
    
    
        private NotificationManager getNotificationManager() {
            return (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        };
    
    
    
    
    
    }
    

    Main4Activity.java

    package lbstest.example.com.lbs.ServiceBestPractice;
    
    import android.Manifest;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import lbstest.example.com.lbs.R;
    
    /**
     * 功能:完整版的下载实例
     */
    public class Main4Activity extends AppCompatActivity implements View.OnClickListener {
    
        private static boolean Justice = false;
    
        EditText urlWeb = null;
    
        private DownloadService.DownloadBinder downloadBinder;
    //先创建一个SerViceConnection 的匿名类,
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
              //  onServiceConnection()方法中获得DownloadBinder的实例
                //有了这个实例,可以在活动中调用服务提供的各种方法
                downloadBinder = (DownloadService.DownloadBinder) service;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main4);
            Button startDownload = (Button) findViewById(R.id.start_download);
            Button pauseDownload = (Button) findViewById(R.id.pause_download);
            Button cancelDownload = (Button) findViewById(R.id.cancel_download);
             urlWeb = (EditText) findViewById(R.id.webUrl);
            startDownload.setOnClickListener(this);
            pauseDownload.setOnClickListener(this);
            cancelDownload.setOnClickListener(this);
            Intent intent = new Intent(this,DownloadService.class);
            //启动和绑定服务
            startService(intent); //启动服务可以保证DownloadService一直在后台运行
            bindService(intent,connection,BIND_AUTO_CREATE); //绑定服务  让Main4Activity和DownloadService进行通信
            if(ContextCompat.checkSelfPermission(Main4Activity.this, Manifest
            .permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(Main4Activity.this,new
                String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
            }
        }
    
        @Override
        public void onClick(View v) {
            if(downloadBinder == null){
                return;
            }
            switch (v.getId()){
                case R.id.start_download:
                    String url = null;
                        if(!urlWeb.getText().toString().equals("")){
                        Log.d("XXX","urlWeb.get is"+urlWeb.getText().toString());
                        url = urlWeb.getText().toString();
                        downloadBinder.startDownload(url);
                        Justice = true;
                    }else {
                        Justice = false;
                        Toast.makeText(Main4Activity.this,"请先填写要下载的网址!",Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.pause_download:
                    if(Justice){
                        downloadBinder.pauseDownload();
                    }else {
                        Toast.makeText(Main4Activity.this,"请先填写要下载的网址!",Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.cancel_download:
                    if(Justice){
                        downloadBinder.cancelDownload();
                    }else {
                        Toast.makeText(Main4Activity.this,"请先填写要下载的网址!",Toast.LENGTH_SHORT).show();
                    }
                    break;
                default:
                    break;
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] 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);
        }
    }
    
    activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="输入要下载的网址"
                android:textSize="20sp"
                />
            <EditText
                android:textSize="18sp"
                android:textColor="#000"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="例:http://www.baidu.com"
                android:id="@+id/webUrl"
                />
    
        </LinearLayout>
        <Button
            android:id="@+id/start_download"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="开始下载" />
    
        <Button
            android:id="@+id/pause_download"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="暂停下载" />
    
        <Button
            android:id="@+id/cancel_download"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="取消下载" />
    </LinearLayout>
    
  • 相关阅读:
    作业
    第一次作业
    临时和永久关闭firewalld与selinux
    联合删除
    使用CascadingDropDown实现级联式下拉框
    使用createElement动态创建HTML对象.
    关于DotNetZip的用法
    网站性能优化:cache-control设置详解
    百度蜘蛛Baiduspider User-Agent字段更新与IP判断
    (转)一个简单,方便的七牛云存储的客户端(收藏)
  • 原文地址:https://www.cnblogs.com/CCCrunner/p/11781884.html
Copyright © 2020-2023  润新知