android复习路之service综合篇

android中service和Asnyctask没有写过综合应用,最近也在看东西没有段时间发过博文了。今天发表一个综合应用记录,代码是来源于郭神的第一行代码,自己进行分析,算事研读吧。要知道的都在注释里。这是一个下载文件的demo并且在系统通知栏显示。

activity:

package com.example.zobject.http;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
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.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.jar.Manifest;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
        private MyService.DownLoadBinder downLoadBinder;//首先获得DownLoadBinder的实例



        private ServiceConnection connection =new ServiceConnection() { //实现ServiceConnection内部类就可以在activity中调用 service中的方法了
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                downLoadBinder= (MyService.DownLoadBinder) iBinder;
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {

            }
        };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.strat);
        Button button1 = (Button) findViewById(R.id.pause);
        Button button2 = (Button) findViewById(R.id.cancel);
        button.setOnClickListener(this);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        Intent intent =new Intent(this,MyService.class);
        startService(intent);//启动服务
        bindService(intent,connection,BIND_AUTO_CREATE);//绑定服务
        if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){//权限检查
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }
    }


    @Override
    public void onClick(View view) {//三种方法的调用
        if (downLoadBinder==null){
            return;
        }
        switch (view.getId()){
            case  R.id.strat:
                String url="https://raw.githubusercontent.com/guolindev/eclipse/master/eclipse-inst-win64.exe";
                downLoadBinder.startDownload(url);
                break;
            case R.id.pause:
                downLoadBinder.PauseDownload();
                break;
            case R.id.cancel:
                downLoadBinder.cancelDownload();
                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,"ju",Toast.LENGTH_LONG);
                }
                break;
            default:
        }



    }

    @Override
    protected void onDestroy() {//在activity销毁的时候解绑service 因为在service还在运行会造成内存泄露
        super.onDestroy();
        unbindService(connection);
    }
}

listener接口
public interface DownLoadListener {  // service和底层的通行接口
    void onProgess(int progess);
    void Success();
    void Failed();
    void onPaused();
    void onCanceled();

}
service层:
package com.example.zobject.http;

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;

public class MyService extends Service {

