Будильник Android не срабатывает после перезагрузки:

РЕДАКТИРОВАТЬ: Любой, кто наткнется на это, может захотеть знать, что для срабатывания сигнала тревоги после перезагрузки вам необходимо зарегистрировать его в манифесте, а не во время выполнения.

У меня есть следующий класс, который я разработал, используя рекомендации здесь:

public class MainActivity extends Activity {
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    BroadcastReceiver br;
    TextView t; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setup(); 
        t = (TextView)findViewById(R.id.textView1);


        ComponentName receiver = new ComponentName(getApplicationContext(), SampleBootReceiver.class);
        PackageManager pm = getApplicationContext().getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);


        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 10);
        calendar.set(Calendar.MINUTE, 22); // Particular minute
        calendar.set(Calendar.SECOND, 0);
        alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                1000*60*60*24, alarmIntent);
    }


    public void setup() {
        br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent i) {
                Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
                //Invoke the service here Put the wake lock and initiate bind service
                t.setText("Hello Alarm set");
            }
        };
        registerReceiver(br, new IntentFilter("com.testrtc") );
        alarmIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.testrtc"),
                0 );
        alarmMgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

У меня есть класс SampleBootReceiver, который:

public class SampleBootReceiver extends BroadcastReceiver {
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    BroadcastReceiver br;
    TextView t; 

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
            Toast.makeText(context, "Hello from Bootloader", 10000).show();
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.HOUR_OF_DAY, 10);
            calendar.set(Calendar.MINUTE, 22); // Particular minute
            calendar.set(Calendar.SECOND, 0);
             alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
             alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                        1000*60*60*24, alarmIntent);


        }
    }
}

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

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.testrtc"
    android:versionCode="1"
    android:versionName="1.0" >

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

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.testrtc.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>

        <receiver
            android:name=".SampleBootReceiver"
            android:enabled="false" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" >
                </action>
            </intent-filter>
        </receiver>
    </application>

</manifest>

Будильник работает нормально до перезагрузки, после перезагрузки я также получаю всплывающее сообщение от класса BootReceiver. Но будильник не сбрасывается. Здесь я хочу прояснить один момент, поскольку в Документах указано, что будильник не будет сброшен, если приложение не будет запущено пользователем хотя бы один раз: Set the RECEIVE_BOOT_COMPLETED permission in your application's manifest. This allows your app to receive the ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting (this only works if the app has already been launched by the user at least once): Каков контекст этого утверждения? Если пользователю необходимо перезапустить приложение, в любом случае будет вызван onCreate и снова будет установлен будильник. Или это утверждение означает, что на протяжении всего жизненного цикла приложение должно запускаться на телефоне хотя бы один раз?


person Skynet    schedule 21.01.2014    source источник
comment
для всех уровней API возникает эта проблема..??   -  person SilentKiller    schedule 21.01.2014
comment
Я не тестировал API уровня 19, однако эта проблема существует для Jelly Bean.   -  person Skynet    schedule 21.01.2014
comment
то, о чем я думал, я столкнулся с тем же самым в JellyBean, и я обнаружил, что BroadcastListener не работает выше 4.0 автоматически после загрузки, поэтому я создал службу для запуска моей трансляции.   -  person SilentKiller    schedule 21.01.2014
comment
В моем случае трансляция работает нормально, однако тревога не сбрасывается, как я уже сказал, я получаю всплывающее сообщение от класса SampleBootReceiver при перезагрузке. Однако я теряю тревогу.   -  person Skynet    schedule 21.01.2014


Ответы (1)


Я думаю, ваш будильник работает нормально, но я не вызываю метод setup(), когда ваш SampleBootReceiver снова запускается после завершения загрузки.

снова добавил эту строку в SampleBootReceiver, чтобы получить alarmIntent

 registerReceiver(br, new IntentFilter("com.testrtc") );
        alarmIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.testrtc"),
                0 );
        alarmMgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));

Спасибо

person Md Abdul Gafur    schedule 21.01.2014
comment
Но я думаю, что могу определить только onReceive (для тревоги) в классе, который расширяет Activity. - person Skynet; 21.01.2014
comment
вы используете новый IntentFilter (com.testrtc), чтобы начать что-то, вам нужно снова позвонить, чтобы выполнить эту работу. - person Md Abdul Gafur; 21.01.2014
comment
Как это сделать, можете ли вы привести мне подробный пример? - person Skynet; 21.01.2014
comment
Я получаю это, когда пытаюсь добавить строки: метод registerReceiver (BroadcastReceiver, IntentFilter) не определен для типа SampleBootReceiver - person Skynet; 21.01.2014
comment
Пожалуйста, найдите Почему registerReceiver не работает без активности .. вы нашли решение. - person Md Abdul Gafur; 21.01.2014
comment
Итак, я использую контекст, который я получаю в public void onReceive(Context context, Intent intent) класса BootReceiver, насколько это безопасно? - person Skynet; 21.01.2014
comment
Приложение вылетает после перезагрузки. - person Skynet; 21.01.2014