当前位置:首页 » 安卓系统 » android命令执行at

android命令执行at

发布时间: 2025-03-25 15:14:27

⑴ android 怎么通过蓝牙向一个硬件发送AT指令

将16进制的字符串转换成bytes,通过hexstring2bytes转换,从而发送指令。

⑵ Android平台到底能不能通过串口发送AT指令呢,急!!!

AT命令(Attention)在手机中,用于对modem(也就是移动模块)通过串口命令进行操作,处理与语音电话、短信和数据。

关于AT命令:

  1. Android系统与AT命令

    对于智能手机,AP和BP分离的情况,在AP上的系统通过串口和BP通信是个不错方式。在Android的源码中有一个内部包com.android.internal.telephony中有对AT命令的封装和解析,但这种internal的包开发者不能调用的SDK部分,可以用来封装ROM。这说明Android对AT command的方式是支持的。

  2. 对于Android如何调用AT command

    用root登录命令行,直接对串口进行操作,如echo -e "AT " > /dev/smd0

    具体的串口,不同设备会有不同,甚至不一定会提供。这种方式,开发者是可以调用的,通过Runtime.exec直接执行命令行命令,但要求是root,例如echo -e "ATD123456789; " > /dev/smd0,拨打123456789的号码。

  3. 目前最新的AT命令标准发布与2014.6.27,似乎还活得挺滋润的。但是给出的keywords是UMTS, GSM, command, terminal, LTE这说明CDMA确实很可能不是采用AT命令的方式。

⑶ 如何修改android模拟器上的IMEI,IMSI,SIM card serial number

手机使用IMEI和IMSI登录到GSM网络的,由GSM网络侧负责将IMSI和映射成手机号(MSISDN),以及执行相反方向的映射。

