phone服务相关
来源:互联网 发布:spss mac版怎么保存 编辑:程序博客网 时间:2024/05/19 17:27
phone系统服务概述
Android系统中framework和app用到名称为phone的服务还是比较多的,需要用到的是ITelephony.aidl
frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl
void answerRingingCall();ITelephony中有各种通讯相关接口,从设计角度来说这个服务中的很多方法是不供三方app调用的,但还是有方法(例如反射)可以使用ITelphony的。不然各种系统管家和骚扰拦截程序怎么能挂断电话呢
服务发布
服务实现是在PhoneInterfaceManager.java中,位于Telephony包下,该包编译后是TeleService.apk,进程就是包名com.android.phone
packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java
public class PhoneInterfaceManager extends ITelephony.Stub {
/* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) { synchronized (PhoneInterfaceManager.class) { if (sInstance == null) { sInstance = new PhoneInterfaceManager(app, phone); } else { Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); } return sInstance; } }单例模式
private PhoneInterfaceManager(PhoneGlobals app, Phone phone) { ... publish(); }
private void publish() { if (DBG) log("publish: " + this); ServiceManager.addService("phone", this); }构造函数中调用publish(), 然后添加名称为phone的服务到系统中。init的调用链如下:
packages/services/Telephony/src/com/android/phone/PhoneApp.java
public class PhoneApp extends Application {该类继承自Application类,即phone进程一启动必会走onCreate方法
@Override public void onCreate() { if (UserHandle.myUserId() == 0) { // We are running as the primary user, so should bring up the // global phone state. mPhoneGlobals = new PhoneGlobals(this); mPhoneGlobals.onCreate(); ... } }packages/services/Telephony/src/com/android/phone/PhoneGlobals.java
public void onCreate() { ... phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone()); ... }phone进程一启动phone服务就添加到系统中,其它进程就可以通过ITelephony调用phone服务
服务实现
拿一个函数举例,就是概述中的answerRingingCallpublic void answerRingingCall() { answerRingingCallForSubscriber(getDefaultSubscription()); }
public void answerRingingCallForSubscriber(int subId) { if (DBG) log("answerRingingCall..."); // TODO: there should eventually be a separate "ANSWER_PHONE" permission, // but that can probably wait till the big TelephonyManager API overhaul. // For now, protect this call with the MODIFY_PHONE_STATE permission. enforceModifyPermission(); sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId)); }
/** * Posts the specified command to be executed on the main thread, * waits for the request to complete, and returns the result. * @see #sendRequestAsync */ private Object sendRequest(int command, Object argument, Integer subId) { if (Looper.myLooper() == mMainThreadHandler.getLooper()) { throw new RuntimeException("This method will deadlock if called from the main thread."); } MainThreadRequest request = new MainThreadRequest(argument, subId); Message msg = mMainThreadHandler.obtainMessage(command, request); msg.sendToTarget(); // Wait for the request to complete synchronized (request) { while (request.result == null) { try { request.wait(); } catch (InterruptedException e) { // Do nothing, go back and wait until the request is complete } } } return request.result; }发送CMD_ANSWER_RINGING_CALL请求到mMainThreadHandler处理,如字面意思该Handler的作用就是把代码运行在主线程,然后binder线程同步wait到结果返回给调用端。Looper.myLooper() 获得的Looper实际就是binder thread的Looper,所以它们一般情况下肯定是不相等的,除非是phone进程代码直接调用该类方法(这个就和binder没有任何关系了,相当于调用一个类的成员方法,但是phone进程这样做其实没有任何意义,因为这个本来就是对外提供服务,phone进程本身要实现同样功能很简单)。
case CMD_ANSWER_RINGING_CALL: request = (MainThreadRequest) msg.obj; int answer_subId = request.subId; answerRingingCallInternal(answer_subId); // Wake up the requesting thread /// M: for ALPS02014935. 2015-04-02 @{ synchronized (request) { request.result = "OK"; request.notifyAll(); } /// @} break;mMainThreadHandler消息处理中调用answerRingingCallInternal方法
private void answerRingingCallInternal(int subId) { final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle(); if (hasRingingCall) { final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle(); final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle(); if (hasActiveCall && hasHoldingCall) { // Both lines are in use! // TODO: provide a flag to let the caller specify what // policy to use if both lines are in use. (The current // behavior is hardwired to "answer incoming, end ongoing", // which is how the CALL button is specced to behave.) PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); return; } else { // answerCall() will automatically hold the current active // call, if there is one. PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); return; } } else { // No call was ringing. return; } }answerRingingCallInternal调用PhoneUtils中相关方法,例如answerCall方法,其实通话UI中接听电话调用的也是该方法,可见phone服务就是开放部分功能对外使用。
使用举例
frameworks/base/telephony/java/android/telephony/TelephonyManager.java
大多三方app不必直接使用ITelephony.aidl,用TelephonyManager即可,这个是sdk中设计的通讯相关类。
private ITelephony getITelephony() { return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); }getITelephony方法获取的就是phone服务
public String getDeviceId() { try { ITelephony telephony = getITelephony(); if (telephony == null) return null; return telephony.getDeviceId(mContext.getOpPackageName()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { return null; } }拿getDeviceId举例,就是使用phone服务获取设备imei或者meid
0 0
- phone服务相关
- phone相关
- Andriod Phone模块相关
- 转:Andriod Phone模块相关
- phone中的绘图相关资料
- 联通的沃phone相关新闻
- android -- phone(五)相关的功能
- Windows Phone 7 电话本相关的操作
- Windows Phone的VideoBrush的分辨率相关
- Phone相关知识学习总结与梳理
- AIX 服务相关命令
- SAP相关服务【兼职】
- WTC服务相关
- web 服务相关
- CentOS 相关服务
- Oracle相关服务详解
- IIS相关服务
- Oracle相关的服务
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
- 专业工具软件作业以及补充资料等说明
- 浅谈HTTP中Get与Post的区别
- java与c之间的参数转换
- cookie 和session 的区别详解
- phone服务相关
- js实现计时器
- maven cxf
- (OK) /opt/android-x86/lineage-14.1-kiwi-on-VB/kernel/generic/android_x86_64/kernel/auditsc.c
- 设计模式01之 简单工厂模式(创建模式)
- 如何用手机访问自己电脑?
- “玲珑杯”ACM比赛 Round #11
- MySQL的学习笔记
- 软件测试工具