在Android服务中注册ContentObserver

14

我正在开发一个家长控制/成人内容过滤应用程序。该应用程序持续监视儿童手机上的通话和短信,并将所有活动记录到服务器上。为此,我在BOOT_COMPLETED时启动了一个服务(MyService.java),并在服务的onCreate方法中注册了callLog和sms uri的contentobserver(请参考下面的代码片段)。

现在的问题是,由于我想监视每个外拨、接听电话和短信,我希望服务能够持续运行(而不会被停止/杀死)。此外,此服务仅用于注册内容观察器,并不进行任何其他处理(其OnstartCommand方法为虚拟的),因此安卓操作系统会在一段时间后杀死该服务。 我该如何确保服务持续运行并保持contentobserver对象处于活动状态?

   
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); }

2
人们已经评论说你无法保持服务运行,但是,由于听起来该服务只是注册ContentObservers,因此真正的问题是当服务被杀死时这些观察者是否保持注册(我相信它们会),以及如何防止在服务重新启动时重新注册新的观察者实例。 - spaaarky21
4个回答

3

你无法保证你的服务在安卓上持续运行。

对于你提到的用例,最好依靠Broadcast receiver,如ACTION_NEW_OUTGOING_CALL和SMS_RECEIVED。

如果你觉得以上支持的Broadcast receivers不能涵盖你所有的用例,请使用AlaramManager定期启动你的SERVICE,并查看CALL_LOGS和SMS表中的数据变化并采取适当的行动(这可能涉及对CALL_LOGS和SMS表中的最后访问数据进行检查标记)。


谢谢Sukumar。由于Android不允许服务无中断地运行,因此必须基于广播接收器重新设计应用程序。 - Srao

2

您可以将服务设置为在前台运行。这将大大降低操作系统杀死服务的可能性。

要了解更多信息,请阅读此处


0

当您的服务被杀死时,内容观察器会立即取消注册。因此,注册一次不是选项,您的服务必须始终运行。为了保证这一点,您必须从onStartCommand返回START_STICKY。您还可以在前台启动服务。

但是,如果服务被杀死时有一个新的调用到达怎么办?为了处理这个问题,您可以将app的最后一个处理过的_id存储在偏好设置中。每次获取所有大于已保存id的新通话日志。您必须在服务创建时以及观察器更改时处理日志。


-1
你不能保证服务会一直运行,但是你可以在 onStartCommand 方法中返回 START_STICKY,这样可以确保 Android 在任何情况下都会重新启动你的服务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接