自动读取短信中心号码

前言

短信中心号码概念

短信中心号码类似信息服务器,如果信息中心号码不正确,短消息是无法发送成功的,各个地区都有自己的信息中心号码,其中移动以+86138开头,关于该号码的获取这举例说明。

获取方法

1、调用Phone中的getSmscAddress(Message message)方法,其中参数的message为获取到结果后发送消息给mHandler,并查询结果AsyncResult的result属性中。
    		 phone=PhoneFactory.getDefaultPhone();
    		 phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));

:2、mHandler实现代码

private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            AsyncResult ar;
            switch (msg.what) {
                case EVENT_QUERY_SMSC_DONE:
                    ar= (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                    } else {
		// TODO: handle exception
		mSmsServiceCenterPref.setSummary((String)ar.result);
		          }
                    }

                default:
                    break;
            }
        }
    };

原理分析

分析到这大家可能觉得短信中心号码的获取非常简单,但如果要实现该功能仅加上这几行代码,大家可以动手试试,会发现该功能不仅没有实现,甚至还抛出了一个“PhoneFactory.getDefaultPhone must be called from Looper thread”这样的异常。
:1、原因造成该异常的根本原因在通过PhoneFactory类的getDefaultPhone()方法返回一个Phone对象,我们可以进入这个类去看这个函数的实现

   public static Phone getDefaultPhone() {
      if (sLooper != Looper.myLooper()) {
           throw new RuntimeException(
               "PhoneFactory.getDefaultPhone must be called from Looper thread");
       }
       if (!sMadeDefaults) {
           throw new IllegalStateException("Default phones haven‘t been made yet!");
       }
      return sProxyPhone[getDefaultSubscription()];
   }

该异常由于Looper对象不一样,Looper.myLooper()该对象是指调用getDefaultPhone方法的所在的进程的looper对象,sLooper对象又指的是谁的looper对象,在那赋值?在调用getDefaultPhone时会返回sProxyPhone[getDefaultSubscription()],该数组又是在那赋值的了?

首先,手机启动时会启动phone进程,phone会调用到PhoneApp.java的onCreate方法,在该方法中会调用PhoneFactory.makeDefaultPhones方法。然后,在makeDefaultPhones函数中,会做两件事情,一是初始化sLooper,二是给phone sProxyPhone[]数组赋值。以下是该方法的核心实现:

 if (!sMadeDefaults) {
                sLooper = Looper.myLooper();
                sContext = context;

                if (sLooper == null) {
                    throw new RuntimeException(
                        "PhoneFactory.makeDefaultPhone must be called from Looper thread");
                }
       sProxyPhone = new PhoneProxy[numPhones];
       for (int i = 0; i < numPhones; i++) {
                    int phoneType = getPhoneType(networkMode[i]);
                    Log.i(LOG_TAG, "get Phone Type:"+ phoneType);

                    if (phoneType == Phone.PHONE_TYPE_GSM) {
                        sProxyPhone[i] = new PhoneProxy(new GSMPhone(context,
                                sCommandsInterface[i], sPhoneNotifier, false, dct, i));
                        Log.i(LOG_TAG, "Creating GSMPhone");
                    } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
                        sProxyPhone[i] = new PhoneProxy(new CDMAPhone(context,
                                sCommandsInterface[i], sPhoneNotifier, false, dct, i));

                        Log.i(LOG_TAG, "Creating CDMAPhone");
                    }
                }

最后,通过前面可以看出sLooper对象是属于phone进程,而Looper.myLooper()是属于调用getDefaultPhone函数的进程,如果调用getDefaultPhone函数的进程和phone进程没有在一个进程空间中执行,则他们的looper对象肯定是不相同的,那么肯定就会抛出“PhoneFactory.getDefaultPhone must be called from Looper thread”这个异常。