(一)、SIM card 号的修改:
SIM card号就是印制在SIM上的一串数字。
读SIM card号的AT命令为:AT+CRSM=176,12258,0,0,10
因此在andorid模拟其源码中找到该AT命令——在sim_card.c中:
const char*
asimcard_io( ASimCard sim, const char* cmd )
{
int nn;
#if ENABLE_DYNAMIC_RECORDS
int command, id, p1, p2, p3;
#endif
static const struct { const char* cmd; const char* answer; } answers[] =
{
{ "+CRSM=192,28436,0,0,15", "+CRSM: 144,0," },
{ "+CRSM=176,28436,0,0,20", "+CRSM: 144,0," },

{ "+CRSM=192,28433,0,0,15", "+CRSM: 144,0," },
{ "+CRSM=176,28433,0,0,1", "+CRSM: 144,0,55" },

{ "+CRSM=192,12258,0,0,15", "+CRSM: 144,0," },
{ "+CRSM=176,12258,0,0,10", "+CRSM: 144,0,98101430121181157002" },

...

...

因此用UE二进制方式打开emulator-arm.exe 或 emulator-x86.exe,并搜索字符串“98101430121181157002”,然后将其修改成需要的SIM card号。
比如:
00209a00h: 31 30 00 00 2B 43 52 53 4D 3A 20 31 34 34 2C 30 ; 10..+CRSM: 144,0
00209a10h: 2C 39 38 31 30 31 34 33 30 31 32 31 31 38 31 31 ; ,981014301211811
00209a20h: 35 37 30 30 32 00 2B 43 52 53 4D 3D 31 39 32 2C ; 57002.+CRSM=192,

(二)、IMEI、IMSI号的修改:

java代码中获取手机的IMEI号与ISMI号途径为:

TelephonyManager manager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String imei = manager.getDeviceId();
String imsi = manager.getSubscriberId();

在android的源码树中找到类TelephonyManager的实现:
成员函数getDeviceId:
/**
* Returns the unique device ID, for example, the IMEI for GSM and the MEID
* or ESN for CDMA phones. Return null if device ID is not available.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceId() {
try {
return getSubscriberInfo().getDeviceId();
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
return null;
}
}

成员函数getSubscriberId:
/**
* Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
* Return null if it is unavailable.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getSubscriberId() {
try {
return getSubscriberInfo().getSubscriberId();
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
// This could happen before phone restarts e to crashing
return null;
}
}

上面两个成员函数最终调用共同的一个私有成员函数getSubscriberInfo():
private IPhoneSubInfo getSubscriberInfo() {
// get it each time because that process crashes a lot
return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
}

而上面私有函数getSubscriberInfo获取的手机IMSI和IMEI号被硬编码在文件android_modem.c中:
/* the Android GSM stack checks that the operator's name has changed
* when roaming is on. If not, it will not update the Roaming status icon
*
* this means that we need to emulate two distinct operators:
* - the first one for the 'home' registration state, must also correspond
* to the emulated user's IMEI
*
* - the second one for the 'roaming' registration state, must have a
* different name and MCC/MNC
*/

#define OPERATOR_HOME_INDEX 0
#define OPERATOR_HOME_MCC 310
#define OPERATOR_HOME_MNC 260
#define OPERATOR_HOME_NAME "Android"
#define OPERATOR_HOME_MCCMNC STRINGIFY(OPERATOR_HOME_MCC) \
STRINGIFY(OPERATOR_HOME_MNC)

#define OPERATOR_ROAMING_INDEX 1
#define OPERATOR_ROAMING_MCC 310
#define OPERATOR_ROAMING_MNC 295
#define OPERATOR_ROAMING_NAME "TelKila"
#define OPERATOR_ROAMING_MCCMNC STRINGIFY(OPERATOR_ROAMING_MCC) \
STRINGIFY(OPERATOR_ROAMING_MNC)
/* a function used to deal with a non-trivial request */
typedef const char* (*ResponseHandler)(const char* cmd, AModem modem);

static const struct {
const char* cmd; /* command coming from libreference-ril.so, if first
character is '!', then the rest is a prefix only */

const char* answer; /* default answer, NULL if needs specific handling or
if OK is good enough */

ResponseHandler handler; /* specific handler, ignored if 'answer' is not NULL,
NULL if OK is good enough */
} sDefaultResponses[] =
{
/* see onRadioPowerOn() */
{ "%CPHS=1", NULL, NULL },
{ "%CTZV=1", NULL, NULL },

...

{ "!+VTS=", NULL, handleSetDialTone },
{ "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */
{ "+CGSN", "000000000000000", NULL }, /* request model version */
{ "+CUSD=2",NULL, NULL }, /* Cancel USSD */

...

/* end of list */
{NULL, NULL, NULL}

};

因此用UE二进制方式打开emulator-arm.exe 或 emulator-x86.exe,并搜索字符串"+CGSN"修改为需要的IMEI号;搜索"+CIMI"修改为需要的IMSI号。需要注意的是 IMSI 号的头六个数字"310260"不能修改,否则模拟器无法与网络连接。
例如:
001fc700h: 33 00 41 00 48 00 21 2B 56 54 53 3D 00 2B 43 49 ; 3.A.H.!+VTS=.+CI
001fc710h: 4D 49 00 33 31 30 32 36 30 30 30 30 30 30 30 30 ; MI.3102600000000
001fc720h: 30 30 00 2B 43 47 53 4E 00 30 30 30 30 30 30 30 ; 00.+CGSN.0000000
001fc730h: 30 30 30 30 30 30 30 30 00 2B 43 55 53 44 3D 32 ; 00000000.+CUSD=2

⑷ android添加蓝牙电量

1.      HFP 命令AT+IPHONEACCEV

描述:报告耳机的状态变更

发起者:耳机

格式:AT+IPHONEACCEV=[Number of key/value pairs ],[key1 ],[val1 ],[key2

],[val2 ],…

参数:

Number of key/value pairs :接下来参数的数量

key:被报告状态变化的类型

1 =电量等级

2 =暂停状态

val:更改的值

Battery events:0-9之间数字的字符串 A

string value between ‘0’ and ‘9’.

Dock state: 0 = undocked, 1 = docked.

           Example:AT+IPHONEACCEV=1,1,3

2.android  framework 修改点

packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetStateMachine.java

BluetoothAssignedNumbers.APPLE可以随便用哪个公司的,但注册广播时要一致就行。

   static {

         classInitNative();

 型乱磨        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID = new HashMap();

         VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put("+XEVENT",BluetoothAssignedNumbers.PLANTRONICS);

         VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put("+ANDROID",BluetoothAssignedNumbers.GOOGLE);  陪绝  +VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put("+XAPL",BluetoothAssignedNumbers.APPLE);

 +VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put("+IPHONEACCEV",BluetoothAssignedNumbers.APPLE);

     }

获取蓝牙电量需要向蓝牙发送回复的at命令:

private (String atString) {

       log("processVendorSpecificAt - atString = " + atString);

       // Currently we accept only SET type commands.

       int indexOfEqual = atString.indexOf("=");

       if (indexOfEqual == -1) {

           Log.e(TAG, "processVendorSpecificAt: command type error in " +atString);

           return false;

       }

       String command = atString.substring(0, indexOfEqual);

       Integer companyId = VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.get(command);

       if (companyId == null) {

           Log.e(TAG, "processVendorSpecificAt: unsupported command: " +atString);

        卜斗   return false;

       }

       String arg = atString.substring(indexOfEqual + 1);

       if (arg.startsWith("?")) {

           Log.e(TAG, "processVendorSpecificAt: command type error in " +atString);

           return false;

       }

       Object[] args = generateArgs(arg);

        + if ("+XAPL".equals(command)) {

        + processAtXapl(args);

        + }

        (command,

                                          companyId,

                                          BluetoothHeadset.AT_CMD_TYPE_SET,

                                          args,

                                          mCurrentDevice);

       atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0);

        return true;

}

/**

      * Process AT+XAPL AT command

      * @param args command arguments after theequal sign

      * @param device Remote device that hassent this command

      */

     private void processAtXapl(Object[] args){

         if (args.length != 2) {

            Log.w(TAG, "processAtXapl()args length must be 2: " + String.valueOf(args.length));

             return;

         }

         if (!(args[0] instanceof String) ||!(args[1] instanceof Integer)) {

             Log.w(TAG, "processAtXapl()argument types not match");

             return;

         }

         // feature = 2 indicates that wesupport battery level reporting only

                Log.d("tsq77","+XAPL=iPhone,");

        atResponseStringNative("+XAPL=iPhone," + String.valueOf(2));

     }

2.上层app监听广播获取电量

packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java

在settings中的蓝牙界面中注册广播,然后把电量显示出来。

       //aaron

       IntentFilter filter=new IntentFilter();

       filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);

       //filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY+"."+BluetoothAssignedNumbers.

APPLE);

       filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY+"."+BluetoothAssignedNumbers.

