9.安卓基础之内容提供者

1. 回顾service

  • 开启服务
  • 绑定服务
  • 调用服务中的方法
  • 解绑服务
  • 关闭服务

2. 远程服务调用代码具体实现步骤

  • 第一步 :
    在远程 service 中去编写一个内部类,让这个内部类集成 Binder,实现 IService 接口,把 IService 接口声明出来 MyAgent extends Binder impelements IService

  • 第二步 :
    将 IService 接口中的public,private给干掉.并且将扩展名改为.aidl

1
2
3
4
interface IService {
void callMethodInService();
}
  • 第三步 :
    回到 service 中的内线类,将其改为继承 IService.Stub类
1
2
3
4
5
6
7
private class MyAgent extends IService.Stub{
@Override
public void callMethodInService() {
methodInService();
}
}
  • 第四步 :
    在这个内部类中实现的方法中去调用服务中的方法
1
2
3
4
5
6
7
8
@Override
public void callMethodInService() {
methodInService();
}
...
public void methodInService(){
System.out.println("远程服务中的方法被调用了 ");
}
  • 第五步 :
    回到远程的调用者应用中, bindService,写法与之前一样.
1
2
3
4
5
6
//绑定远程服务
public void bindservice(View v){
Intent intent = new Intent();
intent.setAction("com.javami.rms");
bindService(intent, new MyConnection(), BIND_AUTO_CREATE);
}
  • 第六步 :
    编写绑定服务的时候,建立的通信频道 MyConnection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private IService agent;
private class MyConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// agent = (IService )service
agent = IService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
  • 第七步 :
    在 MyConnection 的方法中,onServiceConnected 中强制类型转换 service 为内线.
1
agent = IService.Stub.asInterface(service);
  • 第八步 :
    通过内线调用服务中的方法
1
2
3
4
5
6
7
8
9
10
11
//调用远程服务中的方法
public void call(View v){
System.out.println("调用者调用远程服务中的方法 ");
try {
agent.callMethodInService();
} catch (RemoteException e) {
e.printStackTrace();
}
}

3. 杂谈题

android 中如何实现 ipc 通信?

常规的情况下,A应用去激活B应用中的组件的时候,这实际上是一个ipc通信的体现,这个时候发送是Intent就是在做ipc通信,intent也是去实现paraceable接口的,ipc通信时传递的非8种基本类型都需要去实现这个接口,如果是进程间通信,除了使用intent之外,还可以使用远程服务调用,谷歌已经对应用中提供了aidl技术技术供应用之间进行通信.

4. ContentProvider 的学习

内容提供者 : 用来提供数据.

4.1 插入删除数据到系统的短信数据库中

  • 先声明读写sms权限
1
2
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
  • 插入和删除短信的编写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//插入短信到系统的短信数据库中
public void add(View v){
ContentResolver resolver = getContentResolver();
//contentProvider使用的时候必须是以content://打头
Uri uri = Uri.parse("content://sms");
ContentValues values = new ContentValues();
values.put("address", "5201314"); // address
values.put("date", System.currentTimeMillis()); // address
values.put("type", "1"); // address
values.put("body", "亲爱的,我想你了..."); // address
resolver.insert(uri,values);
}
public void delete(View v){
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms");
resolver.delete(uri, "address=?", new String[]{"1 008-6"});
}

4.2 手机监听器的实现

  • 先开启相应的权限
1
2
3
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 启动服务
1
2
3
4
5
6
//开启服务
public void startService(View v){
Intent intent = new Intent();
intent.setAction("com.vrwait.recoder");
startService(intent);
}
  • 实现服务类,先监听电话后实现通话录音
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public class PhoneService extends Service {
private static final String LOG_TAG = "phoneService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
TelephonyManager tm;
@Override
public void onCreate() {
super.onCreate();
//监听电话的状态,如果电话来临,并且拨通了电话,就后台录音
tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
}
private class MyPhoneStateListener extends PhoneStateListener{
private MyPhoneStateListener(MediaRecorder mRecorder) {
this.mRecorder = mRecorder;
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 电话空闲
// 停止 录音
if(mRecorder!=null){
stopRecording();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //电话接通的状态
// 开启 录音
startRecording();
break;
case TelephonyManager.CALL_STATE_RINGING: //电话正在响
break;
default:
break;
}
}
private MediaRecorder mRecorder;
// 开始录音
private void startRecording(){
// 实例化MediaRecorder
mRecorder = new MediaRecorder();
// 指定一个源
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//输出的数据的格式
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//文件的保存到哪里
mRecorder.setOutputFile("/mnt/sdcard/yy.3gp");
//使用什么解码器
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try{
mRecorder.prepare();
}catch (Exception e){
e.printStackTrace();
}
mRecorder.start();
}
// 停止录音
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
  • 务必指定服务对象(启动的服务是从哪里启动的?)
    1
    2
    3
    4
    5
    <service android:name=".PhoneService">
    <intent-filter>
    <action android:name="com.vrwait.recoder"></action>
    </intent-filter>
    </service>