天天看点

手机卫士03-下载app并安装

原文再续书接上一回,昨天我们把那个与服务器端的交互以及解析xml的内容给搭建出来啦,那么今天我们就来完成一下下载新版的apk并安装的逻辑写一下

既然要下载apk,那么肯定是另开一个线程下载的啦,所以我们在这里就新建一个类啦

com.xiaobin.security.engine.downloadtask

<font color="#333333"><font face="arial">package com.xiaobin.security.engine;

import java.io.file;

import java.io.fileoutputstream;

import java.io.inputstream;

import java.net.httpurlconnection;

import java.net.url;

import android.app.progressdialog;

public class downloadtask

{

        public static file getfile(string path, string filepath, progressdialog progressdialog) throws exception

        {

                url url = new url(path);

                httpurlconnection httpurlconnection = (httpurlconnection) url.openconnection();

                httpurlconnection.setconnecttimeout(2000);

                httpurlconnection.setrequestmethod("get");

                if(httpurlconnection.getresponsecode() == 200)

                {

                        int total = httpurlconnection.getcontentlength();

                        progressdialog.setmax(total);

                        inputstream is = httpurlconnection.getinputstream();

                        file file = new file(filepath);

                        fileoutputstream fos = new fileoutputstream(file);

                        byte[] buffer = new byte[1024];

                        int len;

                        int process = 0;

                        while((len = is.read(buffer)) != -1)

                        {

                                fos.write(buffer, 0, len);

                                process += len;

                                progressdialog.setprogress(process);

                        }

                        fos.flush();

                        fos.close();

                        is.close();

                        return file;

                }

                return null;

        }

}

</font></font>

复制代码

好啦,那个写好了,从服务器里面拿到一个最新版的apk之后,我们就要在splashactivity里面写一些安装的逻辑啦,还有一个内部类,用来启动另一个线程下载  com.xiaobin.security.ui.splashactivity

package com.xiaobin.security.ui;

import android.annotation.suppresslint;

import android.app.activity;

import android.app.alertdialog;

import android.content.dialoginterface;

import android.content.intent;

import android.content.pm.packageinfo;

import android.content.pm.packagemanager;

import android.content.pm.packagemanager.namenotfoundexception;

import android.net.uri;

import android.os.bundle;

import android.os.environment;

import android.os.handler;

import android.os.message;

import android.util.log;

import android.view.window;

import android.view.windowmanager;

import android.view.animation.alphaanimation;

import android.widget.linearlayout;

import android.widget.textview;

import android.widget.toast;

import com.xiaobin.security.r;

import com.xiaobin.security.domain.updateinfo;

import com.xiaobin.security.engine.downloadtask;

import com.xiaobin.security.engine.updateinfoservice;