:2、解决方法首先在需要在调用getDefaultPhone函数获取phone对象的进程manifest中声明一下代码

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.mms"
        android:sharedUserId="android.uid.phone">

并将具体的Activity声明以下属性:

android:process="com.android.phone"
小结

短信中心号码的读取,这里只讲述了应用层最最基本的实现以及一些注意事项,其最最核心的实现还是落实到了中间层和Ril层.参考类Ril.java、PhoneBase.java。

时间: 2024-11-02 23:38:14

自动读取短信中心号码的相关文章

Android自动读取短信验证码

Android自动读取短信验证码 extends:http://www.cnblogs.com/jiayaguang/p/4366384.html 实现自动获取手机的短信验证码,原理通过监听短信数据库的变化来解析短信,获取验证码. 直接附上代码: 1.建立一个监听数据库的类 import java.util.regex.Matcher; import java.util.regex.Pattern; import android.app.Activity; import android.data

深度分析:Android中Mms设置页面更改短信中心号码流程

相关控件初始化方法:showSmscPref private void showSmscPref() { int count = MSimTelephonyManager.getDefault().getPhoneCount(); boolean airplaneModeOn = Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; for (int i = 0; i < c

解决:更改短信中心号码不能及时更新显示

[测试步骤]: 1.进入短信界面 2.菜单-设置 3.修改短信中心号码(Set the SIM's smsc number) 保存 [测试结果]:提示保存成功,但是号码没有改变,退出重新进入设置才会看到号码更新 [预期结果]:提示保存成功,号码变为修改过的号码 相关Activity:通过Logcat中I/ActivityManager(  896):我们可以定位到该类-MessagingPreferenceActivity: 相关控件:mSmscPrefList.add(pref); 根据分析我

全国移动短信信息中心号码查询大全

广东省移动短信中心号码 深圳+8613800755500 珠海 +8613800756500 江门 +8613800750500 阳江 +8613800662500 惠州 +8613800752500 河源 +8613800762500 中山 +8613800760500 湛江 +8613800759500 茂名 +8613800668500 广州 +8613800200500 韶关 +8613800751500 清远 +8613800763500 汕头 +8613800754500 潮州 +8

自动填充短信验证码(使用ContentObserver)

为了减少用户的操作步骤,在获得短信验证码的时候,我们可以监听特殊手机号码的短信,截取信息当中的短信验证码(其实有很多应用都监听短信例如360短信,一些信用卡或者是记账类的应用). 原理:可以使用一个自定义的BroadcastReceiver来监听短信,在监听结果当中过滤手机号,在需要回填的activity当中实现实例化广播并且实现其回调接口,在接口当中进行回填验证码,在销毁activity时销毁链接.但是这样操作会出现一些问题,由于一些其他的应用也会使用广播监听手机例如QQ通讯录或者是360通讯

自动获取短信验证码

1.自定义监听类 /** * 短信监听器,用于自动填充验证码 */ public class SMSContentObserver extends ContentObserver { public final String SMS_URI_INBOX = "content://sms/inbox";//收信箱 private Activity activity = null; private String smsContent = "";//验证码 private 

读取短信并复制验证码小工具

获取短信有两种方式,第一种是通过广播接收器,第二种通过读取短信数据库. 第一种: 静态注册了一个广播,通过接收包含android.provider.Telephony.SMS_RECEIVED动作的广播,获取新收到的短信内容. <receiver android:name=".GetSMS" android:enabled="true" android:exported="true"> <intent-filter androi

android自动填写短信验证码

广播类 package com.examp.azuoyoutong.listner; import java.util.regex.Matcher;import java.util.regex.Pattern; import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.telephony.SmsMessage;import

Android中读取短信信息

Android中读取的短信文件有 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /**  * 所有的短信  */ public static final String SMS_URI_ALL = "content://sms/"; /**  * 收件箱短信  */ public static final String SMS_URI_INBOX = "content://sms/inbox"; /**  * 发件箱短信  */ p