Android保持intentservice运行并监听广播

时间:2015-09-27 10:35:27

标签: android

我试图跟踪在没有用户启动应用的情况下触发“SCREEN_ON”的次数。该应用程序本身只显示一些活动,其中包含一些图表和信息。我创建了一个小测试,但我认为这不是正确的方法,因为它正在耗尽我的电池。

我有一个广播接收器“BOOT_COMPLETED”,它启动一个粘性的IntentService,它正在注册“SCREEN_ON”广播接收器,带有一个永无止境的循环来捕捉广播(电池耗尽问题)。

我可以在没有服务的情况下收听“SCREEN_ON”广播吗?

朱尔

清单

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
    android:name=".Application"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:hardwareAccelerated="true">

    <activity
        android:name=".activities.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:enabled="true" android:name=".services.ScreenOnService" />

    <receiver android:name=".broadcast.receivers.AutoStartReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    <receiver android:name=".broadcast.receivers.ScreenOnReceiver">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_ON" />
        </intent-filter>
    </receiver>
</application>

AutoStartReceiver

public class AutoStartReceiver extends BroadcastReceiver
{
    public void onReceive(Context aContext, Intent anIntent)
    {
        Log.i("[AutoStartReceiver]", "onReceive");
        aContext.startService(new Intent(aContext, ScreenOnService.class));
    }
}

ScreenOnReceiver

public class ScreenOnReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Log.i("[ScreenOnReceiver]", "onReceive");
    }
}

ScreenOnService

public class ScreenOnService extends IntentService
{
    private ScreenOnReceiver theReceiver;

    public ScreenOnService()
    {
        super(ScreenOnService.class.getName());
        theReceiver = new ScreenOnReceiver();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.v("[ScreenOnService]", "onStartCommand");
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {
        Log.i("[ScreenOnService]", "onHandleIntent");
        registerReceiver(theReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
        while(true);
    }

    @Override
    public void onDestroy()
    {
        Log.i("[ScreenOnService]", "onDestroy");
        unregisterReceiver(theReceiver);
        super.onDestroy();
    }
}

3 个答案:

答案 0 :(得分:3)

您是否有任何特殊原因使用IntentService而不是常规Service

您应该能够使用常规的Service来实现这一目标。将接收者注册为onStartCommand

的一部分

这样的事情:

public class MyService extends Service {
    private ScreenOnReceiver mReceiver;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mReceiver == null) {
            mReceiver = new ScreenOnReceiver();
            registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
        }
        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

    // remember to unregister receiver in onDestroy...
}

这样可以避免繁忙的循环。 IntentService旨在成为执行后台操作的短期服务。您的使用不符合IntentService的目的。

答案 1 :(得分:0)

  

我有一个广播接收器“BOOT_COMPLETED”,它启动一个粘性的IntentService,它正在注册“SCREEN_ON”广播接收器,带有一个永无止境的循环来捕捉广播(电池耗尽问题)

这对IntentService完全不合适。您的问题是IntentServiceonHandleIntent()返回后关闭,迫使您进入忙碌等待状态。

相反,请使用常规Service

  

我可以在没有服务的情况下收听“SCREEN_ON”广播吗?

AFAIK,ACTION_SCREEN_ON仍无法在清单中注册,因此,是的,您需要Service。但您需要Service,而不是IntentService

答案 2 :(得分:0)

  

我有一个广播接收器&#34; BOOT_COMPLETED&#34;开始发粘   正在注册&#34; SCREEN_ON&#34;的IntentService广播接收器   一个永无止境的循环来捕捉广播(电池耗尽   问题)。

这不正确。意图服务不是为长时间运行而设计的。实际上它在onHandleIntent().之后不再保持运行

如果你想要不断地听设备打开,那么服务肯定会帮助你听每个触发器。

public class ScreenOnService extends Service
{
...........
}