17-使用服务监听通话 组件4 service

服务的生命周期

服务的生命周期跟采用启动服务的方法有关: 当采用Context.startService()方法启动服务,与之有关的生命周期方法onCreate() onStart()  onDestroy()onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。onDestroy()该方法在服务被终止时调用。 当采用Context.bindService()方法启动服务,与之有关的生命周期方法onCreate() onBind()  onUnbind()  onDestroy()onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:onCreate()onStart()onBind()onUnbind()[重载后的方法需返回true]onRebind()

1、服务监听通话

核心文件

public class PhoneService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public void onCreate() { 
		super.onCreate();
		TelephonyManager manager =  (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		manager.listen(new PhoneListener(), PhoneStateListener.LISTEN_CALL_STATE);
	}
	
	private final class PhoneListener extends PhoneStateListener{
		private String incomeingNumber;
		private MediaRecorder mediaRecorder;
		private File  file;
		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);
			try {
				switch(state){
				case TelephonyManager.CALL_STATE_RINGING:  //来电
					this.incomeingNumber = incomingNumber;
					break ;
				case TelephonyManager.CALL_STATE_OFFHOOK:  //通话中
					file = new File(Environment.getExternalStorageDirectory(),incomeingNumber+System.currentTimeMillis()+".3gp");
					mediaRecorder = new MediaRecorder();
					mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//话筒,只能录说话人
					mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//手机常用格式
					mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//编码方式
					mediaRecorder.setOutputFile(file.getAbsolutePath());
					mediaRecorder.prepare();
					mediaRecorder.start(); //开始录音
					break ;
				case TelephonyManager.CALL_STATE_IDLE:  //挂断后返回空闲
					if(mediaRecorder != null ){
						mediaRecorder.stop();
						mediaRecorder.release();
						mediaRecorder = null;
						uploadFile();
					}
					break ;	  
				} 
			} catch ( Exception e) { 
				e.printStackTrace();
			} 
		}
		private void uploadFile() {
			// TODO Auto-generated method stub
			
		}
	}
}
context.stopService(service);
public class BootBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context,PhoneService.class);//显式或隐式
        context.startService(service);//intent激活服务

    }

}

       <service android:name=".PhoneService"></service>
        <receiver android:name=".BootBroadcastReceiver">
            <intent-filter  >
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter> 
        </receiver>
    </application>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<!-- 访问网络 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<!-- 读取通话状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- 创建或者删除文件 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 写文件 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 录音 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
</manifest>

2、建立于访问者相互通信的本地服务

本地服务:服务与访问者在同一个进程中,反之则远程。

public class StuqueryActivity extends Activity {
	private EditText stuno_text;
	private StuServiceConnection conn = new StuServiceConnection();
	private Istu istu;
	private TextView nameText;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		stuno_text = (EditText) this.findViewById(R.id.stuno);
		nameText = (TextView) this.findViewById(R.id.name);
		
		Intent service = new Intent(this, StuService.class);

		bindService(service, conn, BIND_AUTO_CREATE);//启动服务

	}

	private class StuServiceConnection implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName paramComponentName,
				IBinder paramIBinder) {
			istu = (Istu) paramIBinder;

		} 
		@Override
		public void onServiceDisconnected(ComponentName paramComponentName) {
			istu = null;
		} 
	} 
	@Override
	protected void onDestroy() {
		unbindService(conn);
		super.onDestroy();
	}

	public void queryStu(View v) {
		String no = stuno_text.getText().toString();
		int no_int = Integer.parseInt(no); 
		String name = istu.queryStu(no_int);
		nameText.setText(name);
	}
}

public class StuService extends Service {
	private StuBinder binder = new StuBinder();
	
	private String[] names = { "张飞", "赵云", "刘备" };

	public String query(int no) {
		if (no > 0 && no < 4) {
			return names[no - 1];
		}
		return null;
	}

	@Override
	public IBinder onBind(Intent intent) {
		 //通过binder来调取服务中飞方法 
		return binder;
	}
	
	
	private class StuBinder extends  Binder implements Istu{

		@Override
		public String queryStu(int no) {
 			return query(no);
		}
		
	}
}

public interface Istu {
	public String queryStu(int no);
}

 ... <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".StuqueryActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".StuService"></service>...
            

3、建立于访问者相互通信的远程服务 AIDL

AIDL是一种接口定义语言,实现两个进程通信。

远程部分

package com.yza.aidl;
//AIDL接口描述规则 不能有修饰符
 interface StuQuery {
	  String queryStu(int no);
}

public class StuQueryService extends Service {
	
	private IBinder binder = new StuQueryBinder();
	private String[] names = { "张飞", "赵云", "刘备" };

	public String query(int no) {
		if (no > 0 && no < 4) {
			return names[no - 1];
		}
		return null;
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return binder;
	}

	private final class StuQueryBinder extends StuQuery.Stub {

		@Override
		public String queryStu(int no) throws RemoteException {
			// TODO Auto-generated method stub
			return query(no);
		}

	}
}

<!-- 最好用隐式意图 -->
        <service android:name=".StuQueryService">
            <intent-filter >
                <action android:name="com.yza.stu.query" />
            </intent-filter> 
        </service> 

本地则

public class StuqueryActivity extends Activity {
	private EditText stuno_text;
	private StuServiceConnection conn = new StuServiceConnection();
 
	private TextView nameText;
	private StuQuery stuQuery;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		stuno_text = (EditText) this.findViewById(R.id.stuno);
		nameText = (TextView) this.findViewById(R.id.name);
		
		Intent service = new Intent("com.yza.stu.query");

		bindService(service, conn, BIND_AUTO_CREATE);//启动服务

	}

	private class StuServiceConnection implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName paramComponentName,
				IBinder paramIBinder) {
			stuQuery = StuQuery.Stub.asInterface(paramIBinder);
		} 
		@Override
		public void onServiceDisconnected(ComponentName paramComponentName) {
			stuQuery = null;
		} 
	} 
	@Override
	protected void onDestroy() {
		unbindService(conn);
		super.onDestroy();
	}

	public void queryStu(View v) {
		String no = stuno_text.getText().toString();
		int no_int = Integer.parseInt(no); 
		String name;
		try {
			name = stuQuery.queryStu(no_int);
			nameText.setText(name);
		} catch (RemoteException e) { //远程意外
			// TODO Auto-generated catch block
			e.printStackTrace();
			nameText.setText("意外");
		}

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值