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中對數據庫的查詢啦,代碼就不貼了,這裏我直接把源碼附上。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章