杀毒卫士(1)—启动界面帮助类
(1)获取清单文件的所有信息ViewHelper
(2)连接服务器,验证是否有新版本更新LoginHelper
(3)是否是第一次登录的检测,显示不同的界面SafePreference
(4)有新的版本更新,下载并安装新版本DownloadHelper
(5)存放常量的类Const
(5)存放常量的类Const
/**
* 专门存放常量
*/
public class Const {
public static final String SPFNAME = "config";//SharePreference文件名
public static final String ISUPDATA = "updata";//是否检查版本更新
public static final String SAFEPASSWORD = "password";//设置我的手机防盗密码
}
(4)有新的版本更新,下载并安装新版本DownloadHelper
获取apk新版本:
(1)通过给定的apk下载url,下载apk,
public class DownloadHelper {
public static File getApkFile(String url, ProgressDialog pd){
//下载 读到sd 把文件返回回去
int last = url.lastIndexOf("/");
File file = new File(Environment.getExternalStorageDirectory(), url.substring(last+1));
try {
URL u = new URL(url);
HttpURLConnection con = (HttpURLConnection) u.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(5000);
if(con.getResponseCode()==200){
pd.setMax(con.getContentLength());
int num=0;
InputStream is = con.getInputStream();
FileOutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
os.write(buffer, 0, len);
num += len;
Thread.sleep(30);
pd.setProgress(num);
}
os.flush();
os.close();
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
(3)是否是第一次登录的检测,显示不同的界面SafePreference
通常用来存储一些系统成员变量,登录的用户信息:账号和密码; 是否是第一次登录
(a)、向sharepreference存储键值对的步骤:
//获取SharedPreferences 实例
SharedPreferences shp = context.getSharedPreferences("文件名",Context.MODE_PRIVATE);
//通过SharedPreferences获取Editor对象
Editor editor = shp.edit();
//通过向Editor存数键值对
editor.putString("key", "value");
//....putxx(key, value);
//最重要的提交editor
editor.commit();
(b)通过获取指定键的值
getXX(Context context, xx key,xx defaultValue)
public static String getStr(Context context, String key){
SharedPreferences sp = context.getSharedPreferences(Const.SPFNAME, 0);
return sp.getString(key, "");
}
实现
/**
* 对SharePreference操作
* 存
* 取
*/
public class SafePreference {
/**
* 往SharePreference中存数据
* @param contex
* @param key
* @param value
* 不仅可以保持字符串还可以保持boolean
*/
public static void save(Context context, String key, Object value){
//拿到SharePreference
SharedPreferences sp = context.getSharedPreferences(Const.SPFNAME, 0);
//判断要存的数据是什么数据
if(value instanceof String){
sp.edit().putString(key, (String)value).commit();
}else if(value instanceof Boolean){
sp.edit().putBoolean(key,(Boolean)value).commit();
}
}
/**
* 从SharePreference中取数据
* @param contex
* @param key
* @param value
*/
public static String getStr(Context context, String key){
SharedPreferences sp = context.getSharedPreferences(Const.SPFNAME, 0);
return sp.getString(key, "");
}
public static Boolean getBoolean(Context context, String key){
SharedPreferences sp = context.getSharedPreferences(Const.SPFNAME, 0);
return sp.getBoolean(key, false);
}
}
(2)连接服务器,验证是否有新版本更新LoginHelper
(a)创建一个单例LoginHelper
(b)连接服务器,验证是否更新
(c)下载更新
(d)
具体实现:
/**
* 专门处理登陆逻辑
*/
public class LoginHelper {
private static LoginHelper login;
private Activity context;
private UpdataBean bean;
private final int UPDATA = 11;//更新
private final int CONNECTERROR = 12;//连接服务器失败
private final int SERVICEERROR = 13;//服务器出错
private final int DOWNLOADERROR = 14;//下载失败
private ProgressDialog pd;
private LoginHelper(Activity context){
this.context = context;
}
public static LoginHelper getInstance(Activity context){
if(login==null){
login = new LoginHelper(context);
}
return login;
}
/**
* 连接服务器
*/
public void loginConnect(){
new Thread(new Runnable() {
@Override
public void run() {
connect();
}
}).start();
}
/**
* 访问服务器
*/
protected void connect() {
String apkurl = context.getResources().getString(R.string.apkurl);
Message msg = new Message();
try {
URL url = new URL(apkurl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(5000);
if(con.getResponseCode()==200){
//连接成功
bean = XmlParseUtil.getUpdataInfo(con.getInputStream());
if(bean!=null){
if(bean.getVersiion().equals(ViewHelper.getVersion(context))){
//无需更新,已经是最新版本,进入主界面
enterMain();
}else{
//有新版本,需要更新,弹开提示
msg.what = UPDATA;
handler.sendMessage(msg);
}
}
}else{
//连接失败,服务器出错
msg.what = SERVICEERROR;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
//服务器连不上
msg.what = CONNECTERROR;
handler.sendMessage(msg);
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATA://进行更新提示
updateTipDialog();
break;
case CONNECTERROR:
Toast.makeText(context, "连接服务器失败", 1).show();
enterMain();
break;
case SERVICEERROR:
Toast.makeText(context, "服务器出错", 1).show();
enterMain();
break;
case DOWNLOADERROR:
Toast.makeText(context, "下载失败", 1).show();
break;
}
super.handleMessage(msg);
}
};
/**
* 进入主界面
*/
private void enterMain(){
Intent intent = new Intent(context, MainActivity.class);
context.startActivity(intent);
context.finish();
}
/**
* 提示用户升级
*/
protected void updateTipDialog() {
AlertDialog.Builder builder = new Builder(context);
builder.setTitle("升级提示");
builder.setMessage(bean.getDes());
builder.setPositiveButton("升级", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
updateApk();
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
/**
* 下载更新apk
*/
protected void updateApk() {
//在下载的时候,显示一个进度条:动画 下载了多少
pd = new ProgressDialog(context);
pd.setTitle("正在下载...");
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.show();
new Thread(new Runnable() {
@Override
public void run() {
File file = DownloadHelper.getApkFile(bean.getApkUrl(), pd);
pd.dismiss();
if(file==null){
//下载失败
Message msg = new Message();
msg.what = DOWNLOADERROR;
handler.sendMessage(msg);
}else{
//进行安装
/**
* <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" />
<data android:scheme="file" />
<data android:mimeType="application/vnd.android.package-archive" />
</intent-filter>
*/
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(intent);
context.finish();
}
}
}).start();
}
public void destory(){
login = null;
}
}
(1)获取清单文件的所有信息ViewHelper
通过获取packageManager获取PackageInfo包含清单文件中所有的信息
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
public class ViewHelper {
/**
* 获取版本号
* @return
*/
public static String getVersion(Context context) {
PackageManager pm = context.getPackageManager();//拿到包的管理器
try {
//封装了所有的清单文件中的数据
PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0);
return info.versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
最后提供一个更新apk的实体类:
包含apk的url,描述,版本号
public class UpdataBean {
private String versiion;
private String des;
private String apkUrl;
public String getVersiion() {
return versiion;
}
public void setVersiion(String versiion) {
this.versiion = versiion;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public String getApkUrl() {
return apkUrl;
}
public void setApkUrl(String apkUrl) {
this.apkUrl = apkUrl;
}
}
在res/values/下创建一个config.xml,存储apk更新的url,
<resources>
<string name="apkurl">http://192.168.1.103:8080/info1.xml</string>
</resources>
解析xml,获取更新pak信息:
public class XmlParseUtil {
/**
* 解析xml
* @param inputStream
* @return
*/
public static UpdataBean getUpdataInfo(InputStream inputStream) {
//拿到解析器 初始化 拿到事件类型 如果是制定内容就放到bean中
XmlPullParser parser = Xml.newPullParser();
UpdataBean bean = new UpdataBean();
try {
parser.setInput(inputStream, "UTF-8");
int type = parser.getEventType();
while(type!=XmlPullParser.END_DOCUMENT){
switch (type) {
case XmlPullParser.START_TAG:
if("version".equals(parser.getName())){
bean.setVersiion(parser.nextText());
}else if("description".equals(parser.getName())){
bean.setDes(parser.nextText());
}else if("apkurl".equals(parser.getName())){
bean.setApkUrl(parser.nextText());
}
break;
}
type = parser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}