电子设备都有唯一ID号,跟人的身份证号类似。Android 手机GSM WCDMA是号叫IMEI,

CDMA手机叫MEID。* id is called "IMEI" on GSM phones and "MEID" on CDMA phones.

       大部分Android工程师知道IMSI号是由生成工具写的,但并不清楚具体是怎么写的,这个

一般modem工程师比较熟悉。IMEI号一般都是NV 项,实际上是modem侧的一些文件,可以

理解为modem的文件系统,一般关注的有RF射频,音频校准参数数据等,由NV项保存。在

Android上只提供了Read IMEI接口,没有写接口。---实际上这是非常合理的,不能随意修改,

一般会在modem侧做修改限制。搞清楚实质就好办,写号一般是AT命令写,通过AT口通讯。在

android上代码表现为Ril通道;不管是高通,还是MTK,基本上modem都遵守标准的AT命令规范集。

所以这个也算得上通用的办法。下面开始具体的说明。

在MTK Android上,有一个直观的方法先操作验证一下,

1. 拨号界面输入*#*#3646633#*#*
2. 择connectivity下面的cds information
3. 选择Radio information phone 1 或者phone 2
4. AT+输入e会出来AT+EGMR=1,7,"123456789009876"              phone1选它
     AT+EGMR=1,10,"321645987085261"              phone2选它
  

参考代码:

      vendor/mediatek/proprietary/packages/apps/EngineerMode/src/com/

     mediatek/engineermode/EmUtils.java                 

     getmPhone(phoneid).invokeOemRilRequestStrings(command, response);

     EmUtils  封装了一个统一的接口,  EmUtils.invokeOemRilRequestStringsEm

  注意:

         ImeiString[0] = "AT+EGMR=1,7,\"" + imeiString + "\"";//single sim card Phone

         ImeiString[1] = "AT+EGMR"  /// 注意需要增加这个,否则有意外发生  ^_^

         phone = PhoneFactory.getDefaultPhone();//获取Phone对象

         phone.invokeOemRilRequestStrings(ImeiString,

         new WriteImeiHandler().obtainMessage(EVENT_WRITE_IMEI));//发送更新IMEI号AT command

部分参考code:

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;

public static Phone getmPhone(int phoneid) {
        switch (phoneid) {
            case -1:
                mPhoneMain = PhoneFactory.getPhone(ModemCategory.getCapabilitySim());
                mPhone = mPhoneMain;
                break;
            case PhoneConstants.SIM_ID_1:
                if (mPhoneSlot1 == null) {
                    mPhoneSlot1 = PhoneFactory.getPhone(PhoneConstants.SIM_ID_1);
                }
                mPhone = mPhoneSlot1;
                break;
            case PhoneConstants.SIM_ID_2:
                if (mPhoneSlot2 == null) {
                    mPhoneSlot2 = PhoneFactory.getPhone(PhoneConstants.SIM_ID_2);
                }
                mPhone = mPhoneSlot2;
                break;

  public static void invokeOemRilRequestStringsEm(int phoneid, String[] command, Message
            response) {
        try {
            getmPhone(phoneid).invokeOemRilRequestStrings(command, response);
        } catch (Exception e) {
            Elog.v(TAG, e.getMessage());
            Elog.v(TAG, "get phone invokeOemRilRequestStrings failed");
        }
    }

public void executeWriteMeidATCommand(String meid) {
        Log.d(this, "settingMeid=>meid: " + meid);
        Phone phone = getCDMAPhone();
        Log.d(this, "executeWriteMeidATCommand=>radioOn: " + phone.isRadioOn() +

           " available: " + phone.isRadioAvailable());


        String[] commands = new String[2];
        commands[0] = "AT+VMOBID=0, \"7268324842763108\", 2, \"" + meid.toUpperCase() + "\"";
        commands[1] = "+VMOBID";
        phone.invokeOemRilRequestStrings(commands, 

                mHandler != null ? mHandler.obtainMessage(MSG_SETTING_MEID_RESULT) : null);
    }

Android 上层查看*#06#需要同步;因为这个获取只会运行一次,然后保存在全局变量中。

所以在更新完后,同步发一下通知事件。

\frameworks\opt\telephony\src\java\com\android\internal\telephony\GsmCdmaPhone.java

mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); 

mCi.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));

 initOnce

另外如果这个功能需要实测的话,在修改IMEI号后,切换下 飞行模式, 让手机

重新注册下网络。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