由于找工作的原因,所以有好几天没有更新了,今天就更新一下,继续我们之前的手机号码归属地那一块
获得手机号码归属地,我们有两种方式,一种就是通过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); } } }
先给个图给大家看一下先
就是这个样子的啦,当然我们还会进行很多细节处理,如用户自己定义那个归属地的显示位置啦,还有自己定义显示的风格啦,好啦,下次我们要说的主要就是这个啦!
今天源码下载