美文网首页
Android学习笔记(七)

Android学习笔记(七)

作者: 南山伐木 | 来源:发表于2017-02-23 22:26 被阅读24次

    AIDL进程间通信;AIDL(Android Interface Design Language)

    ▲№aidl接口语法:
    1、支持package 和 import等关键字
    支持void interface等关键字
    2、不支持访问修饰符
    3、接口中不能定义常量只能定义方法
    4、参数类型或返回类型:
    a、基本类型
    b、CharSequence
    c、String
    d、List
    e、Map
    f、Parcelable 可打包对象
    5、基本类型、CharSequence、String、List和Map在使用时不需要导包,除此之外的所有类型,使用时必须import,即便该类型与接口定义在同一包中也如此
    ★№[匿名内部类 class A{new B(){},new C(){}},B和C和引用名称为:A.$1,A.$2;]

    ★№AIDL实现跨进程通信原理:在服务端Service和客户端(另一个进程的Activity)共用一个公用的接口,该接口使用AIDL定义,Android系统将该接口实现IInterface的方法并会自动生成该接口的跨进程实现类,

    public static abstract class Stub extends Binder implements 
       com.fanfan.aidl.musicplay.MusicPlayControllor{  ... }
    

    生成的Stub类继承了Binder即可通过进程边界进行跨进程通信,而又实现了AIDL定义的接口,则可实现该接口下的所有方法。

    在客户端定义相同的AIDL接口(包名相同),同样会生成该接口的跨进程实现类Stu;但系统会进行判断,该客户端是否是在同一进程内,若不在同一进程内,则会生成Stu类的代理Stu.Proxy(obj);
    ●内部代码为:

     public static com.fanfan.aidl.musicplay.MusicPlayControllor asInterface(android.os.IBinder obj)
    {
       if (((iin!=null)&&(iin instanceof com.fanfan.aidl.musicplay.MusicPlayControllor))) {
          return ((com.fanfan.aidl.musicplay.MusicPlayControllor)iin);
       }
      return new com.fanfan.aidl.musicplay.MusicPlayControllor.Stub.Proxy(obj);
    }
    

    另外一个进程的客户端通过该代理,扩展该代理Stu.Proxy(obj);即可调用服务端下的所有方法。

    ▲☆实现步骤:
    §服务端
    1、在服务端定义 ***.aidl文件(定AIDL接口)
    2、在Service中的onBind方法返回AIDL.Stub类的对象
    3、在注册Service时,指定一个隐式意图;

    <action android:name="com.fanfan.action.MUSIC_PLAYER_SERVICE"/>
    

    ▲☆客户端:
    1、创建与服务端一样的AIDL接口,包名必须一样。
    2、创建ServiceConnection对象,在其onServiceConnected方法中将参数IBinder对象传入到AIDL接口.Stub.asInterface方法中作参数获得一个AIDL接口对象,如

    1、创建与服务端一样的AIDL接口,包名必须一样。
    2、创建ServiceConnection对象,在其onServiceConnected方法中将参数IBinder对象传入到AIDL接口.Stub.asInterface方法中作参数获得一个AIDL接口对象,如 : controllor = MusicPlayControllor.Stub.asInterface(binder);
    3 、 用service注册时的action创建要绑定的Service:
    Intent intent = new Intent("com.fanfan.action.MUSIC_PLAYER_SERVICE");
    4、调用bindService方法绑定到Service: bindService(intent, conn, BIND_AUTO_CREATE);
    5、通过AIDL接口对象去调用服务端的方法
    6、在onDestroy方法中解除绑定:unbindService(conn);

    ◆电话操作:
    通话记录管理:
    相关表:
    calls : _id number duration date type(对应的 有:Calls.INCOMING_TYPE、Calls.MISSED_TYPE、Calls.OUTGOING_TYPE)
    ★ 相关的API: CallLog Calls
    ▲呼出电话的监听
    当电话呼出时,会发送一个系统广播Intent.ACTION_NEW_OUTGOING_CALL
    可以在广播中获取呼出号码的信息。
    1)getResultData()
    2)intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

    ★☆无法使用abortBroadcast()取消通话,但可使用setResultData(null)取消,也可用setResultData("18545006310")将呼出电话进行更改;
    使用权限:android.permission.PROCESS_OUTGOING_CALLS
    在真机上还需权限:android:name="android.permission.READ_CONTACTS"
    ▲呼入电话的监听:
    1、获取TelephoneManager实例:tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    2、可通过tm获得关于手机许多信息:

    tm.getCallState()); //通话状态 空闲(TelephonyManager.CALL_STATE_IDLE) 摘机(占线) TelephonyManager.CALL_STATE_OFFHOOK、响铃TelephonyManager.CALL_STATE_RINGING;
    tm.getCellLocation());// 通话位置,开了gps可获取精确位置,否则是模糊位置
    tm.getDeviceId());//设备ID
    tm.getDeviceSoftwareVersion());
    tm.getLine1Number()); // 本机号码;
    tm.getNetworkCountryIso());//
    tm.getNetworkOperator());// 手机运营商
    tm.getNetworkOperatorName());//运营商名
    tm.getPhoneType());//手机电话类型,GSM/CDMA
    tm.getSimCountryIso());// sim卡信息
    tm.getSimSerialNumber());// sim卡序列号;
    tm.getSubscriberId());// sim卡识别序列码子码
    tm.isNetworkRoaming());// 是否支持漫游
    tm.getNetworkType());// 网络类型;
    tm.getVoiceMailAlphaTag());//信箱类型
    tm.getVoiceMailNumber());// 音量
    

    ★№ 要监听呼入电话
    可在一个Service中创建一个电话监听器: listener = new PhoneStateListener() {} 包含许多可回调的方法,若只监听通话状态,可重写onCallStateChanged(..)方法;
    利用电话管理器对电话进行监听:tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);//第二个参数为要监听的状态
    必须在onDestroy方法中取消该监听,否则会出现内存泄露:

    tm.listen(listener, PhoneStateListener.LISTEN_NONE);
      //参数为NONE时表示什么都不监听,即可取消监听器。
    

    ★☆ 挂断:需要取出系统类ITelephony,该类包含对呼入电话的许多方法,但在系统被标记为{@hide},即被隐藏,若需要获取此实例,须导入相关的AIDL接口文件,并利用反射机制获得相关方法;

     Method method = Class.forName("android.os.ServiceMananger")// 需要要加载的类名.getDeclaredMethod("getService",String.class);//需要调用方法名和需要的参数
    IBinder binder = (IBinder) method.invoke(null,TELEPHONY_SERVICE);// 参数分别为接收的对象和参数名 
    ITelephony tle = ITelephony.Stub.asInterface(binder); // 通过AIDL获得Service为本地代理 // 调用ITelePhony下的方法 // tle.call(number); //拨打电话,需要root // tle.answerRingingCall();//接听电话,需要root
    tle.endCall();// 挂断电话,可用于防骚扰;
    

    博客地址:Android学习笔记(七)

    相关文章

      网友评论

          本文标题:Android学习笔记(七)

          本文链接:https://www.haomeiwen.com/subject/srhiwttx.html