您的位置:首页 > 移动开发 > Android开发

Android项目实战--手机卫士13--手机号码归属地的逻辑和数据库的压缩

2013-09-17 08:38 495 查看
由于找工作的原因,所以有好几天没有更新了,今天就更新一下,继续我们之前的手机号码归属地那一块

获得手机号码归属地,我们有两种方式,一种就是通过WebService来获取嘛,但是这个是依赖于网络的,如果没有网络,那就没有办法用啦

另一种方法就是通过内置一个数据库,然后在用的时候查询就可以啦,但是这个数据库会很大,有16M所以这样就会造成我们的app体积过大的啦

所以我们就要对它进行压缩一下,怎样压缩呢,其实就是把里面一些重复的字段提取出来,然后达到压缩的作用,这个数据库经过我们的压缩,可以缩小到3M

这两个数据库,我会放到应用程序里面一起打包,想要下载的,到时可以下载来看看

未压缩前的数据库



我们可以看到,里面存放了很多中文字符,这就是这个数据库为什么那么大的原因啦,我们完全可以把这些中文放到另一个表,然后就存放一个id就行啦,这样就可以大大的缩小数据库的大小的啦

压缩后的数据库



压缩后的数据库就是上面一样的啦,体积只有3M,大大的缩小了体积。

如果我们想让这个数据库随着apk装到用户里面去,那么就要把这个文件放到res/raw这个目录下面,因为这个目录下面的资源都不会编译成二进制的格式的,所以然后就可以把整个数据库读取到sd卡上啦

但我们这个程序为了演示,我们就使用16M的那个大数据库啦,而且是通过网络把我们要用的数据库下载下来

好啦,废话不多说,直接上代码

com.xiaobin.security.ui.AToolActivity

package com.xiaobin.security.ui;

import java.io.File;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

import com.xiaobin.security.R;
import com.xiaobin.security.engine.DownloadTask;

public class AToolActivity extends Activity implements OnClickListener
{
	private static final int ERROR = 0;
	private static final int SUCCESS = 1;
	
	private TextView tv_atool_query;
	private ProgressDialog pd;
	
	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler()
	{
		public void handleMessage(Message msg) 
		{
			switch(msg.what)
			{
				case ERROR : 
					Toast.makeText(AToolActivity.this, "下载数据库失败,请检查网络!", Toast.LENGTH_SHORT).show();
					break;
					
				case SUCCESS : 
					Toast.makeText(AToolActivity.this, "数据库下载成功!", Toast.LENGTH_SHORT).show();
					break;
					
				default : 
					break;
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.atool);
		
		tv_atool_query = (TextView) findViewById(R.id.tv_atool_query);
		tv_atool_query.setOnClickListener(this);
	}

	@Override
	public void onClick(View v)
	{
		switch(v.getId())
		{
			case R.id.tv_atool_query : 
				if(isDBExist())
				{
					Intent intent = new Intent(this, QueryNumberActivity.class);
					startActivity(intent);
				}
				else
				{
					//提示用户下载数据库
					pd = new ProgressDialog(this);
					pd.setMessage("正在下载数据库...");
					pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
					pd.setCancelable(false);
					pd.show();
					new Thread()
					{
						public void run() 
						{
							String path = getResources().getString(R.string.serverdb);
							File dir = new File(Environment.getExternalStorageDirectory(), "/security/db");
							if(!dir.exists())
							{
								dir.mkdirs();
							}
							String dbPath = Environment.getExternalStorageDirectory() + "/security/db/data.db";
							try
							{
								//这个类,我们在做更新apk的时候已经写好的啦,现在直接拿过来用就可以啦
								DownloadTask.getFile(path, dbPath, pd);
								pd.dismiss();
							}
							catch (Exception e)
							{
								e.printStackTrace();
								pd.dismiss();
								Message message = new Message();
								message.what = ERROR;
								handler.sendMessage(message);
							}
						};
					}.start();
				}
				break;
				
			default : 
				break;
		}
	}
	
	private boolean isDBExist()
	{
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
		{
			File file = new File(Environment.getExternalStorageDirectory() + "/security/db/data.db");
			if(file.exists())
			{
				return true;
			}
		}
		return false;
	}

}


我们会先把数据库下载下来,然后再进行操作

所以我们会有一个dao

com.xiaobin.security.dao.AddressDao

package com.xiaobin.security.dao;

import android.database.sqlite.SQLiteDatabase;

public class AddressDao
{
	
