在开发Android项目 的时候,有个查询手机和座机归属地的需求,然而Android本身并没有发现提供查询归属地的数据库,所以就需要我们自己来想办法查询来满足项目的需求。
我最初的想法,就是把这些归属地数据存到一个普通的文件,文件内容可以用JSON格式的数据格式,然后每次启动App的时候把文件的JSON内容转换成Java的对象,Google提供了一款工具,可以直接把JSON的字符串转换成我们定义好的Class类,比Java提供的JsonObject好很多,然而我考虑到数据库的大小和查询效率,还是决定使用数据库查询。
Goole的转换JSON的工具是Gson,下载链接:http://download.csdn.net/detail/qxs965266509/8367275
使用方法:http://blog.csdn.net/qxs965266509/article/details/42774691
首先,需要下载归属地的数据库:http://download.csdn.net/detail/qxs965266509/8367219
把数据库DB文件存放到assets或者raw文件中
在启动启动后,需要把DB文件拷贝到Sd卡的中自己定义的目录中,当然你可能会疑问,为什么别人的都是拷贝到data文件下的项目文件中的DataBases文件中,而我却没有这么做?原因是:查看该目录需要root权限,当然这不是主要原因,而是在我测试的时候我把整个DB文件复制到data文件下的项目文件中时,并没有把整个DB文件复制过去,而是一部分,我觉得应该是文件太大的原因,所以考虑复制到SD卡中。
复制代码如下:
public static final String DB_NAME = "callHomeDB.db"; private int BUFFER_SIZE = 1024; private String getDirPath() { String path = fileHandler.sdcardFolder.getAbsolutePath(); return path; } private void copyContactLocation() { try { String path = getDirPath() + "/" + DB_NAME; File file = new File(path); if (!file.exists()) { InputStream is = MainActivity.instance.getResources() .getAssets().open(DB_NAME); FileOutputStream fos = new FileOutputStream(path); byte[] buffer = new byte[BUFFER_SIZE]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.close(); is.close(); } } catch (FileNotFoundException e) { log.e("File not found"); e.printStackTrace(); } catch (IOException e) { log.e("IO exception"); e.printStackTrace(); } }
下面说一下查询:
有一种方法可以直接把DB文件转换成一个Database数据库对象
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(path, null);
然而,可以直接操作SQLiteDatabase的实例来查询数据库,如果你的查询次数非常少的情况,可以使用这种,看不出查询效率,查询次数大的话建议不要用这种方式,查询效率太低,严重影响真个项目框架的执行效率,很多东西都会变得不灵敏。
为了提高查询效率,我使用的android提供的查询数据库的SQLiteOpenHelper类,查询效率大大提高,相信android是做了很多优化的。
首先需要重写DataBase的上下文,代码如下:
package com.open.lxxms.handler; import java.io.File; import com.open.lib.MyLog; import android.content.Context; import android.content.ContextWrapper; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; /** * CustomDatabaseContext 2015-1-10 下午7:51:05 * * @author 乔晓松 [email protected] */ public class CustomDatabaseContext extends ContextWrapper { public String tag = "CustomDatabaseContext"; public MyLog log = new MyLog(tag, true); private String mDirPath; public CustomDatabaseContext(Context base, String dirPath) { super(base); this.mDirPath = dirPath; log.e("CustomPathDatabaseContext"); } @Override public File getDatabasePath(String name) { File result = new File(mDirPath + File.separator + name); if (!result.getParentFile().exists()) { result.getParentFile().mkdirs(); } return result; } @Override public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { log.e("openOrCreateDatabase1"); return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory); } @Override public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) { log.e("openOrCreateDatabase2"); return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name) .getAbsolutePath(), factory, errorHandler); } }
下面是我封装的DB的工具类:
package com.open.lxxms.handler; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.os.Environment; import com.open.lib.MyLog; import com.open.lxxms.MainActivity; /** * DBOptions 2015-1-10 下午8:57:47 * * @author 乔晓松 [email protected] */ public class DBHandler extends SQLiteOpenHelper { public String tag = "DBOptions"; public MyLog log = new MyLog(tag, true); public static final String DB_NAME = "callHomeDB.db"; private int BUFFER_SIZE = 1024; public static final String PACKAGE_NAME = "com.open.lxxms"; public static final String DB_PATH = "/data" + Environment.getDataDirectory().getAbsolutePath() + "/" + PACKAGE_NAME; public static DBHandler getInstance(Context context) { DBHandler dbOptions = new DBHandler(context, null, null, 1); return dbOptions; } public DBHandler(Context context, String name, CursorFactory factory, int version) { // super(context, name, factory, version); super(new CustomDatabaseContext(context, getDirPath()), DB_NAME, factory, version); try { String path = getDirPath() + "/" + DB_NAME; File file = new File(path); if (!file.exists()) { InputStream is = MainActivity.instance.getResources() .getAssets().open("callHomeDB.db"); FileOutputStream fos = new FileOutputStream(path); byte[] buffer = new byte[BUFFER_SIZE]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.close(); is.close(); } } catch (FileNotFoundException e) { log.e("File not found"); e.printStackTrace(); } catch (IOException e) { log.e("IO exception"); e.printStackTrace(); } log.e("DBOptions"); } public static FileHandler fileHandler = FileHandler.getInstance(); private static String getDirPath() { String path = fileHandler.sdcardFolder.getAbsolutePath(); return path; } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub log.e("onCreate"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub log.e("onUpgrade"); } public String getResult(SQLiteDatabase database, String number) { // log.e(number); String result = "未知号码"; number = number.replaceAll(" ", ""); // try { if (number.length() > 7) { String firstNum = number.substring(0, 1); if (number.length() >= 10) { if ("0".equals(firstNum)) { String s1 = number.substring(1); String s2 = s1; String second = s1.substring(0, 1); if (second.equals("1") || second.equals("2")) { s2 = s1.substring(0, 2); } else { s2 = s1.substring(0, 3); } String sql = "select location from tel_location where _id = ? "; String[] param = new String[] { s2 }; if (database != null && database.isOpen()) { Cursor cursor = database.rawQuery(sql, param); if (cursor.moveToNext()) { result = cursor.getString(0); } cursor.close(); } } else { if (number.indexOf("+86") == 0) { number = number.substring(3); } if (number.indexOf("86") == 0) { number = number.substring(2); } String s1 = number.substring(0, 7); String sql = "select location from mob_location where _id = ? "; String[] param = new String[] { s1 }; if (database != null && database.isOpen()) { Cursor cursor = database.rawQuery(sql, param); if (cursor.moveToNext()) { result = cursor.getString(0); } cursor.close(); } } } else { result = "本地号码"; } } else { if (number.length() < 4) { result = "未知号码"; } else { result = "本地号码"; } } // } catch (Exception e) { // e.printStackTrace(); // } return result; } }
使用方法:
DBHandler dbOptions = DBHandler.getInstance(context); SQLiteDatabase database = dbOptions.getReadableDatabase();
String result = dbOptions.getResult(database, number);
归属地的数据库:http://download.csdn.net/detail/qxs965266509/8367219
如有转载,请著名出自http://blog.csdn.net/qxs965266509