在貼出代碼之前,還是先普及一下手機號碼的知識吧。
1、國內手機號碼長度爲11位
目前,我國國內所用的手機號碼的長度一般爲11位,是世界上最長的手機號碼。11位數的號碼足夠容納上百億個號碼了,而目前中國人口也只不過十來億人,因而把首位的“1”給固定下來了,第二位數字換一個數字就又能增加10億個號碼的容量啦。
2、國內的手機號碼大多以13及13以後的號碼開頭
因爲10,11,12開頭的大多作爲特殊的號碼段。如:
10開頭,電信服務號碼,如103國際半自動掛號,108國際對方付費電話,1000電信服務中心,1001聯通服務中心等。
11開頭,賦予特種服務號碼,如110匪警,111電信內部測試,112報修,113、115國內人工長途掛號,114查號臺,116國內人工長
途查詢,117報時,119火警等.
12開頭,賦予民用特殊號碼,如120(醫院),121(天氣預報),122交通事故告警,126、127、128、129尋呼臺(BP機時代)。
當然還有一些其他的特殊號碼段有:如:16聲訊類,17長途電話服務等,在此就不一一列舉啦。
3、確定手機號碼的運營商和歸屬地
目前,我國使用的手機號碼爲11位,其中各段有不同的編碼方向:前3位表示網絡識別號;第4-7位表示地區編碼;第8-11位表示用戶號碼。
其中目前開放的號段中(每年都在更新,可能不全):
移動:134、135、136、137、138、139、150、151、152、157、158、159、182、183、184、187、188
聯通:130、131、132、155、156、185、186
電信:133、153、180、181、189
手機號碼中間四位(即第4-7位)表示歸屬地。這裏有兩個概念HLR和VLR。
HLR(Home Location Register)表示歸屬位置寄存器,它是一個包含手機訂戶的被授權的詳細信息的中央數據庫。保存的是用戶的基本信息,如你的SIM的卡號、手機號碼、簽約信息等,以及動態信息,如當前的位置、是否已經關機等;
VLR(Visiting Location Register)表示訪問位置寄存器。也表示一個數據庫,保存的是用戶的動態信息和狀態信息,以及從HLR下載的用戶的簽約信息。
手機號碼的中間四位即表示HLR代碼。其中前三位由運營商統一分配到各省,最後一位由各省分配到本地網。
因而,我們只需要根據前三位判斷出網絡運營商,根據中間四位判斷出歸屬地就可以確定號碼的來源了。
好了,要了解的基本瞭解了,不懂的,網上一搜一大把的。先來說說Demo的實現吧!
4、Demo功能
(1).Demo中查詢的數據庫是反編譯系統自身應用所帶的數據庫的(下了很大的決心才決定把手機給root了的)。
(2).實現的功能包括:a.根據號碼查詢手機號碼和城市區號;b.根據城市名查詢區號;c.根據國家或地區名查詢國家代號。
(3).界面採用的是ViewPager+Fragment的實現。
無圖無真相,先上個圖吧!
5、代碼
1、軟件主界面的實現,通過繼承FragmentActivity.java來實現。
代碼如下:
package com.eden.phonenum;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu;
public class NumFragmentActivity extends FragmentActivity {
private static final int DEFAULT_OFFSCREEN_PAGES = 1;
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_phonenum);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(DEFAULT_OFFSCREEN_PAGES);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText(R.string.number_to_location),
NumberFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.location_to_number),
CityFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.country_name),
CountryFragment.class, null);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tab, menu);
return true;
}
/**A adapter class,which extends FragmentPagerAdapter class and implements OnPageChangeListener
* and ActionBar.TabListener interface.*/
public static class TabsAdapter extends FragmentPagerAdapter implements
OnPageChangeListener, ActionBar.TabListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
/**static inner class,stored tab informations.*/
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
private Fragment fragment;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
/**Add tabs.*/
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
@Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
TabInfo info = mTabs.get(position);
if (info.fragment == null)
info.fragment = Fragment.instantiate(mContext,
info.clss.getName(), info.args);
return info.fragment;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mTabs.size();
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
}
2、用到的工具類AssetsDatabaseManager.java。用於將Android中的assets目錄中的數據庫壓縮文件拷貝到Android系統的數據庫文件存放處,即路徑“/data/data/應用包名/databases/數據庫名.db”處。此處參考於:http://blog.csdn.net/trbbadboy/article/details/8001157package com.eden.phonenum.utils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
/**
* <p>This is a Assets Database Manager, you can use a assets database file
* in you application. It will copy the database file to <em>
* "/data/data/[your application package name]/database"</em> when you first time you
* use it Then you can get a SQLiteDatabase object by the assets database file.</p>
* How to use:
* <ul>
* <li>Initialize AssetsDatabaseManager.
* <li>Get AssetsDatabaseManager.
* <li>Get a SQLiteDatabase object through database file.
* <li>Use this database object.
* </ul>
* Using example:<code>
* <li>AssetsDatabaseManager.initManager(getApplication());
* <li>AssetsDatabaseManager mg =AssetsDatabaseManager.getAssetsDatabaseManager();
* <li> SQLiteDatabase db1 = mg.getDatabase("db1.db"); </code>
*/
public class AssetsDatabaseManager {
private static final String TAG = "AssetsDatabaseManager";
private static String DB_PATH = "/data/data/%s/databases";// %s is packageName.
private Map<String, SQLiteDatabase> databases = new HashMap<String, SQLiteDatabase>();
private Context mContext = null;
private static AssetsDatabaseManager mInstance = null;//singleton pattern.
private AssetsDatabaseManager(Context context) {
this.mContext = context;
}
/** Initialize AssetDatabaseManager. */
public static void initManager(Context context) {
if (null == mInstance)
mInstance = new AssetsDatabaseManager(context);
}
/** Get a AssetsDatabaseManager object. */
public static AssetsDatabaseManager getAssetsDatabaseManager() {
return mInstance;
}
/**
* Get a assets database, if this database is opened,this method is only
* return a copy of the opened database.
*
* @param dbName
* , the assets file which will be opened for a database.
* @return, if success it return a SQLiteDatabase object else return null.
*/
public SQLiteDatabase getDatabase(String dbName) {
dbName = getPrefix(dbName) + ".db";//number_location.db
if (databases.get(dbName) != null) {
Log.i(TAG, String.format("Return a database copy of %s.", dbName));
return databases.get(dbName);
}
if (null == mContext)
return null;
Log.i(TAG, String.format("Create database %s.", dbName));
String dbPath = getDatabaseFilePath();
String dbFile = getDatabaseFile(dbName);
File file = new File(dbFile);// "/data/data/packageName/databases/dbName"
SharedPreferences dbsp = mContext.getSharedPreferences(
AssetsDatabaseManager.class.toString(), Context.MODE_PRIVATE);
// Get Database file flag,if true means this database file was copied and valid.
boolean flag = dbsp.getBoolean(dbName, false);
if (!flag || !file.exists()) {// if flag is false or file is not exist.
file = new File(dbPath);
if (!file.exists() && !file.mkdirs()) {
Log.i(TAG, "Create \"" + dbPath + "\" failed!");
return null;
}
if (!copyAssetsToFilesystem(dbName, dbFile)) {
Log.i(TAG, String.format("Copy %s to %s failed!", dbName, dbFile));
return null;
}
dbsp.edit().putBoolean(dbName, true).commit();
}
SQLiteDatabase db = SQLiteDatabase.openDatabase(dbFile, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
if (null != db)
databases.put(dbName, db);
return db;
}
/**get file's prefix in front of the point.*/
private String getPrefix(String str){
return str.substring(0,str.lastIndexOf("."));
}
private String getDatabaseFilePath() {
return String.format(DB_PATH,
mContext.getApplicationInfo().packageName);
}
private String getDatabaseFile(String dbName) {
return getDatabaseFilePath() + "/" + dbName;
}
/** Copy the database file to file system. */
private boolean copyAssetsToFilesystem(String dbSrc, String dbDes) {
Log.i(TAG, "Copy " + dbSrc + " to " + dbDes);
InputStream inStream = null;
ZipInputStream zin = null;
OutputStream outStream = null;
AssetManager am = mContext.getAssets();
try {
inStream = am.open(getPrefix(dbSrc) + ".zip");
zin = new ZipInputStream(new BufferedInputStream(inStream));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze=zin.getNextEntry()) != null){
Log.i(TAG, "Unzipping " + ze.getName());
outStream = new FileOutputStream(dbDes);
while ((count = zin.read(buffer)) != -1){
outStream.write(buffer, 0, count);
}
outStream.close();
zin.closeEntry();
}
zin.close();
} catch (IOException e) {
e.printStackTrace();
try {
if (zin != null)
zin.close();
if (outStream != null)
outStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return false;
}
return true;
}
/** close assets database. */
public boolean closeDatabase(String dbfile) {
if (databases.get(dbfile) != null) {
SQLiteDatabase db = databases.get(dbfile);
db.close();
databases.remove(dbfile);
return true;
}
return false;
}
/** Close all assets databases. */
public static void closeAllDatabase() {
Log.i(TAG, "closeAllDatabases.");
if (mInstance != null) {
for (int i = 0; i < mInstance.databases.size(); i++) {
if (mInstance.databases.get(i) != null)
mInstance.databases.get(i).close();
}
mInstance.databases.clear();
}
}
}
3、主要代碼就這些啦,其餘的就是在Fragment中對數據庫的查詢啦,代碼就不貼了,這裏我直接把源碼附上。