原文再续书接上一回,昨天我们把那个与服务器端的交互以及解析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>
- package com.xiaobin.security.ui;
- import java.io.File;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.ProgressDialog;
- 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()
- {
- @Override
- public void onClick(DialogInterface dialog, int which)
- {
- 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);
- loadMainUI();
- 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()
- {
- try
- {
- PackageManager packageManager = getPackageManager();
- PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0);
-
- return packageInfo.versionName;
- }
- catch (NameNotFoundException e)
- {
- e.printStackTrace();
- 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");
- finish();
- startActivity(intent);
- }
-
- //===========================================================================================
-
- /**
- * 下载的线程
- *
- */
- 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();
- progressDialog.dismiss();
- Toast.makeText(SplashActivity.this, "更新失败", Toast.LENGTH_SHORT).show();
- loadMainUI();
- }
- }
-
- }
- }
就这样子,我们就把启动界面时候,从服务器获取最新版的内容,然后提示用户是不是要更新的处理弄好啦! 既然启动界面弄好啦,那么,我们接下来,肯定是要做我们最重要的主界面啦 我们的主界面用到的是一个叫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_width="match_parent"
- android:layout_height="match_parent"
- android:verticalSpacing="8dip"
- android:numColumns="2" />
- </LinearLayout>
- 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;
- import android.widget.TextView;
- import com.xiaobin.security.R;
- 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);
- }
- @Override
- public int getCount()
- {
- return NAMES.length;
- }
- @Override
- public Object getItem(int position)
- {
- return position;
- }
- @Override
- public long getItemId(int position)
- {
- return position;
- }
- @Override
- 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;
- }
-
- }
- package com.xiaobin.security.ui;
- import com.xiaobin.security.R;
- import com.xiaobin.security.adapter.MainUIAdapter;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
- 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 ;
- private SharedPreferences sp;
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- 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()
- {
- @Override
- 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()
- {
- @Override
- public void onClick(DialogInterface dialog, int which)
- {
- // TODO Auto-generated method stub
-
- }
- });
- builder.create().show();
- }
- return false;
- }
- });
- }
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id)
- {
- switch(position)
- {
- case 0 : //手机防盗
- 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;
- }
- }
- }
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>