public class splashactivity extends activity

        private textview tv_version;

        private linearlayout ll;

        private progressdialog progressdialog;

        private updateinfo info;

        private string version;

        private static final string tag = "security";

        @suppresslint("handlerleak")

        private handler handler = new handler()

                public void handlemessage(message msg)

                        if(isneedupdate(version))

                                showupdatedialog();

                };

        };

        @override

        protected void oncreate(bundle savedinstancestate)

                super.oncreate(savedinstancestate);

                requestwindowfeature(window.feature_no_title);

                setcontentview(r.layout.splash);

                getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, windowmanager.layoutparams.flag_fullscreen);

                tv_version = (textview) findviewbyid(r.id.tv_splash_version);

                version = getversion();

                tv_version.settext("版本号  " + version);

                ll = (linearlayout) findviewbyid(r.id.ll_splash_main);

                alphaanimation alphaanimation = new alphaanimation(0.0f, 1.0f);

                alphaanimation.setduration(2000);

                ll.startanimation(alphaanimation);

                progressdialog = new progressdialog(this);

                progressdialog.setprogressstyle(progressdialog.style_horizontal);

                progressdialog.setmessage("正在下载...");

                new thread()

                        public void run()

                                try

                                {

                                        sleep(3000);

                                        handler.sendemptymessage(0);

                                }

                                catch (interruptedexception e)

                                        e.printstacktrace();

                        };

                }.start();

        private void showupdatedialog()

                alertdialog.builder builder = new alertdialog.builder(this);

                builder.seticon(android.r.drawable.ic_dialog_info);

                builder.settitle("升级提醒");

                builder.setmessage(info.getdescription());

                builder.setcancelable(false);

                builder.setpositivebutton("确定", new dialoginterface.onclicklistener()

                        @override

                        public void onclick(dialoginterface dialog, int which)

                                if(environment.getexternalstoragestate().equals(environment.media_mounted))

                                        file dir = new file(environment.getexternalstoragedirectory(), "/security/update");

                                        if(!dir.exists())

                                        {

                                                dir.mkdirs();

                                        }

                                        string apkpath = environment.getexternalstoragedirectory() + "/security/update/new.apk";

                                        updatetask task = new updatetask(info.geturl(), apkpath);

                                        progressdialog.show();

                                        new thread(task).start();

                                else

                                        toast.maketext(splashactivity.this, "sd卡不可用,请插入sd卡", toast.length_short).show();

                                        loadmainui();

                });

                builder.setnegativebutton("取消", new dialoginterface.onclicklistener()

                                loadmainui();

                builder.create().show();

        private boolean isneedupdate(string version)

                updateinfoservice updateinfoservice = new updateinfoservice(this);

                try

                        info = updateinfoservice.getupdateinfo(r.string.serverurl);

                        string v = info.getversion();

                        if(v.equals(version))

                                log.i(tag, "当前版本:" + version);

                                log.i(tag, "最新版本:" + v);

                                return false;

                        else

                                log.i(tag, "需要更新");

                                return true;

                catch (exception e)

                        e.printstacktrace();

                        toast.maketext(this, "获取更新信息异常,请稍后再试", toast.length_short).show();

                        loadmainui();

                return false;

        private string getversion()

                        packagemanager packagemanager = getpackagemanager();

                        packageinfo packageinfo = packagemanager.getpackageinfo(getpackagename(), 0);

                        return packageinfo.versionname;

                catch (namenotfoundexception e)

                        return "版本号未知";

        private void loadmainui()

                intent intent = new intent(this, mainactivity.class);

                startactivity(intent);

                finish();

        /**

         * 安装apk

         * @param file 要安装的apk的目录

         */

        private void install(file file)

                intent intent = new intent();

                intent.setaction(intent.action_view);

                intent.setdataandtype(uri.fromfile(file), "application/vnd.android.package-archive");

        //===========================================================================================

         * 下载的线程

         *

        class updatetask implements runnable

                private string path;

                private string filepath;

                public updatetask(string path, string filepath)

                        this.path = path;

                        this.filepath = filepath;

                @override

                public void run()

                        try

                                file file = downloadtask.getfile(path, filepath, progressdialog);

                                progressdialog.dismiss();

                                install(file);

                        catch (exception e)

                                e.printstacktrace();

                                toast.maketext(splashactivity.this, "更新失败", toast.length_short).show();

ps:上面那个com.xiaobin.security.ui.splashactivity类里面的那个handler是我为让用户清楚看到那个启动界面而设置的,不然,因为都是在同一个局域网里面,一下子就会完成那个更新的判断的啦,如果不用更新,那就会看不到那个启动界面的啦,所以为了我们能够看到那个界面,我让它休眠了2秒钟,才进行与服务器更新的,所以有什么不明白的也可以问一下

就这样子,我们就把启动界面时候,从服务器获取最新版的内容,然后提示用户是不是要更新的处理弄好啦! 既然启动界面弄好啦,那么,我们接下来,肯定是要做我们最重要的主界面啦 我们的主界面用到的是一个叫gridview的控件,它需要一个adapter,所以我们也要新建一个adapter的类 下面是主界面的布局文件

<?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="40dip"

        android:gravity="center_vertical|center_horizontal"

        android:background="@drawable/title_background"

        android:orientation="vertical">

        <textview

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:textcolor="@android:color/white"

            android:textsize="22sp"

            android:text="@string/main"/>

    </linearlayout>

    <gridview

        android:id="@+id/gv_main"

        android:layout_height="match_parent"

        android:verticalspacing="8dip"

        android:numcolumns="2" />

</linearlayout>

下面是adapter类的代码com.xiaobin.security.adapter.mainuiadapter

package com.xiaobin.security.adapter;

import android.content.context;

import android.content.sharedpreferences;

import android.view.layoutinflater;

import android.view.view;

import android.view.viewgroup;

import android.widget.baseadapter;

import android.widget.imageview;

public class mainuiadapter extends baseadapter

        private static final string[] names = new string[] {"手机防盗", "通讯卫士", "软件管理", "流量管理", "任务管理", "手机杀毒",

                        "系统优化", "高级工具", "设置中心"};

        private static final int[] icons = new int[] {r.drawable.widget01, r.drawable.widget02, r.drawable.widget03,

                        r.drawable.widget04, r.drawable.widget05, r.drawable.widget06, r.drawable.widget07,

                        r.drawable.widget08, r.drawable.widget09};

        //声明成静态,起到一定的优化作用,关于adapter还有别的优化方法的,有机会我们再说

        private static imageview imageview;

        private static textview textview;

        private context context;

        private layoutinflater inflater;

        private sharedpreferences sp;

        public mainuiadapter(context context)

                this.context = context;

                inflater = layoutinflater.from(this.context);

                sp = context.getsharedpreferences("config", context.mode_private);

        public int getcount()

                return names.length;

        public object getitem(int position)

                return position;

        public long getitemid(int position)

        public view getview(int position, view convertview, viewgroup parent)

                view view = inflater.inflate(r.layout.main_item, null);

                imageview = (imageview) view.findviewbyid(r.id.iv_main_icon);

                textview = (textview) view.findviewbyid(r.id.tv_main_name);

                imageview.setimageresource(icons[position]);

                textview.settext(names[position]);

                if(position == 0)

                        string name = sp.getstring("lostname", "");

                        if(!name.equals(""))

                                textview.settext(name);

                return view;

adapter也写好啦,那么接下来,肯定就是我们的主界面啦com.xiaobin.security.ui.mainactivity

import com.xiaobin.security.adapter.mainuiadapter;

import android.content.sharedpreferences.editor;

import android.widget.adapterview;

import android.widget.edittext;

import android.widget.adapterview.onitemlongclicklistener;

import android.widget.gridview;

import android.widget.adapterview.onitemclicklistener;

public class mainactivity extends activity implements onitemclicklistener

        private gridview gridview;

        private mainuiadapter adapter ;

                setcontentview(r.layout.main);

                sp = this.getsharedpreferences("config", context.mode_private);

                gridview = (gridview) findviewbyid(r.id.gv_main);

                adapter = new mainuiadapter(this);

                gridview.setadapter(adapter);

                gridview.setonitemclicklistener(this);

                gridview.setonitemlongclicklistener(new onitemlongclicklistener()

                        public boolean onitemlongclick(adapterview<?> parent, final view view, int position, long id)

                                if(position == 0)        //这个是因为,如果我们的手机被盗了,用户一看到第一个手机防盗,那样肯定会先卸载我们的程序的,所以我们在手机防盗这个item里面,设置了一个重命名的功能

                                        alertdialog.builder builder = new alertdialog.builder(mainactivity.this);

                                        builder.settitle("设置");

                                        builder.setmessage("请输入要理性的名称");

                                        final edittext et = new edittext(mainactivity.this);

                                        et.sethint("新名称");

                                        builder.setview(et);

                                        builder.setpositivebutton(android.r.string.ok, new dialoginterface.onclicklistener()

                                                @override

                                                public void onclick(dialoginterface dialog, int which)

                                                {

                                                        string name = et.gettext().tostring();

                                                        if(name.equals(""))

                                                        {

                                                                toast.maketext(mainactivity.this, "输入内容不能为空", toast.length_short).show();

                                                        }

                                                        else

                                                                editor editor = sp.edit();

                                                                editor.putstring("lostname", name);

                                                                editor.commit();

                                                                textview tv = (textview) view.findviewbyid(r.id.tv_main_name);

                                                                tv.settext(name);

                                                                adapter.notifydatasetchanged();

                                                }

                                        });

                                        builder.setnegativebutton(android.r.string.cancel, new dialoginterface.onclicklistener()

                                                        // todo auto-generated method stub

                                        builder.create().show();

        public void onitemclick(adapterview<?> parent, view view, int position, long id)

                switch(position)

                        case 0 : //手机防盗

                                break;

                        case 1 : //通讯卫士

                        case 2 : //软件管理

                        case 3 : //流量管理

                        case 4 : //任务管理

                        case 5 : //手机杀毒

                        case 6 : //系统优化

                        case 7 : //高级工具

                        case 8 : //设置中心

                        default :

上面的那个重命名的功能,是我们把重新命名的名字,存放到一个sharedpreferences里面的,然后下一次启动的时候,就先检查里面有没有对应的值,没有就用默认的,有就用用户自己命名的 好啦,今天的代码基本上写得差不多的啦,现在只剩下添加权限啦,因为要读取sd卡,所以要添加相应的权限

<uses-permission android:name="android.permission.mount_unmount_filesystems" />

    <uses-permission android:name="android.permission.write_external_storage"/>

现在就可以测试啦,记得要把服务器打开喔,还要昨天说的那个服务器的目录下面放一个apk喔,并把那个update.xml修改成与现在这个版本不一致的喔,不然不会更新的,不明白的可以看看下面的图

手机卫士03-下载app并安装

注意一下名称的对应 好啦,今天就说到这里啦

手机卫士03-下载app并安装

mb, 下载次数: 1115)

继续阅读