上次写了一篇博客,“三行代码实现软件下载,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>














相关文章:

  • 2021-05-26
  • 2022-12-23
  • 2021-08-10
  • 2021-05-18
  • 2022-12-23
  • 2021-12-24
  • 2022-01-18
猜你喜欢
  • 2022-12-23
  • 2021-12-31
  • 2022-12-23
  • 2021-11-17
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案