• Android下载更新的安装包以及九宫格界面


    继上篇博客,我接下来做的是一个九宫格界面,但是对之前的Splash页面我还有要说的就是,当出现网络异常、json解析异常或者没有更新的时候,我们都必须要跳转到我们的主页面,因为Splash页面仅是展示一下我们的开发的品牌和版本信息,我们没有必要因为网络没有接通等一些异常,就让用户使用不了我们的软件。所以我们应该做的 是当出现这些异常的时候,我们要用Toast提示一下用户到底出现了什么异常。所以在之前的代码基础上我增加了红色的代码。

     上篇博客当我们检查到新版本的时候,我们来下载这个安装包。以及显示下载的进度。下面我来展示一下效果图:

    package com.itcast.mobilesafe58.activity;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    
    import com.itcast.mobilesafe58.utils.StreamUtils;
    import com.itcast.mobilesafe58.utils.ToastUtils;
    import com.lidroid.xutils.HttpUtils;
    import com.lidroid.xutils.exception.HttpException;
    import com.lidroid.xutils.http.ResponseInfo;
    import com.lidroid.xutils.http.callback.RequestCallBack;
    
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.Message;
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.content.DialogInterface.OnClickListener;
    import android.content.Intent;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.view.Menu;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Toast;
    
    /*
     * 展示品牌---->初始化数据---->检查版本---->校验合法性
     */
    public class SplashActivity extends Activity {
        private static final int UPDATE_DIALOG = 1;//更新提醒
        private static final int NETWORK_ERROR = 2;//网络异常
        private static final int JSON_ERROR = 3;//数据解析失败
        private static final int URL_ERROR = 4;//网络异常
        private static final int ENTER_HOME = 5;//跳转主页面
        //控件初始化
        private TextView tvVersion;
        private TextView tvProgress;
        //服务器的返回值
        private String mVersionName;//成员变量
        private int mVersionCode;
        private String mDescription;
        private String mDownloadUrl;
        //消息传递
        private Handler mHandler = new Handler(){
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case UPDATE_DIALOG:
                    showUpdateDialog();
                    break;
                case NETWORK_ERROR:
                    ToastUtils.showToast(getApplicationContext(), "网络异常");
                    enterHome();
                    break;
                case JSON_ERROR:
                    ToastUtils.showToast(getApplicationContext(), "数据解析失败");
                    enterHome();
                    break;
                case URL_ERROR:
                    ToastUtils.showToast(getApplicationContext(), "网络连接异常");
                    enterHome();
                    break;
                case ENTER_HOME:
                    enterHome();
                default:
                    break;
                }
            };
        };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_splash);
            tvVersion = (TextView)findViewById(R.id.tv_version);
            tvProgress = (TextView)findViewById(R.id.tv_progress);
            tvVersion.setText("版本名:"+getVersionName());
            checkVersion();//检查版本
        }
        /*
         * 检查版本更新
         */
        private void checkVersion() {
            // TODO Auto-generated method stub
            new Thread(){
                long startTime = System.currentTimeMillis();//开始时间
                Message msg = Message.obtain();//获取消息
                public void run(){
                    try {
                        //
                        URL url = new URL("http://10.0.2.2:8080/versionCode.json");                    
                        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                        conn.setConnectTimeout(2000);//连接网络超时
                        conn.setReadTimeout(2000);//读取超时
                        conn.setRequestMethod("GET");//访问方法
                        conn.connect();//连接网络
                        int responseCode = conn.getResponseCode();
                        if(responseCode == 200){
                            String result = StreamUtils.streamToString(conn.getInputStream());
                            System.out.println("访问成功--->"+result);
                            //json数据解析
                                JSONObject  jo = new JSONObject(result);
                                mVersionName = jo.getString("versionName");
                                mVersionCode = jo.getInt("versionCode");
                                mDescription = jo.getString("description");
                                mDownloadUrl = jo.getString("downloadUrl");
                                System.out.println("versionCode--->"+mVersionCode);
                                if (getVersionCode()<mVersionCode) {//如果软件的版本与网络中的版本号不一致,提示用户更新版本
                                    System.out.println("有新版本!!!");
                                    msg.what = UPDATE_DIALOG;
                                }else{
                                    System.out.println("没有新版本!!!");
                                    //跳转到主页面
                                    msg.what = ENTER_HOME;
                                }
                        }
                    } catch (MalformedURLException e) {
                        //url异常
                        // TODO Auto-generated catch block
                        msg.what = URL_ERROR;
                        e.printStackTrace();
                    } catch (IOException e) {
                        //网络异常
                        // TODO Auto-generated catch block
                        msg.what = NETWORK_ERROR;
                        e.printStackTrace();
                    }catch (JSONException e) {
                        //json异常
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        msg.what = JSON_ERROR;
                    }finally{
                        long endTime = System.currentTimeMillis();//访问网络结束时间
                        long timeUsed = endTime - startTime;//访问网络总的用时
                        if (timeUsed<2000) {//如果访问网络的时间小于2秒,就展示闪屏页面。目的是凑够两秒,来展示软件的品牌。
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        
                        mHandler.sendMessage(msg);//发送消息
                    }
                }
    
                
            }.start();
            
        }
        /*
         * 用于提醒用户更新的提示窗
         */
        protected void showUpdateDialog() {
            // TODO Auto-generated method stub
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("发现新版本:"+mVersionName);
            builder.setMessage(mDescription);//新版本的描述
            builder.setPositiveButton("立即升级", new OnClickListener() {
                
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub
                    System.out.println("发现新版本");
                    downloadApk();
                }
            });
            builder.setNegativeButton("以后再说", new OnClickListener() {
                
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub
                    enterHome();
                }
            });
            builder.show();
            
        }
        /*
         * 下载安装包
         */
        protected void downloadApk(){
            String target = Environment.getExternalStorageDirectory().getAbsolutePath()+"/mobilesafe.apk";
            tvProgress.setVisibility(View.VISIBLE);
            HttpUtils utils = new HttpUtils();
            utils.download(mDownloadUrl, target, new RequestCallBack<File>() {
                //下载成功
                @Override
                public void onSuccess(ResponseInfo<File> responseInfo) {
                    // TODO Auto-generated method stub
                    System.out.println("下载成功!!!!");
                    File result = responseInfo.result;
                    tvProgress.setVisibility(View.GONE);
                    enterHome();
                }
                /*
                 * 正在下载
                 * total 文件总大小
                 * current 当前下载的大小
                 * isUploading 是否正在上传
                 * (non-Javadoc)
                 * @see com.lidroid.xutils.http.callback.RequestCallBack#onLoading(long, long, boolean)
                 */
                
                public void onLoading(long total, long current, boolean isUploading) {
                    // TODO Auto-generated method stub
                    super.onLoading(total, current, isUploading);
                    //
                    int percent = (int) ((current*100)/total);
                    tvProgress.setText("下载进度:"+percent+"%");
                }
                //下载失败
                @Override
                public void onFailure(HttpException error, String msg) {
                    // TODO Auto-generated method stub
                    System.out.println("下载失败!!!!");
                    //ToastUtils.showToast(getApplicationContext(),"下载失败!!");
                    error.printStackTrace();
                    
                }
            });
        }
        /*
         * 获取版本名
         */
        private String getVersionName() {
            // TODO Auto-generated method stub
            //获取包管理器
            PackageManager pm = getPackageManager();
            try {
                PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
                int versionCode = packageInfo.versionCode;//获取版本号
                String versionName = packageInfo.versionName;//获取版本名
                System.out.println("versionName"+versionName+",versionCode"+versionCode);
                return versionName;
            } catch (NameNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return "";
        }
    /*
     * 获取版本号
     */
        private int getVersionCode() {
            // TODO Auto-generated method stub
            //获取包管理器
            PackageManager pm = getPackageManager();
            try {
                PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
                int versionCode = packageInfo.versionCode;//获取版本号
                return versionCode;
            } catch (NameNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return 0;
        }
        //跳转到主页面
        private void enterHome(){
            startActivity(new Intent(this,HomeActivity.class));//开启的新的页面
            finish();//结束原来的页面
        }
       
        
    }

    当我们运行程序的时候就会发现,我们的Splash页面展示的时间太短暂,为了更好的让Splash页面的功能能够体现我们让跳转页面的时间慢一点,这样我们就可以展示一下我们的品牌。但是如果用户的网速特别慢打开软件都需要花费很长时间,我们就没有必要让用户看我们的页面了。这样的话就需要我们来计算一下开始进入程序的时间,以及结束的时间,当用时小于2秒时,我们就让剩下的时间看一会闪屏页面。否则就直接跳转到主页面。所以我在我的程序中添加了一下的代码:上面程序的粉红色部分

    好了,上篇的博客补充完毕。接下来介绍一下我做的九宫格页面。先把效果展示一下:

     

    我们做九宫格经常用到的一个控件就是GridView,下面我把我的布局文件写在下面,这样的话可以更好的讲解一下九宫格当中的特殊属性:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/white"
        android:orientation="vertical" >
     <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:background="#8866FF00"
            android:textColor="#000"
            android:textSize="30sp"
            android:text="功能列表" />
    <GridView 
            android:id="@+id/gv_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:verticalSpacing="15dp"           //这是定义每一行和每一行之间的间隔
            android:numColumns="3">               //这是定义一行有几个图片
        
    </GridView>
    </LinearLayout>

    下面是第一个功能模块-----》手机防盗功能的开发,当用户第一次点击手机防盗的时候会弹出一个设置密码的对话框,实现的效果图是:

     实现代码是:

    package com.itcast.mobilesafe58.activity;
    
    import com.itcast.mobilesafe58.utils.ToastUtils;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.app.AlertDialog.Builder;
    import android.app.Application;
    import android.content.Intent;
    import android.text.TextUtils;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.GridView;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class HomeActivity extends Activity {
    
        private GridView gvHome;
       //把需要添加的文字写在一个数组当中
        private String[] mHomeList = new String[]{"手机防盗","通讯卫士",
                "软件管家","病毒查杀","缓存清理","进程管理","流量统计","高级工具","设置中心"};
    //把需要添加的图片放在一个数组当中
    private int[] mImageIds = new int[]{R.drawable.shi04xi, R.drawable.qi08ta,R.drawable.qi06ta,R.drawable.qi07ta, R.drawable.qi07ta,R.drawable.qi08ta,R.drawable.qi09ta, R.drawable.qi08ta,R.drawable.qi09ta}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); gvHome = (GridView)findViewById(R.id.gv_home); gvHome.setAdapter(new HomeAdapter());//与ListView极其相似 //设置条目的点击事件 gvHome.setOnItemClickListener(new OnItemClickListener() { //parent代表gridview,view代表每个条目的view对象,position代表每个条目的位置 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub switch (position) { case 0://手机防盗 showSafeDialog(); break; case 1://通讯卫士 break; case 2://软件管家 break; case 3://病毒查杀 break; case 4://缓存清理 break; case 5://进程管理 break; case 6://流量统计 break; case 7://高级工具 break; case 8://设置中心 break; default: break; } } }); } /* * 密码弹窗 */ protected void showSafeDialog() { // TODO Auto-generated method stub //弹出设置密码的对话框 showSetUpPswdDialog(); } /* * 设置密码弹窗 */ private void showSetUpPswdDialog() { // TODO Auto-generated method stub AlertDialog.Builder builder = new AlertDialog.Builder(this); final AlertDialog dialog = builder.create();//创建dialog对象 View view = View.inflate(this, R.layout.dialog_set_password, null); dialog.setView(view, 0, 0, 0, 0);//给dialog设置自定义的布局,强制把上下左右边距设置为0,为了兼容2.x版本 final EditText etPassword = (EditText)view.findViewById(R.id.et_password); final EditText etPasswordConfirm = (EditText)view.findViewById(R.id.et_password_confirm); Button btn_OK = (Button)view.findViewById(R.id.btn_ok); Button btn_cancel = (Button)view.findViewById(R.id.btn_cancel); btn_OK.setOnClickListener(new OnClickListener() { /* * 判断两次输入的密码是否为空,两次输入的密码是否一致 * (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ @Override public void onClick(View v) { // TODO Auto-generated method stub String password = etPassword.getText().toString().trim(); String passwordConfirm = etPasswordConfirm.getText().toString().trim(); if (TextUtils.isEmpty(password)&&TextUtils.isEmpty(passwordConfirm)) { ToastUtils.showToast(getApplicationContext(), "输入框不能为空"); }else{ if (password .equals(passwordConfirm)) { ToastUtils.showToast(getApplicationContext(), "登录成功"); dialog.dismiss();//隐藏弹窗 HomeActivity.this.startActivity(new Intent(getApplicationContext(),LostAndFindActivity.class)); }else{ ToastUtils.showToast(getApplicationContext(), "两次输入的密码不一致!"); } } } private void startActivity(Application application, Class<LostAndFindActivity> class1) { // TODO Auto-generated method stub } }); btn_cancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }); dialog.show(); } /* * 九宫格数据适配器 */ class HomeAdapter extends BaseAdapter{ //得到item的个数 @Override public int getCount() { // TODO Auto-generated method stub return mHomeList.length; } //根据位置获取对象 @Override public String getItem(int position) { // TODO Auto-generated method stub return mHomeList[position]; } // @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } //初始化每一个item的布局 @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View view = View.inflate(getApplicationContext(), R.layout.list_item_home, null); ImageView ivHome = (ImageView)view.findViewById(R.id.iv_home); TextView tvHome = (TextView) view.findViewById(R.id.tv_home); tvHome.setText(mHomeList[position]); ivHome.setImageResource(mImageIds[position]); return view; } } }
  • 相关阅读:
    lazarus中objfpc编译模式与delphi编译模式的不同
    TFDUpdateOptions.UpdateNonBaseFields
    protobuf数据类型与delphi数据类型映射
    delphi基于google protobuf开发
    mormot https设置
    基于数据模型的序列
    fastmove+fastcode
    localstack 应用架构
    dremio 21 pdfs 不在支持
    dremio 21 其他一些新特性
  • 原文地址:https://www.cnblogs.com/kangyaping/p/5500228.html
Copyright © 2020-2023  润新知