具有警报管理器和内部广播接收器的Android长时间运行服务

时间:2012-02-04 05:12:30

标签: android service broadcastreceiver alarmmanager

我有一个使用自定义Connection类(扩展线程)到硬件控制器的服务。当用户更喜欢时,我希望永久保持这种联系。我已经有了Android设备丢失互联网连接,在Wi-Fi等之间切换的代码。

为了保持连接,控制器要求您在每5分钟内与其通话。我目前在Connection类中启动一个在while()中运行的线程,并检查系统时间和上次通信的时间,以及何时> 4分钟它要求一个状态。出于某种原因,在不同的时间,通信不会及时发生。即,在5分钟后发生。就我所知,服务并不会死,但是" Ping"控制器迟到了。当手机插入充电器(或调试器)时,这种情况不会发生。此外,当我将服务移动到前台时,行为是相同的。

手机进入睡眠状态时,手机的速度是否会降低?

有更好的方法吗?

我认为它是AlarmManger,但是我在服务中遇到内部课程时遇到了麻烦。我尝试使用API​​演示作为起点,但我似乎无法弄清楚如何注册广播接收器。我试图以编程方式注册接收器,而不更改清单。

public class DeviceConnectionService extends Service {

    @Override
    public void onCreate() {
        Intent intent = new Intent(this, PingConnection.class);
        intent.setAction("KEEP_CONNECTION_ALIVE");
        PendingIntent sender = PendingIntent.getBroadcast(this,
            0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        // We want the alarm to go off 30 seconds from now.
        long firstTime = SystemClock.elapsedRealtime();
        firstTime += 15*1000;
        // Schedule the alarm!
        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                firstTime, 15*1000, sender);
        // register to listen to the Alarm Manager
        if (mPingConnectionReceiver == null) {
            mPingConnectionReceiver = new PingConnection();
            getApplicationContext().registerReceiver(mPingConnectionReceiver,
             new IntentFilter("KEEP_CONNECTION_ALIVE"));
        }
    }

    // ...

    public class PingConnection extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (dBug) Log.i("PingConnection", "Pinging Controller");
            // do real work here
        }
    }
}

3 个答案:

答案 0 :(得分:5)

  

手机进入睡眠状态时,手机的速度是否会降低?

手机在进入睡眠状态时关闭其处理器。这就是“睡眠”的定义。

  

我认为它是AlarmManger,但我无法在服务中使用内部类。我尝试使用API​​演示作为起点,但我似乎无法弄清楚如何注册广播接收器。我试图以编程方式注册接收器,而不更改清单。

AlarmManager这是一种不寻常的方法。话虽这么说,既然你拒绝详细描述“遇到麻烦”,很难帮助你。

摆脱getApplicationContext()(你不需要它,在这种情况下真的不想要它)。我会在触摸AlarmManager之前注册接收器。在开始制作之前,请选择包含您的包名称的操作名称(例如com.something.myapp.KEEP_CONNECTION_ALIVE)。

除此之外,请检查LogCat是否有警告。


<强>更新

在您的LogCat中,您应该收到来自AlarmManager的警告,抱怨无法与您的BroadcastReceiver通话。

替换:

Intent intent = new Intent(this, PingConnection.class);
intent.setAction("KEEP_CONNECTION_ALIVE");

使用:

Intent intent = new Intent("KEEP_CONNECTION_ALIVE");

你可能会有更好的运气。

答案 1 :(得分:0)

您无法在服务中注册AlarmManager。 您所能做的就是在Manifest.xml中将其声明为全局。 您可以通过这种方式从服务启动警报,方法是在Manifest.xml中声明它

如果您有远程服务并关闭启动器活动,则AlarmManager仍将运行,但不要忘记在服务的onDestroy()方法上停止它。

我试图仅在服务中注册AlarmManager,因为我没有将它用于主要活动,但没有成功! 它不像普通的BroadCastReceiver那样注册。

事情就是这样,你必须在Manifest.xml中将它声明为全局

答案 2 :(得分:0)

我知道它已经很晚了,但也许对其他人有用。

你可以注册它,问题是当Intent试图调用它时。

而不是这样称呼它:

Intent intent = new Intent(this, PingConnection.class);

创建一个空意图并添加您要收听的动作:

Intent intent = new Intent();
intent.setAction("value you want to register");

然后创建待处理的意图并像你一样发送广播。

为接收者创建一个属性,以便您可以在整个类中访问它,并在必要时取消注册(如果pendingIntent也是您可以随时取消注册的属性):

private PingConnection pingConnection = new PingConnection();

像这样注册:

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("the value you used before");
getApplicationContext().registerReceiver(pingConnection, filter);

现在你不会得到任何错误,而且这个类不是静态的,而且它是一个内部类。