2015-09-27 30 views
2

我試圖跟蹤「SCREEN_ON」在沒有用戶啓動應用程序的情況下觸發了多少次。該應用程序本身只顯示一些活動,僅包含一些圖表和信息。我創建了一個小測試,但我認爲這不是正確的方法,因爲它耗盡了我的電池。Android保持intentservice運行並監聽廣播

我收到了一個廣播接收器「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(); 
    } 
} 

回答

2

您是否有任何特殊原因使用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的目的。

+0

太棒了!我使用的是IntentService,因爲我只想讓1個活動的ScreenOnService運行。我只是讀完有關Service和IntentService的完整文檔。謝謝! – Jurdefur

0

我得到了一個廣播接收器「BOOT_COMPLETED」即會啓動註冊「SCREEN_ON」與永無止境的循環趕上廣播接收器的粘性IntentService廣播的(電池漏水問題)

這是完全inapp用於IntentService的ropriate。你的問題是onHandleIntent()返回後IntentService關機,迫使你進入這個忙碌的等待狀態。

取而代之,請使用常規Service

我可以在沒有服務的情況下收聽「SCREEN_ON」廣播嗎?

據我所知,ACTION_SCREEN_ON仍然無法在清單中進行註冊,所以,是的,你需要一個Service。但你需要一個Service,而不是一個IntentService

0

我得到了一個廣播接收器「BOOT_COMPLETED」啓動粘性 IntentService被註冊「SCREEN_ON」廣播接收機 與永無止境的循環趕上廣播公司(電池漏 問題)。

這是不正確的。意圖服務不適用於長時間運行的操作。實際上,它不再是繼續運行後onHandleIntent().

如果你想不斷聽到設備打開,那麼服務一定會幫助你聽取每個觸發器。

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