    private String downloadUrl;
    private DownLoad downLoad;
    private DownLoadListener downLoadListener = new DownLoadListener() {//实现定义的接口
        @Override
        public void onProgess(int progess) {
            getNoti().notify(1, notification("Download.......", progess));
        }

        @Override
        public void Success() {
            downLoad = null;
            stopForeground(true);//把进程放到前台进行避免被杀掉
            getNoti().notify(1, notification("DownSuccess", -1));
            Toast.makeText(MyService.this, "Successs", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void Failed() {
            downLoad = null;
            stopForeground(true);
            getNoti().notify(1, notification("DownloadFailed", -1));
            Toast.makeText(MyService.this, "Failed", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onPaused() {
            downLoad = null;
            Toast.makeText(MyService.this, "Pause", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onCanceled() {
            downLoad = null;
            stopForeground(true);
            Toast.makeText(MyService.this, "Cancelded", Toast.LENGTH_LONG).show();
        }
    };




    private NotificationManager getNoti() {//进行进度条的显示和定义
        return (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    }

    private Notification notification(String title, int progess) {
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = 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(pendingIntent);
        builder.setContentTitle(title);
        if (progess > 0) {
            builder.setContentText(progess + "%");
            builder.setProgress(100, progess, false);
        }
        return builder.build();
    }

    private DownLoadBinder downLoadBind = new DownLoadBinder();

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

    class DownLoadBinder extends Binder {//继承binder 供上层进行调用

        public void startDownload(String url) {
            if (downLoad == null) {
                downloadUrl = url;
                downLoad = new DownLoad(downLoadListener);//绑定一个listener给底层方便调用
                startForeground(1, notification("download.......", 0));
                downLoad.execute(downloadUrl);//在这开启ansyctask的异步调用
                Toast.makeText(MyService.this, "startdownload........", Toast.LENGTH_LONG).show();

            }
        }

        public void PauseDownload() {
            if (downLoad != null) {
                downLoad.pauseDown();
            }
        }

        public void cancelDownload() {
            if (downLoad != null) {// 这个是下载直接停止
                downLoad.canelDown();
            } else {
                if (downloadUrl != null) {// 这部分是暂停后取消
                    String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
                    String dectoty = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
                    File file = new File(dectoty + fileName);
                    if (file.exists()) {
                        file.exists();
                    }
                    getNoti().cancel(1);
                    stopForeground(true);
                    Toast.makeText(MyService.this, "Canceled", Toast.LENGTH_LONG).show();
                }
            }
        }
    }
}
Asyn:
package com.example.zobject.http;

import android.os.AsyncTask;
import android.os.Environment;

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 zobject on 2017/1/11.
 */

public class DownLoad extends AsyncTask<String, Integer, Integer> {///异步处理接受三个参数第一个是url地址,第二个和第三个进度反馈用int型
    public static final int SUCCESS = 0;
    public static final int FAILED = 1;
    public static final int PAUSEE = 2;
    public static final int CANCELED = 3;
    private DownLoadListener downLoadListener;
    private boolean isCancelde = false;
    private boolean isPause = false;
    private int lastProgess;

    public DownLoad(DownLoadListener listener) {
        this.downLoadListener = listener;
    }//接受一个接受进来

    @Override
    protected Integer doInBackground(String... strings) {//接受 第一个参数进来
        InputStream inputStream = null;
        RandomAccessFile saveFile = null;//随机存储方法
        File file = null;
        try {
            long DownLoadLength = 0;
            String downLoadUrl = strings[0];
            String fileName = downLoadUrl.substring(downLoadUrl.lastIndexOf("/"));//通过路径获得到文件的名字
            String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();//获取到downloadd的文件路径
            file = new File(directory + fileName);//文件的路径为file
            if (file.exists()) {
                DownLoadLength = file.length();//判读路径是否存在,下载的长度文件的文件的当前长度,这个段代码用来读取当前的下载数目,用来实现暂停后继续下载
            }

            long ContentLength = getContentLength(downLoadUrl);//求的文件的总的长度
            if (ContentLength == 0) {
                return FAILED;
            } else if (ContentLength == DownLoadLength) {
                return SUCCESS;
            }
            OkHttpClient okhettp = new OkHttpClient();//这里是继续下载的操作
            Request requset = new Request.Builder().addHeader("RANGE", "bytes" + DownLoadLength + "-").url(downLoadUrl).build();//跳过下载过的文件

            Response response = okhettp.newCall(requset).execute();
            if (response != null) {//这段就是存储下载好的文件了,如果返回的不是空值就进行存储

                inputStream = response.body().byteStream();
                saveFile = new RandomAccessFile(file, "rw");
                saveFile.seek(DownLoadLength);
                byte[] b = new byte[1024];
                int total = 0;
                int len;
                while ((len = inputStream.read()) != -1) {
                    if (isCancelde) {
                        return CANCELED;//如果前台进行了取消操作就返回取消的标识符
                    } else if (isPause) {
                        return PAUSEE;//如果前台返进行了暂停就返回暂停的标识符
                    } else {
                        total += len;
                        saveFile.write(b, 0, len);
                        int progess = (int) ((total + DownLoadLength) * 100 / ContentLength);//这里就是下载进度的实时反馈
                        publishProgress(progess);//切换到主线程进行京进度条的加载
                    }
                }
                response.body().close();//下载完成
                return SUCCESS;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();

                }
                if (saveFile != null) {
                    saveFile.close();
                }
                if (isCancelde && file != null) {
                    file.delete();//如果取消了下载,就删除文件
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        return FAILED;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        int progress = values[0];
        if (progress > lastProgess) {
            downLoadListener.onProgess(progress);//实时的反馈下砸进度
            lastProgess = progress;
        }
    }

    @Override
    protected void onPostExecute(Integer integer) {//四种结果的反馈结果提供给借口进行回掉
        switch (integer) {
            case SUCCESS:
                downLoadListener.Success();
                break;
            case FAILED:
                downLoadListener.Failed();
                break;
            case PAUSEE:
                downLoadListener.onPaused();
                break;
            case CANCELED:
                downLoadListener.onCanceled();
                break;
            default:
                break;

        }
    }

    public void pauseDown() {
        isPause = true;
    }//提供给服务层进行调用让本层进行一定的操作

    public void canelDown() {
        isCancelde = true;
    }

    private long getContentLength(String downLoadUrl) throws IOException {//返回文件的长度显示计算的百分比
        OkHttpClient client = new OkHttpClient();
        Request requset = new Request.Builder().url(downLoadUrl).build();
        Response res = client.newCall(requset).execute();
        if (res != null && res.isSuccessful()) {
            long reslength = res.body().contentLength();
            res.close();
            return reslength;
        }
        return 0;
    }
}
效果图:
 

x


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值