我正在研究家长控制/成人内容过滤应用程序 . 这个应用程序持续监视孩子的手机上的电话和微笑,并将所有活动记录到服务器上 . 为此,我在BOOT_COMPLETED上启动服务(MyService.java),在服务的onCreate方法中,我为callLog和sms uri注册了一个contentobserver(请参阅下面的代码片段) .
现在的问题是,因为我想监视每个传出,传入呼叫和短信我希望服务连续运行(不被停止/杀死) . 此外,此服务仅用于注册内容观察者而不进行任何其他处理(其OnstartCommand方法是虚拟的),因此android OS会在一段时间后终止服务 . How do I ensure that the service runs continuously and keeps the contentobserver object alive ?
public class MyService extends Service {
private CallLogObserver clLogObs = null;
public void onCreate() {
super.onCreate();
try{
clLogObs = new CallLogObserver(this);
this.getContentResolver().registerContentObserver(android.provider.CallLog.Calls.CONTENT_URI, true, clLogObs);
}catch(Exception ex)
{
Log.e("CallLogData", ex.toString());
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy() {
if( clLogObs !=null )
{
this.getContentResolver().unregisterContentObserver(clLogObs);
}
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return Service.START_STICKY;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
4 回答
您无法确保自己的服务在Android上持续运行 .
对于您提到的用例,最好依赖广播接收器,如ACTION_NEW_OUTGOING_CALL和SMS_RECEIVED .
如果您认为,上面支持的广播接收器并未涵盖您的所有用例 . 使用AlaramManager定期启动您的SERVICE并查看CALL_LOGS和SMS表中的数据更改并采取适当的操作(这可能涉及检查标记CALL_LOGS和SMS表上的最后访问数据) .
您可以将服务设置为在前台运行 . 这将使您的服务被操作系统杀死的可能性大大降低 .
阅读here了解更多信息 .
一旦您的服务被杀,内容观察者就会被取消注册 . 因此,注册一次不是一个选项,您的服务必须始终运行 . 为了保证这一点,你必须从onStartCommand返回START_STICKY . 您也可以在前台启动该服务 .
但是,如果新服务在服务被杀时到达,该怎么办?要处理此问题,您可以将最后处理的_id存储在应用的首选项中 . 每次获取所有新的通话记录,其ID大于保存的ID . 您必须处理服务onCreate以及观察者onChange上的日志 .
你不能保证它会连续运行,但是你可以从onStartCommand返回START_STICKY,这可以保证Android在任何原因被杀死时会重新启动你的服务 .