	public static SQLiteDatabase getAddressDB(String path)
	{
		//打开那个存放电话号码的数据库
		return SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
	}

}


然后呢,有一个类来判断是那一个地方的号码

com.xiaobin.security.engine.NumberAddressService

package com.xiaobin.security.engine;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;

import com.xiaobin.security.dao.AddressDao;

public class NumberAddressService
{
	
	public static String getAddress(String number)
	{
		String pattern = "^1[3458]\\d{9}$";
		String address = number;
		if(number.matches(pattern))//手机号码
		{
			address = query("select city from info where mobileprefix = ? ", new String[] {number.substring(0, 7)});
			if(address.equals(""))
			{
				address = number;
			}
		}
		else	//固定电话
		{
			int len = number.length();
			switch(len)
			{
				case 4 : //模拟器
					address = "模拟器";
					break;
					
				case 7 : //本地号码
					address = "本地号码";
					break;
					
				case 8 : //本地号码
					address = "本地号码";
					break;
					
				case 10 : //3位区号,7位号码
					address = query("select city from info where area = ? limit 1", new String[] {number.substring(0, 3)});
					if(address.equals(""))
					{
						address = number;
					}
					break;
					
				case 11 : //3位区号,8位号码  或4位区号,7位号码
					address = query("select city from info where area = ? limit 1", new String[] {number.substring(0, 3)});
					if(address.equals(""))
					{
						address = query("select city from info where area = ? limit 1", new String[] {number.substring(0, 4)});
						if(address.equals(""))
						{
							address = number;
						}
					}
					break;
					
				case 12 : //4位区号,8位号码
					address = query("select city from info where area = ? limit 1", new String[] {number.substring(0, 4)});
					if(address.equals(""))
					{
						address = number;
					}
					break;
					
				default : 
					break;
			}
		}
		return address;
	}
	
	private static String query(String sql, String[] selectionArgs)
	{
		String result = "";
		String path = Environment.getExternalStorageDirectory() + "/security/db/data.db";
		SQLiteDatabase db = AddressDao.getAddressDB(path);
		if(db.isOpen())
		{
			Cursor cursor = db.rawQuery(sql, selectionArgs);
			if(cursor.moveToNext())
			{
				result = cursor.getString(0);
			}
			cursor.close();
			db.close();
		}
		return result;
	}

}


然后呢,我们就要去到之前完成的界面里面,补上一些逻辑啦

com.xiaobin.security.ui.QueryNumberActivity

package com.xiaobin.security.ui;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.TextView;

import com.xiaobin.security.R;
import com.xiaobin.security.engine.NumberAddressService;

public class QueryNumberActivity extends Activity
{
	private TextView tv_result;
	private EditText et_query_number;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.query_number);
		
		tv_result = (TextView) findViewById(R.id.tv_query_result);
		et_query_number = (EditText) findViewById(R.id.et_query_number);
	}
	
	public void query(View v)
	{
		String number = et_query_number.getText().toString().trim();
		//如果查询内容为空,那么就抖动输入框
		if(TextUtils.isEmpty(number))
		{
			Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
			et_query_number.startAnimation(shake);
		}
		else
		{
			String address = NumberAddressService.getAddress(number);
			tv_result.setText("归属地信息:" + address);
		}
	}

}


好啦,到现在为止,那个查询号码归属地的,我们就已经做好的啦,我们下一次将会把归属地在有电话打进来的时候显示出来!

先给个图给大家看一下先



就是这个样子的啦,当然我们还会进行很多细节处理,如用户自己定义那个归属地的显示位置啦,还有自己定义显示的风格啦,好啦,下次我们要说的主要就是这个啦!

今天源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: