Android实现APP版本升级

来源:互联网 发布:以太网数据帧格式 mii 编辑:程序博客网 时间:2024/06/05 16:12

最近写的项目中有用到版本升级,所以简单的写了一个例子来实现这个功能,由于时间紧迫,代码有很多需要优化的地方,请各位大神指正。

页面大概是这个样子的:


在服务中使用okgo下载APK,下载过程中在通知栏显示下载进度,下载完成后,通知栏消失,进入APK安装页面;

主要代码:

public class Update_app {    private Context context;    private String update_url = "http://b2b.yoyoce.com/mobile/member/down";    private String apk_url = "";    private int version = 0;    private String ed_num, content, size;    public Update_app(Context context) {        this.context = context;    }    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what) {                case 1:                    if (isNeedUpdate()) {                        SharedPreferences sp = context.getSharedPreferences("update", Context.MODE_PRIVATE);                        sp.getInt("num", 0);                        if (sp.getInt("num", 0) != version) {                            ShowDialog();                        }                    }                    break;            }        }    };    public void update() {        get_service();    }    private boolean isNeedUpdate() {        if (getVersion() < version) {            return true;        } else {            return false;        }    }    //获取当前版本号    private int getVersion() {        try {            PackageManager packageManager = context.getPackageManager();            PackageInfo packageInfo = packageManager.getPackageInfo(                    context.getPackageName(), 0);            return packageInfo.versionCode;        } catch (Exception e) {            e.printStackTrace();            return -1;        }    }    void get_service() {        OkGo.post(update_url)                .tag(this)                .connTimeOut(100000)                .readTimeOut(100000)                .writeTimeOut(100000)                .cacheKey(update_url)                .cacheTime(1000 * 60 * 60 * 24)                .cacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)                //这里给出的泛型为 ServerModel,同时传递一个泛型的 class对象,即可自动将数据结果转成对象返回                .execute(new StringCallback() {                    @Override                    public void onSuccess(String s, Call call, Response response) {                        try {                            JSONObject jsonObject = new JSONObject(s);                            if (jsonObject.getInt("status") == 1) {                                JSONObject jsonObject1 = jsonObject.getJSONObject("result");                                apk_url = jsonObject1.getString("apk_url");                                String edition = jsonObject1.getString("edition");                                //展示给用户                                ed_num = jsonObject1.getString("ed_num");                                content = jsonObject1.getString("content");                                size = jsonObject1.getString("size");                                version = Integer.parseInt(edition);                                handler.sendEmptyMessage(1);                            }                        } catch (JSONException e) {                            e.printStackTrace();                        }                    }                });    }    void ShowDialog() {        //弹出对话框        final LayoutInflater inflaterDl = LayoutInflater.from(context);        LinearLayout layout = (LinearLayout) inflaterDl.inflate(R.layout.update, null);        //初始化按钮        TextView update_tv_yes = (TextView) layout.findViewById(R.id.update_tv_yes);        TextView update_tv_no = (TextView) layout.findViewById(R.id.update_tv_no);        final CheckBox cb = (CheckBox) layout.findViewById(R.id.cb);        TextView new_banben = (TextView) layout.findViewById(R.id.new_banben);        TextView apk_size = (TextView) layout.findViewById(R.id.apk_size);        TextView new_context1 = (TextView) layout.findViewById(R.id.new_context1);        new_banben.setText("最新版本: " + ed_num);        apk_size.setText("新版本大小: " + size);        new_context1.setText(content);        final AlertDialog dialog = new AlertDialog.Builder(context).create();        dialog.show();        dialog.getWindow().setContentView(layout);        Window dialogWindow = dialog.getWindow();        dialogWindow.setGravity(Gravity.CENTER);        WindowManager.LayoutParams lp = dialogWindow.getAttributes();        //屏幕宽高度        WindowManager m = ((MainActivity) context).getWindowManager();        Display d = m.getDefaultDisplay();        //lp.height = (int) (d.getHeight() * 0.4);        lp.width = (int) (d.getWidth() * 0.9);        dialogWindow.setAttributes(lp);        update_tv_yes.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(context, Update_Service.class);                intent.putExtra("apk_url",apk_url);                context.startService(intent);                Toast.makeText(context, "下载中,请稍等…", Toast.LENGTH_SHORT).show();                dialog.dismiss();            }        });        update_tv_no.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (cb.isChecked()) {                    dialog.dismiss();                    SharedPreferences sharedPreferences = context.getSharedPreferences("update", Context.MODE_PRIVATE);                    SharedPreferences.Editor editor = sharedPreferences.edit();                    editor.putInt("num", version);                    editor.commit();                } else {                    dialog.dismiss();                }            }        });    }}

