Android学习笔记_22_服务Service应用之—与Activity进行相互通信的本地服务
一、启动服务的两种方法方法:
第一种: startService()和stopService()启动关闭服务。适用于服务和Activity之间没有调用交互的情况。如果相互之间需要方法调用或者传递参数,需要使用bindService()和unbindService()方法启动关闭服务。
第二种: 采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法,这个时候调用者和服务绑定在一起。 如果客户端要与服务进行通信,那么,onBind()方法必须返回Ibinder对象。如果调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
服务有关的生命周期方法
与采用Context.startService()方法启动服务有关的生命周期方法
onCreate() 》 onStart() 》 onDestroy()
onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务, 但onStart() 方法会被多次调用。
onDestroy()该方法在服务被终止时调用。
onCreate() 》 onBind() 》 onUnbind() 》 onDestroy()
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用 Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。
如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:
onCreate() 》onStart() > onBind() > onUnbind()[重载后的方法需返回true]àonRebind()
二、代码实现:
1、配置文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.phonelisteners" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <service android:name="com.example.phonelistener.PhoneService"/> <receiver android:name="com.example.phonelistener.BootBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> </application> <!-- 开机启动权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- 监听电话状态 --> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- 在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 访问internet权限 --> <uses-permission android:name="android.permission.INTERNET"/> <!-- 刻录权限 --> <uses-permission android:name="android.permission.RECORD_AUDIO"/> </manifest>
2、通过广播接收者启动服务:
public class BootBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //意图是用于激活组件的,服务不能自己启动 Intent in = new Intent(context,PhoneService.class); context.startService(in); } }
3、监听电话服务:
package com.example.phonelistener; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Service; import android.content.Context; import android.content.Intent; import android.media.MediaRecorder; import android.os.IBinder; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; public class PhoneService extends Service { private static final String TAG = "PhoneService"; @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { super.onCreate(); // 通过系统内置服务获取电话管理服务 TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); telManager.listen(new PhoneListener(),PhoneStateListener.LISTEN_CALL_STATE); Log.e(TAG, "onCreate()"); } private class PhoneListener extends PhoneStateListener { private File file; private boolean recoding; private String mobile; private MediaRecorder recorder; @Override public void onCallStateChanged(int state, String incomingNumber) { try { Log.i(TAG, " phone number: "+incomingNumber); switch (state) { /* 无任何状态时,挂断电话回到空闲状态 */ case TelephonyManager.CALL_STATE_IDLE: if (recorder != null) { if (recoding) { recorder.stop(); recorder.release(); Log.e(TAG, "record finish"); recorder = null; //uploadFile(); } } break; case TelephonyManager.CALL_STATE_OFFHOOK: // 接起电话时 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String filename = mobile + dateFormat.format(new Date()) + ".3gp"; // file=new File(Environment.getExternalStorageDirectory(),filename); file=new File("/storage/sdcard0/Music",filename); recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// .3pg recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(file.getAbsolutePath()); recorder.prepare(); recorder.start();// 开始录音 recoding = true; Log.e(TAG, "recording: "+file.getAbsolutePath()); break; case TelephonyManager.CALL_STATE_RINGING: //电话进来时 mobile = incomingNumber; break; } } catch (Exception e) { Log.e(TAG, e.toString()); } super.onCallStateChanged(state, incomingNumber); } //上传文件 private void uploadFile(){ } }
4、图解: