在贴出代码之前,还是先普及一下手机号码的知识吧。
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/8001157
package 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中对数据库的查询啦,代码就不贴了,这里我直接把源码附上。