两行代码实现标题栏软件更新并自动安装

来源:互联网 发布:音频切割软件 一刀切 编辑:程序博客网 时间:2024/06/16 23:02

上次写了一篇博客,“三行代码实现软件下载,dialog显示” ,出乎我意料之外,热度挺高,都是标题在搞怪,

一直都想总结一下标题栏的使用 ,以前写的代码封装不太好 ,调用还是有点麻烦 ,下午花了几个小时,就整理一下

代码简洁,一气呵成,简单测试,目前没有bug 。具体使用,可以根据自己的场景,小修小改


代码下载地址 :http://download.csdn.net/detail/fkgjdkblxckvbxbgb/9922869



具体效果,可以自行运行代码,看效果 。

代码还是贴一下,可以局部的看一下代码,不用看整体的,代码都差不多的

先看主界面的代码,代码很简洁,初始化一下,然后直接调用升级的方法

package com.reeman.view;import android.app.Activity;import android.app.Notification;import android.os.Bundle;import android.os.Environment;import android.support.v4.app.NotificationCompat;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.RemoteViews;import com.reeman.view.down.DownParsener;import com.reeman.view.down.DownView;import com.reeman.view.down.TitleBarUtil;public class ProgressAcitivty2 extends Activity {    TitleBarUtil titleBarUtil;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_progress);        initView();    }    private void initView() {        titleBarUtil = new TitleBarUtil(ProgressAcitivty2.this);        findViewById(R.id.btn_download_start).setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                titleBarUtil.updateApk();            }        });    }}


apk安装类

