天天看點

手機衛士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)

繼續閱讀