Safe-splash页面(1)

来源:互联网 发布:mac怎么下载idea 编辑:程序博客网 时间:2024/05/21 18:40

这个页面的功能有:基本的显示加载的logo页面,logo页面会有一些文本的信息,版本号版本名等信息。加载的时候,会保持logo页面至少2秒(睡眠的方式来实现)。进入的时候会判断一下当前的版本和服务端获取的json的版本信息,如果服务端的版本号大于现在的版本号会进行升级,同时splash页面会现在下载的进度等等信息。下载完成以后用户可以选择安装或者取消安装跳转首页,或者直接返回不安装跳转首页。

获取版本信息

/** * 获取版本的版本名 */private String getVersionName() {// 获取到包的管理器PackageManager packagerManager = getPackageManager();try {// 获取包名PackageInfo packageInfo = packagerManager.getPackageInfo(getPackageName(), 0);// 版本号int versionCode = packageInfo.versionCode;// 版本名String versionName = packageInfo.versionName;System.out.println("versionName:" + versionName);return versionName;} catch (NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return "";}/** * 获取版本的版本号 */private int getVersionCode() {// 获取到包的管理器PackageManager packagerManager = getPackageManager();try {// 获取包名PackageInfo packageInfo = packagerManager.getPackageInfo(getPackageName(), 0);// 版本号int versionCode = packageInfo.versionCode;// 版本名String versionName = packageInfo.versionName;System.out.println("versionCode:" + versionCode);return versionCode;} catch (NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return 0;}

下载版本,通过子线程的方式来进行下载,防止阻塞主线程,利用Handle消息队列机制来根据不同的消息来加载

/** * 从服务器获取版本信息校验,确定是否需要进行升级 */private void checkVersion() {// 获取当前的时间final long startTime = System.currentTimeMillis();// 防止阻塞主线程new Thread() {@Overridepublic void run() {String path = "http://192.168.0.100:8080/update.json";Message msg = Message.obtain();HttpURLConnection conn = null;try {URL url = new URL(path);conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");// 请求方式conn.setConnectTimeout(5000);// 链接超时conn.setReadTimeout(5000);// 响应超时,连接成功,但服务器不给响应conn.connect();// 链接服务器int responseCode = conn.getResponseCode();// 获取响应码if (responseCode == 200) {InputStream inputStream = conn.getInputStream();String result = StreamUtils.readFromeStream(inputStream);System.out.println("返回的结果是:" + result);// 解析json,作者的版本鸡西不了json,因此设置成固定值,正常应该是解析出来的值,注释下面5行/* * 解析不了json为了测试,写成固定值 JSONObject jo = new * JSONObject(result); mVersionName = * jo.getString("versionName"); mVersionCode = * jo.getInt("VersionCode"); mDesc = * jo.getString("description"); mDownloadUrl = * jo.getString("downloadUrl"); */JSONObject jo = new JSONObject(result);mVersionName = "2.0";mVersionCode = 2;mDesc = "赶紧升级啊";mDownloadUrl = "http://192.168.0.100:8080/Safe2.0.apk";System.out.println("添加的功能:" + mDesc);if (mVersionCode > getVersionCode()) {// 服务器的版本号大于本地的版本号,需要升级// 需要升级,弹出升级对话框msg.what = CODE_UPDATE_DIALOG;} else {// 没有版本更新,跳转主页msg.what = CODE_ENTER_HOME;}}} catch (MalformedURLException e) {// 更新异常msg.what = CODE_UPDATE_ERROR;e.printStackTrace();} catch (IOException e) {// 网络异常msg.what = CODE_NET_ERROR;e.printStackTrace();} catch (JSONException e) {// JSON异常msg.what = CODE_JSON_ERROR;e.printStackTrace();} finally {// 强制logo界面加载显示2slong endTime = System.currentTimeMillis();long timeUsed = endTime - startTime;if (timeUsed < 2000) {try {Thread.sleep(2000 - timeUsed);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 主线程发消息mHandler.sendMessage(msg);// 关闭网络连接if (conn != null) {conn.disconnect();}}}}.start();}

消息队列的处理

private Handler mHandler = new Handler() {public void handleMessage(android.os.Message msg) {switch (msg.what) {case CODE_UPDATE_DIALOG:showUpdate();break;case CODE_UPDATE_ERROR:Toast.makeText(SplashActivity.this, "升级错误", Toast.LENGTH_SHORT).show();// 跳转主页面enterHome();break;case CODE_NET_ERROR:Toast.makeText(SplashActivity.this, "网络错误", Toast.LENGTH_SHORT).show();// 跳转主页面enterHome();break;case CODE_JSON_ERROR:Toast.makeText(SplashActivity.this, "JSON数据解析错误",Toast.LENGTH_SHORT).show();// 跳转主页面enterHome();break;case CODE_ENTER_HOME:// 跳转主页面enterHome();break;default:break;}}};

下载apk和安装apk的方法

/** * 下载新版的apk */protected void download() {// 先判断有没有sd卡if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 下载的时候让进度显示tv_progress.setVisibility(View.VISIBLE);// 文件下载的位置String target = Environment.getExternalStorageDirectory()+ "/UPDATE.APK";// 利用github的Xutils执行下载HttpUtils utils = new HttpUtils();utils.download(mDownloadUrl, target, new RequestCallBack<File>() {@Overridepublic void onLoading(long total, long current,boolean isUploading) {super.onLoading(total, current, isUploading);System.out.println("下载进度" + current + "/" + total);tv_progress.setText("下载进度:" + current * 100 / total + "%");}// 下载失败@Overridepublic void onFailure(HttpException arg0, String arg1) {Toast.makeText(SplashActivity.this, "下载失败",Toast.LENGTH_SHORT).show();}// 下载成功@Overridepublic void onSuccess(ResponseInfo<File> arg0) {System.out.println("下载成功");// 跳转到系统的下载页面Intent intent = new Intent(Intent.ACTION_VIEW);intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setDataAndType(Uri.fromFile(arg0.result),"application/vnd.android.package-archive");// startActivity(intent);startActivityForResult(intent, 0);// 如果用户取消安装,会返回结果,会调用发onActivityResult}});} else {Toast.makeText(SplashActivity.this, "没有sd卡", Toast.LENGTH_SHORT).show();}}

在安装界面,用户可能点击返回,处理如下

/** * 防止用户在升级界面按下返回按键 */@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {enterHome();super.onActivityResult(requestCode, resultCode, data);}

总代码如下:

package com.ldw.safe.Activity;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import org.json.JSONException;import org.json.JSONObject;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.DialogInterface.OnCancelListener;import android.content.DialogInterface.OnClickListener;import android.content.Intent;import android.content.SharedPreferences;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.view.View;import android.view.animation.AlphaAnimation;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;import com.ldw.safe.R;import com.ldw.safe.db.dao.AntiVirous;import com.ldw.safe.utils.StreamUtils;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 com.lidroid.xutils.http.client.HttpRequest.HttpMethod;public class SplashActivity extends Activity {protected static final int CODE_UPDATE_DIALOG = 0;protected static final int CODE_UPDATE_ERROR = 1;protected static final int CODE_NET_ERROR = 2;protected static final int CODE_JSON_ERROR = 3;protected static final int CODE_ENTER_HOME = 4;private TextView tv_version;private TextView tv_progress;// 下载进度显示// 服务器json参数private String mVersionName;private int mVersionCode;private String mDesc;private String mDownloadUrl;private SharedPreferences mPref;//把设置的数据保存在mPrefprivate Handler mHandler = new Handler() {public void handleMessage(android.os.Message msg) {switch (msg.what) {case CODE_UPDATE_DIALOG:showUpdate();break;case CODE_UPDATE_ERROR:Toast.makeText(SplashActivity.this, "升级错误", Toast.LENGTH_SHORT).show();// 跳转主页面enterHome();break;case CODE_NET_ERROR:Toast.makeText(SplashActivity.this, "网络错误", Toast.LENGTH_SHORT).show();// 跳转主页面enterHome();break;case CODE_JSON_ERROR:Toast.makeText(SplashActivity.this, "JSON数据解析错误",Toast.LENGTH_SHORT).show();// 跳转主页面enterHome();break;case CODE_ENTER_HOME:// 跳转主页面enterHome();break;default:break;}}};private RelativeLayout splash;private AntiVirous virous;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_splash);// 显示版本号TextView tv_version = (TextView) findViewById(R.id.tv_version);tv_version.setText("版本号:" + getVersionName());// 下载进度显示,默认是隐藏的tv_progress = (TextView) findViewById(R.id.tv_progress);//获取splsh的全局属性splash = (RelativeLayout)findViewById(R.id.splash);mPref = getSharedPreferences("config", MODE_PRIVATE);copyDB("address.db");//拷贝数据库copyDB("antivirus.db");//拷贝病毒库//更新病毒库updateVirous();//检测设置是否设置了自动更新boolean autoUpdate = mPref.getBoolean("auto_update", true);if(autoUpdate){checkVersion();}else{//不自动升级mHandler.sendEmptyMessageDelayed(CODE_ENTER_HOME, 2000);//延迟2s进入主页}//让splash页面有一个渐变的效果AlphaAnimation anim = new AlphaAnimation(0.3f, 1f);anim.setDuration(2000);splash.startAnimation(anim);}/* * 更新病毒数据库 */private void updateVirous() {virous = new AntiVirous();//联网从服务器获取到最新数据的md5的特征码HttpUtils httpUtils = new HttpUtils();//新增的病毒库String url = "http://192.168.0.2:8080/virus.json";httpUtils.send(HttpMethod.GET, url, new RequestCallBack<String>() {@Overridepublic void onFailure(HttpException arg0, String arg1) {// TODO Auto-generated method stub}@Overridepublic void onSuccess(ResponseInfo<String> arg0) {//解析jsontry {JSONObject jsonObject = new JSONObject(arg0.result);/* 谷歌的gojosn Gson gson = new Gson();//解析jsonVirus virus = gson.fromJson(arg0.result, Virus.class);dao.addVirus(virus.md5, virus.desc); *///json的key-value配对{}String md5 = jsonObject.getString("md5");String desc = jsonObject.getString("desc");virous.addVirous(md5, desc);} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}/** * 获取版本的版本名 */private String getVersionName() {// 获取到包的管理器PackageManager packagerManager = getPackageManager();try {// 获取包名PackageInfo packageInfo = packagerManager.getPackageInfo(getPackageName(), 0);// 版本号int versionCode = packageInfo.versionCode;// 版本名String versionName = packageInfo.versionName;System.out.println("versionName:" + versionName);return versionName;} catch (NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return "";}/** * 获取版本的版本号 */private int getVersionCode() {// 获取到包的管理器PackageManager packagerManager = getPackageManager();try {// 获取包名PackageInfo packageInfo = packagerManager.getPackageInfo(getPackageName(), 0);// 版本号int versionCode = packageInfo.versionCode;// 版本名String versionName = packageInfo.versionName;System.out.println("versionCode:" + versionCode);return versionCode;} catch (NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return 0;}/** * 从服务器获取版本信息校验,确定是否需要进行升级 */private void checkVersion() {// 获取当前的时间final long startTime = System.currentTimeMillis();// 防止阻塞主线程new Thread() {@Overridepublic void run() {String path = "http://192.168.0.100:8080/update.json";Message msg = Message.obtain();HttpURLConnection conn = null;try {URL url = new URL(path);conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");// 请求方式conn.setConnectTimeout(5000);// 链接超时conn.setReadTimeout(5000);// 响应超时,连接成功,但服务器不给响应conn.connect();// 链接服务器int responseCode = conn.getResponseCode();// 获取响应码if (responseCode == 200) {InputStream inputStream = conn.getInputStream();String result = StreamUtils.readFromeStream(inputStream);System.out.println("返回的结果是:" + result);// 解析json,作者的版本鸡西不了json,因此设置成固定值,正常应该是解析出来的值,注释下面5行/* * 解析不了json为了测试,写成固定值 JSONObject jo = new * JSONObject(result); mVersionName = * jo.getString("versionName"); mVersionCode = * jo.getInt("VersionCode"); mDesc = * jo.getString("description"); mDownloadUrl = * jo.getString("downloadUrl"); */JSONObject jo = new JSONObject(result);mVersionName = "2.0";mVersionCode = 2;mDesc = "赶紧升级啊";mDownloadUrl = "http://192.168.0.100:8080/Safe2.0.apk";System.out.println("添加的功能:" + mDesc);if (mVersionCode > getVersionCode()) {// 服务器的版本号大于本地的版本号,需要升级// 需要升级,弹出升级对话框msg.what = CODE_UPDATE_DIALOG;} else {// 没有版本更新,跳转主页msg.what = CODE_ENTER_HOME;}}} catch (MalformedURLException e) {// 更新异常msg.what = CODE_UPDATE_ERROR;e.printStackTrace();} catch (IOException e) {// 网络异常msg.what = CODE_NET_ERROR;e.printStackTrace();} catch (JSONException e) {// JSON异常msg.what = CODE_JSON_ERROR;e.printStackTrace();} finally {// 强制logo界面加载显示2slong endTime = System.currentTimeMillis();long timeUsed = endTime - startTime;if (timeUsed < 2000) {try {Thread.sleep(2000 - timeUsed);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 主线程发消息mHandler.sendMessage(msg);// 关闭网络连接if (conn != null) {conn.disconnect();}}}}.start();}/** * 弹出升级对话框 */private void showUpdate() {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("最新版本:" + mVersionName);builder.setMessage(mDesc);// builder.setCancelable(false);//在升级页面不允许返回,这种方法不可取builder.setPositiveButton("立即更新", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 下载新版的apkdownload();}});builder.setNegativeButton("稍后更新", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 用户不升级直接跳转到主页enterHome();}});// 监听升级页面,用户按下返回按键,直接跳到主界面builder.setOnCancelListener(new OnCancelListener() {@Overridepublic void onCancel(DialogInterface dialog) {// TODO Auto-generated method stubenterHome();}});builder.show();}/** * 下载新版的apk */protected void download() {// 先判断有没有sd卡if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 下载的时候让进度显示tv_progress.setVisibility(View.VISIBLE);// 文件下载的位置String target = Environment.getExternalStorageDirectory()+ "/UPDATE.APK";// 利用github的Xutils执行下载HttpUtils utils = new HttpUtils();utils.download(mDownloadUrl, target, new RequestCallBack<File>() {@Overridepublic void onLoading(long total, long current,boolean isUploading) {super.onLoading(total, current, isUploading);System.out.println("下载进度" + current + "/" + total);tv_progress.setText("下载进度:" + current * 100 / total + "%");}// 下载失败@Overridepublic void onFailure(HttpException arg0, String arg1) {Toast.makeText(SplashActivity.this, "下载失败",Toast.LENGTH_SHORT).show();}// 下载成功@Overridepublic void onSuccess(ResponseInfo<File> arg0) {System.out.println("下载成功");// 跳转到系统的下载页面Intent intent = new Intent(Intent.ACTION_VIEW);intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setDataAndType(Uri.fromFile(arg0.result),"application/vnd.android.package-archive");// startActivity(intent);startActivityForResult(intent, 0);// 如果用户取消安装,会返回结果,会调用发onActivityResult}});} else {Toast.makeText(SplashActivity.this, "没有sd卡", Toast.LENGTH_SHORT).show();}}/** * 防止用户在升级界面按下返回按键 */@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {enterHome();super.onActivityResult(requestCode, resultCode, data);}/** * 进入主页面 */public void enterHome() {Intent intent = new Intent(this, HomeActivity.class);startActivity(intent);}/* * 拷贝数据库 */public void copyDB(String dbName){//获取数据库的文件路径,要拷贝的目标地址File targetFile = new File(getFilesDir(), dbName);////数据库存在if(targetFile.exists()){System.out.println("数据库已经存在");return;}FileOutputStream out = null;InputStream in = null;try {in = getAssets().open(dbName);out = new FileOutputStream(targetFile);//读数据int len = 0;byte[] buffer = new byte[1024];while((len = in.read(buffer)) != -1 ){out.write(buffer, 0, len);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {in.close();out.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}