对话框布局:

<?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"    android:paddingBottom="25dp"    android:paddingTop="5dp">    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:paddingBottom="10dp"        android:paddingTop="10dp"        android:text="发现新版本"        android:textColor="#009aff"        android:textSize="16sp" />    <View        android:layout_width="match_parent"        android:layout_height="2dp"        android:layout_marginLeft="20dp"        android:layout_marginRight="20dp"        android:background="#009aff" />    <TextView        android:id="@+id/new_banben"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="20dp"        android:layout_marginRight="10dp"        android:layout_marginTop="20dp"        android:textSize="15sp" />    <TextView        android:id="@+id/apk_size"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="20dp"        android:layout_marginRight="10dp"        android:textSize="15sp" />    <TextView        android:id="@+id/new_context"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="20dp"        android:layout_marginRight="10dp"        android:layout_marginTop="10dp"        android:text="更新内容:"        android:textSize="15sp" />    <TextView        android:id="@+id/new_context1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="20dp"        android:layout_marginRight="10dp"        android:layout_marginTop="5dp"        android:textSize="15sp" />    <CheckBox        android:id="@+id/cb"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="15dp"        android:layout_marginTop="15dp"        android:checked="false"        android:text="忽略本版"        android:textColor="#666"        android:textSize="16sp">    </CheckBox>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:orientation="horizontal">        <TextView            android:id="@+id/update_tv_no"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_marginLeft="10dp"            android:layout_marginRight="5dp"            android:layout_weight="1"            android:background="@drawable/next_update_tv"            android:gravity="center"            android:paddingBottom="5dp"            android:paddingTop="5dp"            android:text="下次再说"            android:textSize="15sp" />        <TextView            android:id="@+id/update_tv_yes"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_marginLeft="5dp"            android:layout_marginRight="10dp"            android:layout_weight="1"            android:background="@drawable/now_update_tv"            android:gravity="center"            android:paddingBottom="5dp"            android:paddingTop="5dp"            android:text="立即更新"            android:textColor="#fff"            android:textSize="15sp" />    </LinearLayout></LinearLayout>
服务中开始下载, okgo用到的依赖:

compile 'com.lzy.net:okgo:2.0.0'compile 'com.lzy.net:okrx:0.1.0'compile 'com.lzy.net:okserver:1.1.0'

