电子设备都有唯一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号后,切换下 飞行模式, 让手机
重新注册下网络。