public class SplashActivity extends Activity {
private static final String TAG = "mainactivity";
private static final int NEED_UPDATE = 1;
private static final int CONNECT_SERVER_ERROR = 2;
private static final int SHOW_MESSAGE=3;
private static final int HIDE_MESSAGE=4;
UpdateInfo info;
AddressService addressService;
TextView tv_copydb;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case NEED_UPDATE:
showUpdateDialog();
break;
case CONNECT_SERVER_ERROR:
showErrorDialog();
break;
case SHOW_MESSAGE:
tv_copydb.setVisibility(View.VISIBLE);
break;
case HIDE_MESSAGE:
tv_copydb.setVisibility(View.INVISIBLE);
break;
}
}
private void showErrorDialog() {
AlertDialog.Builder builder = new Builder(SplashActivity.this);
builder.setTitle("错误");
builder.setMessage("连接服务器失败");
builder.setPositiveButton(R.string.ok, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//finish();
//临时修改,不连接服务器也能进程序主界面
Intent intent = new Intent(SplashActivity.this,MainScreenActivity.class);
startActivity(intent);
finish();
}
});
builder.create().show();
}
/***
* 因为在非UI线程里面不能创建对话框,所以我们需要用handler 和 message 来实现创建对话框
* */
private void showUpdateDialog() {
AlertDialog.Builder builder = new Builder(SplashActivity.this);
//错误AlertDialog.Builder builder = new Builder(getApplicationContext());
//mainactivity.this 是 getApplicationContext()的子集.
//mainactivity 里面有一些参数 比如说当前activity 的windowlayout的一些参数是 getApplicationContext()所没有的
builder.setTitle(R.string.please_update);
builder.setMessage(info.getDescription());
builder.setPositiveButton(R.string.ok, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, "调用下载方法");
final ProgressDialog pd = new ProgressDialog(SplashActivity.this);
pd.setMessage(getApplicationContext().getResources().getString(R.string.downing));
pd.show();
try {
new Thread(){ //开辟线程下载服务器更新的apk文件
public void run() {
File file;
try {
file = DownLoadService.getFile(info.getUrl()); //解析的url
install(file);
pd.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}}.start();
} catch (Exception e) {
e.printStackTrace();
}
}
//确定了后开始安装,替换掉原来的了
private void install(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
finish(); //自己安装完了关闭AlertDialog
startActivity(intent);
}
});
builder.setNegativeButton(R.string.cancle, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, "用户取消");
Intent intent = new Intent(SplashActivity.this,MainScreenActivity.class);
startActivity(intent);
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}; //handler结束
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.splashactivity);
tv_copydb = (TextView) findViewById(R.id.copydatabase);
addressService = new AddressService(this);
boolean isexist = addressService.isExist();
if(isexist){//数据库存在不做任何操作
new Thread(new CheckVersionTask()).start();
}else{
new Thread(new CopyDBTask()).start();
}
AlphaAnimation aa = new AlphaAnimation(0.1f, 1.0f);
aa.setDuration(5000);
RelativeLayout rl = (RelativeLayout) this.findViewById(R.id.rl_splash);
rl.startAnimation(aa);
}
//初始化完address.db数据库,不存在的拷贝任务
private class CopyDBTask implements Runnable{
public void run() {
try {
sendShowTextMessage();
addressService.copyDataBase();
sendHideTextMessage();
new Thread(new CheckVersionTask()).start();
} catch (Exception e) {
e.printStackTrace();
}
}
//向handle发消息,更新textview,显示正在下载
private void sendShowTextMessage() {
Message msg = new Message();
msg.what = SHOW_MESSAGE;
handler.sendMessage(msg);
}
//下载完后更新textview为不可见
private void sendHideTextMessage() {
Message msg = new Message();
msg.what = HIDE_MESSAGE;
handler.sendMessage(msg);
}
}
//开辟线程检查是否需要更新升级 (解析服务器xml,判断服务器版本号与本地版本确定是否需要升级)
private class CheckVersionTask implements Runnable {
public void run() {
String path = getApplicationContext().getResources().getString(
R.string.server_url);
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setConnectTimeout(5000);
Thread.sleep(4000);
InputStream ins = conn.getInputStream();
info = UpdateInfoParser.getUpdateInfo(ins);
String version = getApplicationContext().getResources()
.getString(R.string.version);
if (version.equals(info.getVersion())) {
Log.i(TAG, "版本相同,无需升级");
Intent intent = new Intent(SplashActivity.this,MainScreenActivity.class);
startActivity(intent);
finish();
} else {
Log.i(TAG, "版本不相同,需要升级");
sendUpdateMessage();
}
} catch (Exception e) {
Message msg = new Message();
msg.what = CONNECT_SERVER_ERROR;
handler.sendMessage(msg);
e.printStackTrace();
}
}
private void sendUpdateMessage() {
Message msg = new Message();
msg.what = NEED_UPDATE;
handler.sendMessage(msg);
}
}
操作数据库的类:
/**
* 程序第一初始化的时候,通过类加载器把数据库拷贝到/data/data/<包名>/目录下
* @author Administrator
*
*/
public class AddressService {
public static final String TAG="AddressService";
Context context;
public static final String DBNAME= "address.db";
public AddressService(Context context) {
this.context = context;
}
/**
* 判断数据库是否存在
* @return
*/
public boolean isExist() {
File file = new File(context.getFilesDir(),DBNAME);
return file.exists();
}
/**
* 拷贝数据库到系统的/data/data/<包名>/下
* @throws Exception
*/
public void copyDataBase() throws Exception{
InputStream is = this.getClass().getClassLoader().getResourceAsStream("address.db");
File file = new File(context.getFilesDir(),DBNAME);
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer))!=-1){
fos.write(buffer, 0, len);
};
fos.close();
is.close();
}
public String getAddress(String number){
File file = new File(context.getFilesDir(),DBNAME);
String address = number;
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null,SQLiteDatabase.OPEN_READONLY);
if (db.isOpen()){ // 如果数据库是打开的,就可以对数据库进行操作,操作完后记得关闭数据库
// ^1[358]\d{9}$
if(Pattern.compile("^1[358]\\d{9}{1}quot;).matcher(number).matches()){
String phoneprefix7 = number.substring(0, 7);
Log.i(TAG,phoneprefix7);
Cursor cursor= db.rawQuery("select city from info where mobileprefix=?", new String[]{phoneprefix7});
if(cursor.moveToFirst()){
address = cursor.getString(0);
}
cursor.close();
}
else{
Cursor cursor= null;
/* 固定电话 本地号码7位 ,8位
长途号码 带区号 区号有3位和4位的
10位 3位区号+7位电话号码
11位 4位区号+7位电话 3位区号+8位电话
12位 4位区号+8位电话*/
switch (number.length()) {
case 7:
address = context.getApplicationContext().getResources().getString(R.string.local);
break;
case 8:
address = context.getApplicationContext().getResources().getString(R.string.local);
break;
case 10:
String numberprefix3 = number.substring(0, 3);
cursor= db.rawQuery("select city from info where area=?", new String[]{numberprefix3});
if(cursor.moveToFirst()){
address = cursor.getString(0);
}
cursor.close();
break;
case 11:
String numberprefix_3 = number.substring(0, 3);
String numberprefix_4 = number.substring(0, 4);
cursor= db.rawQuery("select city from info where area=? or area = ?", new String[]{numberprefix_3,numberprefix_4});
if(cursor.moveToFirst()){
address = cursor.getString(0);
}
cursor.close();
break;
case 12:
String numberprefix4 = number.substring(0, 4);
cursor= db.rawQuery("select city from info where area=?", new String[]{numberprefix4});
if(cursor.moveToFirst()){
address = cursor.getString(0);
}
cursor.close();
break;
case 4:
address = context.getApplicationContext().getResources().getString(R.string.emulator);
break;
}
}
db.close();
}
return address;
}
}
下载远程apk的类:
public class DownLoadService {
/**
*
* @param urlpath 要下载文件的地址,下载到sdcard
* @return
* @throws Exception
*/
public static File getFile(String urlpath) throws Exception{
Thread.sleep(5000);
URL url = new URL(urlpath);
File file = null;
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
InputStream ins = conn.getInputStream();
//把他写到文件里面
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
file = new File(Environment.getExternalStorageDirectory(),"update.apk");
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while((len=ins.read(buffer))!=-1){
fos.write(buffer, 0, len);
}
ins.close();
fos.close();
}
else{
throw new Exception("sd卡不可读写");
}
return file;
}
}