public class Update_Service extends Service {    private NotificationManager notifyManager;    private NotificationCompat.Builder builder;    private RemoteViews mRemoteViews;    @Nullable    @Override    public IBinder onBind(Intent intent) {        return null;    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);        mRemoteViews = new RemoteViews(getPackageName(), R.layout.update_progress);        mRemoteViews.setImageViewResource(R.id.icon_pg, R.mipmap.icon);        mRemoteViews.setTextViewText(R.id.pg_tv, "0%");        builder = new NotificationCompat.Builder(this)                .setSmallIcon(R.mipmap.icon)                .setContentTitle("正在下载安装包")                .setContentText("请稍等…")                .setTicker("开始更新")                .setContent(mRemoteViews);        notifyManager.notify(1, builder.build());        down(intent.getStringExtra("apk_url"));        return Service.START_STICKY;    }    void down(String url2) {        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            String sdpath = Environment.getExternalStorageDirectory().getAbsolutePath();            OkGo.get(url2)                    .tag(this)                    .execute(new FileCallback(sdpath, "fenglaike.apk") {                        @Override                        public void onBefore(BaseRequest request) {                        }                        @Override                        public void onSuccess(File file, Call call, Response response) {                            Intent intent = new Intent(Intent.ACTION_VIEW);                            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                            getApplicationContext().startActivity(intent);                            stopSelf();                            notifyManager.cancelAll();                        }                        @Override                        public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {                            mRemoteViews.setProgressBar(R.id.pg, 100, (int) (Math.round(progress * 10000) * 1.0f / 100), false);                            mRemoteViews.setTextViewText(R.id.pg_tv, (Math.round(progress * 10000) * 1.0f / 100) + "%");                            notifyManager.notify(1, builder.build());                        }                        @Override                        public void onError(Call call, @Nullable Response response, @Nullable Exception e) {                            super.onError(call, response, e);                            Toast.makeText(getApplicationContext(), "下载出错,请重新下载", Toast.LENGTH_SHORT).show();                        }                    });        } else {            Toast.makeText(getApplicationContext(), "存储卡装载错误", Toast.LENGTH_SHORT).show();        }    }}

通知栏布局:

<?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="65dp"    android:gravity="center_vertical"    android:orientation="horizontal">    <ImageView        android:id="@+id/icon_pg"        android:layout_width="45dp"        android:layout_height="45dp" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="center_vertical"        android:orientation="vertical">        <TextView            android:layout_width="wrap_content"            android:layout_height="15dp"            android:layout_marginLeft="10dp"            android:text="更新下载中"            android:textSize="10sp" />        <ProgressBar            android:id="@+id/pg"            style="?android:attr/progressBarStyleHorizontal"            android:layout_width="match_parent"            android:layout_height="3.5dp"            android:progressDrawable="@drawable/pg_style"            android:layout_marginBottom="5dp"            android:layout_marginLeft="10dp"            android:layout_marginRight="10dp"            android:layout_marginTop="5dp"            android:background="#debd2c"            android:max="100"            android:progress="0" />        <TextView            android:id="@+id/pg_tv"            android:layout_width="wrap_content"            android:layout_height="15dp"            android:layout_marginLeft="10dp"            android:text="25%"            android:textSize="10sp" />    </LinearLayout></LinearLayout>

进度条背景:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">    <!-- 这个是背景颜色 -->    <item android:id="@android:id/background">        <shape>            <!-- 这个是设置圆角还会直角,如果设置成0dip就是直角 -->            <corners android:radius="5dip" />            <!-- 设置背景的颜色,将startColor、centerColor、endColor都设置成同一个颜色值 -->            <!--                 如果你不用颜色值也可以,可以直接用图片来代替,在item中添加这个属性就可以了,其他的不需要                 android:drawable="@drawable/progressbar_bg"            -->            <gradient                android:endColor="#DDE3E4"                android:startColor="#DDE3E4" />        </shape>    </item>    <!-- 这个是第二进度条的颜色,没用到,大同小异 -->    <!--<item android:id="@android:id/secondaryProgress">        <clip>            <shape>                <corners android:radius="5dip" />                <gradient                    android:angle="270"                    android:centerColor="#80C07AB8"                    android:centerY="0.75"                    android:endColor="#a0C07AB8"                    android:startColor="#80C07AB8" />            </shape>        </clip>    </item>-->    <!-- 这个是设置你进度的颜色 -->    <item android:id="@android:id/progress">        <clip>            <shape>                <!-- 这个也是设置时圆角还是直角,左边的 -->                <corners android:radius="5dip" />                <!-- 设置进度的颜色,将startColor、centerColor、endColor都设置成同一个颜色值 -->                <gradient                    android:endColor="#009aff"                    android:startColor="#009aff" />            </shape>        </clip>    </item></layer-list>
为了在关闭应用后还可以继续下载,可以再开启一个进程:

<service            android:name=".update.Update_Service"            android:process=":download" />









原创粉丝点击