最近做了一个监听电话并录音的小例子,而保证它在后台运行不被杀确实不容易。
首先在主service中:
service中重写onStartCommand方法,这个方法有三个返回值, START_STICKY是service被kill掉后自动
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter=new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
UserPresentReceive userReceive = new UserPresentReceive();
registerReceiver(userReceive,filter);
int flag = START_STICKY;
// 判断是否是Broadcast发来的intentif (!("Protect".equals(intent.getAction()))) {
System.out.println("action" + intent.getAction());
this.outGoingNum = intent.getStringExtra("outGoingNums");
// 将耗时操作放到子线程中
backGroundExecution();
}
return super.onStartCommand(intent, flag, startId);
}
在onDestroy()方法中,启动当前服务,同时再启动protectService()
public void onDestroy() {
System.out.println("ServicePhone_onDestroy");
Intent ins = new Intent(this, ServicePhone.class);
ins.setAction("Protect");
startService(ins);
Intent in = new Intent(this, ProtectService.class);
startService(in);
super.onDestroy();
}
新建一个ProtectService服务 ,同时再建一个broadcastReceive
public int onStartCommand(Intent intent, int flags, int startId) {
Intent ins = new Intent(this, ServicePhone.class);
ins.setAction("Protect");
startService(ins);
flags = START_STICKY;
return super.onStartCommand(intent, flags, startId);
}
public void onDestroy() {
Intent in = new Intent(this, ServicePhone.class);
in.setAction("Protect");
startService(in);
//相互关联
Intent ins = new Intent(this, ProtectService.class);
startService(ins);
super.onDestroy();
}
ProtectService中用alarmManager来不断触发UserPresentReceive
private void proctectServiceInBack() {
/**
* 指定时间间隔 重复唤醒alarm
*/
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// 在合适的时间醒来
int alarmType = AlarmManager.RTC_WAKEUP;
// 设置时间长度
long timeOrLengthofWait = 150;
long timeOrLengthofWaits=20000;
Intent intent = new Intent(getApplicationContext(),
UserPresentReceive.class);
intent.setAction("protect");
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0,
intent, 0);
alarmManager.setRepeating(alarmType, timeOrLengthofWait,
timeOrLengthofWaits, alarmIntent);
}
在UserPresentReceive 监听系统广播:
Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,如果已经被结束了,就重新启动Service。
同时监听 ACTION_BOOT_COMPLETED
public void onReceive(Context content, Intent intent) {
System.out.println("UserPresentReceive");
if(Intent.ACTION_TIME_TICK.equals(intent.getAction()) ){
Intent in=new Intent(content, ProtectService.class);
content.startService(in);
}else if(Intent.ACTION_BUG_REPORT.equals(intent.getAction())){
Intent in=new Intent(content, ProtectService.class);
content.startService(in);
}else{
Intent in=new Intent(content, ProtectService.class);
content.startService(in);
}
//开机自启
if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){
Intent in=new Intent(content,ServicePhone.class);
in.setAction("Protect");
content.startService(in);
} else{
Intent in=new Intent(content, ServicePhone.class);
in.setAction("Protect");
content.startService(in);
}
}
}
另外建再建一个broadcastReceive来监听电话状态
if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
//取得号码
String outGoingNum = intent
.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Intent in=new Intent(content,ServicePhone.class);
in.setAction(".b2");
//将号码传给service
in.putExtra("outGoingNums", outGoingNum);
content.startService(in);
} else{
Intent in=new Intent(content, ServicePhone.class);
in.setAction(".b3");
content.startService(in);
}
}
manifest.xml application中可以加 android:persistent="true" 提高不被杀死的几率
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:persistent="true"
android:theme="@style/AppTheme" >
将protectService另起一个进程
<service
android:process=":protect"
android:name="com.example.phonelisten.ProtectService"
android:enabled="true" >
</service>
监听系统广播 设置android:priority 提高优先权
<receiver android:name="com.example.phonelisten.ReceivePhone" >
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.TIME_TICK" />
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<receiver android:name="com.example.phonelisten.UserPresentReceive" >
<intent-filter android:priority="999" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIME_TICK" />
<action android:name="android.intent.action.BUG_REPORT" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.media.RINGER_MODE_CHANGED" />
</intent-filter>
</receiver>