获取短信中心号大致有三种方式,第一种方法 通过向移动运营商(比如10086)发送一条免费短信然后等待对方回复,从对方回复的短信中获取短信中心号;实现方式参见 ,该种方式的优点就是肯定能得到正确的短信中心号(电信的卡除外), 但也有一些缺点 1: 对方回复短信需要等待一段时间,具体等待多长时间无法确定。2: 有的手机不一定能成功拦截下行短信因此带来的用户体验不是很好。
第二种方法和第一种比较相似,直接从用户的收件箱中读取一条短信然后从该信息中获取短信中心号,这种方式的好处就是不用发送短信;缺点是获取的短信中心号不一定正确,比如用户以前一直用的移动的卡收件箱中短信存的都是移动的短信中心号,之后如果换成联通的卡后获取的短信中心还是移动的。
第三种就是直接获取用户手机中的短信中心号,该种方式需要你的应用满足两个条件,1:你的应用需要有系统签名. 2:你的应用需要和phone进程在同一个进程组。具体实现方式如下:
配置AndroidManifest.xml 文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" " package="com.hello" android:sharedUserId="android.uid.phone" android:versionCode="1" android:versionName="100">
<application android:icon="@drawable/icon" android:process="com.android.phone" android:label="@string/app_name"> <activity android:name=".HelloWordActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
</application>
</manifest>
具体实现代码如下:
public class HelloWordActivity extends Activity implements Callback {
private Handler mSmscHandle = null;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
try { mSmscHandle = new Handler(this); getSmsc();
}
catch(Exception e)
{}
}
/** * 本方法需要使用到两个隐藏类 * com.android.internal.telephony.PhoneFactory * com.android.internal.telephony.Phone */ @SuppressWarnings("unchecked") public void getSmsc() { try { //调用PhoneFactory.getDefaultPhone() Class PhoneFactory = Class.forName("com.android.internal.telephony.PhoneFactory"); Method getDefaultPhone = PhoneFactory.getMethod("getDefaultPhone", (Class[]) null); Object phone = (Object)getDefaultPhone.invoke(null, (Object[]) null); Log.i("HELLOWORLD", "phone:" + phone); //调用Phone.getSmscAddress(Message result) Class[] ParamType = new Class[1]; ParamType[0] = Message.class; Message msg = mSmscHandle.obtainMessage(10001); Object[] paramValue = new Object[1]; paramValue[0] = msg; Class Phone = Class.forName("com.android.internal.telephony.Phone"); Method getSmscAddress = Phone.getDeclaredMethod("getSmscAddress", ParamType); getSmscAddress.invoke(phone, paramValue); } catch( Exception e ) { showTrace(e); } }
public boolean handleMessage(Message msg) { // TODO Auto-generated method stub /** * 收到短信中心号 * sg.obj 为AsyncResult的实例对象 */ Log.i("HELLOWORLD", "handleMessage() msg.what:" + msg.what + " data:" + msg.peekData() + " result:" + msg.obj.toString()); if(10001 == msg.what) { dealSmscResult(msg.obj); } return false; }
private void dealSmscResult(Object asyncResult) { try { Field exception = asyncResult.getClass().getDeclaredField("exception"); Throwable throwable = (Throwable)exception.get(asyncResult); Field result = asyncResult.getClass().getDeclaredField("result"); Object myResult = result.get(asyncResult); if(null != myResult) { Log.i("HELLOWORLD", "dealSmscResult() result:" + myResult.toString()); String szResult = (String)myResult; String szAddr = szResult.split(",")[0]; Log.i("HELLOWORLD", "dealSmscResult() smsc:" + szAddr); } if(null != throwable) { Log.i("HELLOWORLD", "dealSmscResult() throwable:" + throwable.getMessage()); } } catch(Exception e) { showTrace(e); } }
}
代码比较简单,就是调用两个两个隐藏的com.android.internal.telephony.PhoneFactory,
om.android.internal.telephony.Phone 就能获取本机的短信中心号码。
之后还需要使用android源码包中 platform.pk8 platform.x509.pem 两个文件(build\target\product\security 目录下)对生成的apk签名;否则无法安装在手机上。签名的命令为
java -jar signapk.jar platform.x509.pem platform.pk8 HelloWord.apk HelloWordSign.apk
大功告成,现在你的手机运行HelloWordSign.apk看看log中有没有短信中心号。在本人的i9000上测试成功。