Android手机号码归属地查询

在贴出代码之前,还是先普及一下手机号码的知识吧。

1、国内手机号码长度为11位

目前,我国国内所用的手机号码的长度一般为11位,是世界上最长的手机号码。11位数的号码足够容纳上百亿个号码了,而目前中国人口也只不过十来亿人,因而把首位的“1”给固定下来了,第二位数字换一个数字就又能增加10亿个号码的容量啦。

2、国内的手机号码大多以13及13以后的号码开头

因为10,11,12开头的大多作为特殊的号码段。如:

10开头,电信服务号码,如103国际半自动挂号,108国际对方付费电话,1000电信服务中心,1001联通服务中心等。

11开头,赋予特种服务号码,如110匪警,111电信内部测试,112报修,113115国内人工长途挂号,114查号台,116国内人工长

查询,117报时,119火警等.

12开头,赋予民用特殊号码,如120(医院),121(天气预报),122交通事故告警,126127128129寻呼台(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中对数据库的查询啦,代码就不贴了,这里我直接把源码附上。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章