APPLE);

       getActivity().registerReceiver(mIntentReceiver,filter);

       Log.i("a", "registerReceiver  ");

       //end

   private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {

       @Override

       public void onReceive(Context context, Intent intent) {

           final String action = intent.getAction();

           if(action.equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) {

                Log.i("a","intent  "+intent);

                String command=intent.getStringExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD);

                if("+IPHONEACCEV".equals(command)) {

                    Object[] args = (Object[])intent.getSerializableExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS);

                    if (args.length >= 3&& args[0] instanceof Integer &&((Integer)args[0])*2+1<=args.length) {

                        for (inti=0;i<((Integer)args[0]);i++) {

                           if(!(args[i*2+1] instanceof Integer) || !(args[i*2+2] instanceof Integer)) {

                                continue;

                            }

                            if(args[i*2+1].equals(1)) {

                                floatlevel=(((Integer)args[i*2+2])+1)/10.0f;//获取的电量百分比

                                break;

                            }

                        }

                    }

                }

           }

       }

};

⑸ android 中什么是上下层交互接口,命令

Android的无线接口层(RIL)充当了Android电话服务与无线电硬件之间的抽象层,它与具体的通信方式无关,主要提供GSM网络支持。在Android电话系统的架构图中,RIL被置于一个实线框内,代表其属于Android系统的一部分,而合作伙伴专用的部分则由虚线框表示。