package com.reeman.view.down;import android.content.Context;import android.content.Intent;import android.net.Uri;import java.io.File;public class ApkUtil {    public static void installApk(Context context, String apkUrl) {        // 核心是下面几句代码        Intent intent = new Intent(Intent.ACTION_VIEW);        intent.setDataAndType(Uri.fromFile(new File(apkUrl)),                "application/vnd.android.package-archive");        context.startActivity(intent);    }}

下载状态监听类

package com.reeman.view.down;/** * Created by Administrator on 2017/8/6. */public interface DownListener {    /**     * 开始下载     */    void downStart();    /***     * 下载进度,和速度     * @param progress     * @param speed     */    void downProgress(int progress, long speed);    /***     * 下载完成     * @param downUrl     */    void downSuccess(String downUrl);    /***     * 下载失败     * @param failedDesc     */    void downFailed(String failedDesc);}

下载的工具类

package com.reeman.view.down;import android.util.Log;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.concurrent.TimeUnit;import okhttp3.Call;import okhttp3.Callback;import okhttp3.Dispatcher;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;/** * Created by reeman on 2017/7/21. */public class DownUtil implements Callback {    OkHttpClient mOkHttpClient;    DownListener downListener;    String downPath;    String downUrl;    public DownUtil(DownListener downListener) {        this.downListener = downListener;        mOkHttpClient = new OkHttpClient.Builder()                .connectTimeout(10, TimeUnit.SECONDS)                .readTimeout(10, TimeUnit.SECONDS)                .build();    }    public void downFile(String downUrl, String downPath) {        this.downUrl = downUrl;        this.downPath = downPath;        try {            downListener.downStart();            String downDir = downPath.substring(0, downPath.lastIndexOf("/")).trim();            String downName = downPath.substring(downPath.lastIndexOf("/") + 1, downPath.length()).trim();            Log.i("down", "下载地址==" + downDir + "   下载的名字==" + downName);            File destDir = new File(downDir);            if (destDir.isDirectory() && !destDir.exists()) {                destDir.mkdirs();            }            Request request = new Request.Builder().url(downUrl).build();            mOkHttpClient.newCall(request).enqueue(this);        } catch (Exception e) {            downListener.downFailed(e.toString());            Log.d("down", "=================error==" + e.toString());        }    }    public void cacleDown() {        Dispatcher dispatcher = mOkHttpClient.dispatcher();        for (Call call : dispatcher.runningCalls()) {            call.cancel();        }    }    @Override    public void onFailure(Call call, IOException e) {        downListener.downFailed(e.toString());        Log.d("down", "onFailure");    }    @Override    public void onResponse(Call call, Response response) throws IOException {        InputStream is = null;        byte[] buf = new byte[2048];        int len = 0;        FileOutputStream fos = null;        try {            is = response.body().byteStream();            long total = response.body().contentLength();            File file = new File(downPath);            if (file.exists()) {                Log.i("down", "文件存在,删除文件==");                file.delete();            }            if (!file.exists() && file.isFile()) {                Log.i("down", "下载文件不存在创建文件==");                boolean isCreat = file.createNewFile();                Log.i("down", "创建文件==" + isCreat);            }            fos = new FileOutputStream(file);            long sum = 0;            long saveSum = 0;            while ((len = is.read(buf)) != -1) {                fos.write(buf, 0, len);                sum += len;                final int progress = (int) (sum * 1.0f / total * 100);                final long speed = sum - saveSum;                saveSum = sum;                Log.d("down", "===================" + progress + "  speed =" + speed);                updateProgress(progress, speed);            }            fos.flush();            downListener.downSuccess(downPath);            Log.d("down", "=================success==");        } catch (Exception e) {            downListener.downFailed(e.toString());            Log.d("down", "=================error==" + e.toString());        } finally {            if (is != null)                is.close();            if (fos != null)                fos.close();        }    }    int lastProgress = 0;    private void updateProgress(int progress, long speed) {        if (progress > lastProgress) {            downListener.downProgress(progress, speed);        }        lastProgress = progress;    }}

用于界面更新的类

package com.reeman.view.down;/** * Created by Administrator on 2017/8/6. */public interface DownView {    void updatePeogress(int progress, String desc);    /***     * 下载失败     * @param errorDesc     */    void downError(String errorDesc);    /***     * 下载成功     * @param savePath     */    void downSuccess(String savePath);}

下载,界面更新Parsener类

package com.reeman.view.down;import android.os.Handler;public class DownParsener implements DownListener {    DownUtil downUtil;    DownView downView;    private Handler handler = new Handler();    public DownParsener(DownView downView) {        this.downView = downView;        downUtil = new DownUtil(this);    }    public void startDown(String downUrl, String savaPath) {        downUtil.downFile(downUrl, savaPath);    }    @Override    public void downStart() {        handler.post(new Runnable() {            @Override            public void run() {                downView.updatePeogress(0, "开始下载");            }        });    }    @Override    public void downProgress(final int progress, long speed) {        handler.post(new Runnable() {            @Override            public void run() {                if (progress == 100) {                    downView.updatePeogress(progress, "下载完成");                } else {                    downView.updatePeogress(progress, "下载中");                }            }        });    }    @Override    public void downSuccess(final String downUrl) {        handler.post(new Runnable() {            @Override            public void run() {                downView.downSuccess(downUrl);            }        });    }    @Override    public void downFailed(final String failedDesc) {        handler.post(new Runnable() {            @Override            public void run() {                downView.downError(failedDesc);            }        });    }}


通知栏的工具类

package com.reeman.view.down;import android.app.Activity;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.os.Environment;import android.support.v4.app.NotificationCompat;import android.util.Log;import android.view.View;import android.widget.RemoteViews;import android.widget.Toast;import com.reeman.view.R;public class TitleBarUtil implements DownView {    int notifyId = 102;    NotificationCompat.Builder mBuilder;    Context context;    public NotificationManager mNotificationManager;    DownParsener downParsener;    String URL_VIDEO = Environment.getExternalStorageDirectory().getPath();    public TitleBarUtil(Context context) {        this.context = context;        downParsener = new DownParsener(this);        mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);        initNotify();    }    public void updateApk() {        String downUrl = "http://58.63.233.48/app.znds.com/down/20170712/ystjg_2.6.0.1059_dangbei.apk";        String downPath = URL_VIDEO + "/tengxun.apk";        downParsener.startDown(downUrl, downPath);    }    /**     * 初始化通知栏     */    private void initNotify() {        mBuilder = new NotificationCompat.Builder(context);        mBuilder.setWhen(System.currentTimeMillis())// 通知产生的时间,会在通知信息里显示                .setContentIntent(getDefalutIntent(0))                .setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级                .setOngoing(false)// ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)                .setSmallIcon(R.drawable.ic_launcher);    }    /**     * 显示带进度条通知栏     */    public void showProgressNotify() {        mBuilder.setContentTitle("等待下载")                .setTicker("开始下载");// 通知首次出现在通知栏,带上升动画效果的        // 确定进度的        mBuilder.setProgress(100, 0, false); // 这个方法是显示进度条        mNotificationManager.notify(notifyId, mBuilder.build());    }    /**     * 显示自定义的带进度条通知栏     */    private void showCustomProgressNotify(String status, int progress) {        RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),                R.layout.view_custom_progress);        mRemoteViews.setImageViewResource(R.id.custom_progress_icon,                R.drawable.ic_launcher);        mRemoteViews.setTextViewText(R.id.tv_custom_progress_title, progress + "%");        mRemoteViews.setTextViewText(R.id.tv_status, status);        if (progress >= 100) {            mRemoteViews.setProgressBar(R.id.custom_progressbar, 0, 0, false);            mRemoteViews.setViewVisibility(R.id.custom_progressbar, View.GONE);        } else {            mRemoteViews.setProgressBar(R.id.custom_progressbar, 100, progress,                    false);            mRemoteViews.setViewVisibility(R.id.custom_progressbar,                    View.VISIBLE);        }        mBuilder.setContent(mRemoteViews).setContentIntent(getDefalutIntent(0))                .setTicker("软件更新");        Notification nitify = mBuilder.build();        nitify.contentView = mRemoteViews;        mNotificationManager.notify(notifyId, nitify);    }    public void stopDownloadNotify() {        mBuilder.setContentTitle("下载已取消").setProgress(0, 0, false);        mNotificationManager.notify(notifyId, mBuilder.build());    }    public PendingIntent getDefalutIntent(int flags) {        PendingIntent pendingIntent = PendingIntent.getActivity(context, 1,                new Intent(), flags);        return pendingIntent;    }    @Override    public void updatePeogress(int progress, String desc) {        Log.i("main", "显示进度条===" + progress + "//" + desc);        showCustomProgressNotify(desc, progress);    }    @Override    public void downError(String errorDesc) {        Toast.makeText(context, errorDesc, Toast.LENGTH_SHORT).show();    }    @Override    public void downSuccess(String savePath) {        Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();        ApkUtil.installApk(context, savePath);        clearNotify(notifyId);    }    public void clearNotify(int notifyId) {        if (notifyId == 0) {            mNotificationManager.cancelAll();        } else {            mNotificationManager.cancel(notifyId);        }    }}


最后还有两个界面xml

view_custom_rogress.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@color/white"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <ImageView            android:id="@+id/custom_progress_icon"            android:layout_width="50dip"            android:layout_height="50dip"            android:src="@drawable/ic_launcher" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginLeft="10dp"            android:layout_marginRight="10dp"            android:orientation="vertical">            <RelativeLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginLeft="15dp"                android:layout_marginRight="15dp">                <TextView                    android:id="@+id/tv_status"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="准备下载"                    android:textColor="@color/black"                    android:textSize="12sp" />                <TextView                    android:id="@+id/tv_custom_progress_title"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_alignParentRight="true"                    android:text="0%"                    android:textSize="15sp" />            </RelativeLayout>            <ProgressBar                android:id="@+id/custom_progressbar"                style="@android:style/Widget.ProgressBar.Horizontal"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginTop="10dp" />        </LinearLayout>    </LinearLayout></RelativeLayout>

主界面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:background="@color/white"    android:orientation="vertical"    android:padding="10dip">    <Button        android:id="@+id/btn_download_start"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="40dip"        android:text="开始下载" /></LinearLayout>














原创粉丝点击