Ресиверы Android работают не так, как ожидалось

Честно говоря, они вообще ничего не делают. Позвольте мне начать с того, что я знаю, что Android переработал приемники в 3.1, в частности, управление загрузкой. Я знаю, что они сделали так, чтобы ACTION_BOOT_COMPLETED нельзя было использовать, если приложение не было ранее запущено пользователем. Тем не менее, людям удалось использовать их в текущем приложении, но я никогда не попадаю в свои приемники из-за моего BOOT_COMPLETED или моего SHUTDOWN.

Быстрое редактирование - пожалуйста, посмотрите внизу этого сообщения исправленный Shutdown Receiver, я заставил его работать, и теперь я просто застрял в своих усилиях, чтобы заставить BOOT_COMPLETED работать.

Мой манифест:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.smashingboxes.speedblock"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="18" />

    <!-- PERMISSIONS -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

...

    <!-- RECEIVERS -->
    <receiver android:name=".BootReceiver"
        android:enabled="true" >
        <intent-filter>
           <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    <receiver android:name=".ShutdownReceiver" >
       <intent-filter>
           <action android:name="android.intent.action.SHUTDOWN" />
       </intent-filter>
    </receiver>

Теперь мои реализованные классы приемников довольно просты:

BOOT_COMPLETED Приемник (тот, который не работает)

public class BootReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context c, Intent i) {
        Intent starterIntent = new Intent(c, LaunchActivity.class);

        // Start the activity (by utilizing the passed context)
        starterIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        c.getApplicationContext().startService(starterIntent);  
    }
}

Я пробовал разные вещи, основанные на том, что я видел в отношении решений, например, изменяя свою деятельность по запуску, чтобы включить

/* May need this, as of 3.1 we can't call BOOT_COMPLETED until the app has been run successfully */
Intent intent = new Intent("com.smashingboxes.speedblock.intent");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
this.sendBroadcast(intent);

или включить это в мой фильтр намерений загрузочного приемника в моем манифесте

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

Кажется, ничего не работает. Когда журналы вставляются в методы моего приемника, они никогда не попадают. Очевидно, люди до сих пор довольно регулярно используют эти два приемника, поэтому мне сложно понять, почему ни один из них не работает. Я что-то пропустил с регистрацией или что-то в этом роде?

--РЕДАКТИРОВАТЬ--

Я решил проблему с моим выключенным приемником. Во-первых, я по глупости забыл часть тега ACTION_. Во-вторых, у HTC есть отдельные методы выключения, в моем случае мне нужно было добавить фильтр намерений в свой запрос Receiver:

 <receiver android:name=".ShutdownReceiver" >
     <intent-filter>
         <action android:name="android.intent.action.ACTION_SHUTDOWN" />
         <action android:name="android.intent.action.QUICKBOOT_POWEROFF" />
     </intent-filter>
 </receiver>

Теперь мой приемник завершения работы работает, но все же не повезло с приемником завершения загрузки.


person zgc7009    schedule 12.03.2014    source источник


Ответы (1)


Я нашел ответ и считаю, что это действительно важно отметить, поскольку похоже, что в какой-то момент другие столкнутся с проблемой. Моя проблема заключалась в том, что я запускал «Launcher Activity» под названием LauncherActivity. По сути, он действовал как мой шлюз для запуска служб, приемников и тому подобного при запуске приложения. Это очень простой класс Activity:

public class LaunchActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    /* May need this, as of 3.1 we can't call BOOT_COMPLETED until the app has been run successfully */
    Intent intent = new Intent("com.smashingboxes.speedapp.intent");
    intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    this.sendBroadcast(intent);
}

@Override
protected void onStart(){
    super.onStart();

    Intent serviceIntent = new Intent(this, MainService.class);
    startService(serviceIntent);

    // NOTE: It is VERY, VERY important that we DO NOT finish this activity.
    // If we do, our BootReceiver will no longer receive its broadcast and 
    // we won't auto-start on boot
    //finish();
}

}

Обратите внимание, что я вызывал finish () для LaunchActivity. Проблема в том, что оно, казалось, сообщало Android, что приложение находится в остановленном состоянии, а это означает, что оно не разрешает прием широковещательной передачи BOOT_COMPLETED, хотя у меня было несколько служб, работающих в фоновом режиме. LauncherActivity ДОЛЖЕН оставаться активным на протяжении всего жизненного цикла, иначе приемник BOOT_COMPLETED станет бесполезным. То, что я раньше не видел, упоминалось, но опять же, я думаю, стоит отметить.

person zgc7009    schedule 13.03.2014