RIL由两个基本部分组成:RIL守护进程(RIL Daemon)和Vendor RIL。RIL守护进程负责初始化Vendor RIL,管理所有来自Android通讯服务的请求命令,将这些命令调度给Vendor RIL;而Vendor RIL则负责与无线电硬件进行通信,并通过未被请求的命令(即被动请求命令)将其分发给RIL守护进程。在Android启动时,RIL守护进程会读取rild.lib路径和rild.libargs系统参数,以确定应该使用的Vendor RIL库及向Vendor RIL提供的初始化参数。随后,RIL守护进程会加载Vendor RIL库,执行RIL_Init以初始化RIL并获取RIL函数所需参数,最后调用Android通讯栈中的RIL_register,为Vendor RIL函数提供参考。

RIL句柄提供了两种交互方式:主动请求命令和被动请求命令。主动请求命令来自RIL lib,包括DIAL和HANGUP等;被动请求命令则来自基带,如CALL_STATE_CHANGED 和 NEW_SMS。主动请求命令的代码片段包括OnRequest和OnRequestComplete函数,其中主动请求命令有超过60种,涵盖SIM PIN、电话状态、网络状态查询、网络设置、短信、PDP连接、电源和复位以及供应商定义及其支持等类别。

被动请求命令的代码片段为OnUnsolicitedResponse函数,它有超过10条被动请求命令,包括网络状态改变、新短信通知、新USSD通知以及信号强度和时间改变等。为了实现一个专用的通讯RIL,需要定义一系列函数以创建一个共享库,这些函数被定义在RIL头部文件(/include/telephony/ril.h)中。RIL参考源码位于/commands/reference-ril/,提供了一个使用贺式(Hayes)AT命令设备的参考Vendor RIL,适用于快速入门和通讯测试。

特定的Vendor RIL必须定义一个初始化函数,提供一系列句柄函数以处理每一个通讯请求。Android RIL守护进程会在启动时调用RIL_Init以初始化RIL。RIL_RadioFunctions结构体包含了无线电函数指针,如RIL_version、RIL_RequestFunc、RIL_RadioStateRequest、RIL_Supports、RIL_Cancel和RIL_GetVersion等。Vendor RIL必须提供RIL_RequestFunc函数来发送主动命令,RIL主动命令请求类型定义在ril.h的RIL_REQUEST_prefix中。RIL_RequestFunc函数需要处理各种RIL主动请求,并调用RIL_onRequestComplete函数完成通讯。

此外,RIL_Cancel函数用于指示取消一个待处理请求,一旦取消,被调用者应当尽量放弃请求并调用RIL_onRequestComplete函数的RIL_Errno CANCELLED。响应请求后调用RIL_onRequestComplete并产生其他结果是可以接受的,但会被忽略。RIL_Cancel函数应立刻返回,无需等待取消。RIL_GetVersion函数返回你的Vendor RIL的版本字符串。

热点内容
android作业 发布:2025-03-26 05:51:44 浏览:370
苹果微信怎么锁屏密码忘了怎么办啊 发布:2025-03-26 05:50:10 浏览:268
abaqus二次开发python 发布:2025-03-26 05:46:18 浏览:337
proe50编程 发布:2025-03-26 05:44:08 浏览:122
phpdatetime 发布:2025-03-26 05:43:33 浏览:948
oracle的linux客户端配置 发布:2025-03-26 05:36:38 浏览:201
安卓app安装包在哪个目录 发布:2025-03-26 05:35:43 浏览:663
安卓爱奇艺观看影片时如何看高清 发布:2025-03-26 05:34:13 浏览:533
换安卓手机如何把通讯录 发布:2025-03-26 05:30:41 浏览:349
c语言的环境变量 发布:2025-03-26 05:20:57 浏览:958