一次报警不起作用

时间:2014-05-05 11:18:55

标签: android notifications android-alarms

我做了一些研究,并尝试实施一次性警报,向用户发送通知,但由于某种原因我无法理解,当时机成熟时,警报未被激活。我认为onReceive方法没有被调用,但我不知道为什么,因为它是我第一次尝试实现警报。

===编辑:似乎警报的onReceive正在起作用,我收到了祝酒消息"警报!!"在合适的时间(不知道为什么它在我第一次测试时没有),但没有收到通知,但是......有任何线索吗?

这是Alarm类的代码:

public class Alarm extends BroadcastReceiver {

    public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        // send notification

        Toast.makeText(context, "Alarm!!", Toast.LENGTH_SHORT).show();

        // API < 16 so have to use compat
        NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context)
            .setContentTitle(context.getResources().getString(R.string.memo_test_ready))
            .setContentText(context.getResources().getString(R.string.click_to_start));

        Intent resultIntent = new Intent(context, UpcomingTest.class);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addParentStack(UpcomingTest.class);
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(
                    0,
                    PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager =
            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(123, mBuilder.build());

    }

    public void Set(Context context)
    {
        DatabaseHandler db = new DatabaseHandler(context);
        MemoryTestLevel memoTestLevel = new MemoryTestLevel();
        long timeInterval;
        long memoryTest_dateTime;

        String alarmMemoLevel;
        List<Phrase> studyPhrasesList = db.getPhrasesWithState(Phrase.START_STUDYING);
        if (studyPhrasesList.size() > 0 ){ // if there are any phrases here, update them; dateTime == level 1
            alarmMemoLevel = "Level 1 ";
            memoTestLevel = db.getMemoryTestLevelWithLevel(MemoryTestLevel.LEVEL_1);
            timeInterval = memoTestLevel.getTimeInterval();
            TestDateTimeCalculator datetimeCalc = new TestDateTimeCalculator();
            memoryTest_dateTime = datetimeCalc.calculate(timeInterval);
            for(Phrase phrase : studyPhrasesList){  
                phrase.setMemoryTestPending(memoTestLevel.getMemoryTest_id(), memoryTest_dateTime);
                db.updatePhrase(phrase);
            }
        } else {
            // if there are no phrases to be set at level 1, then get the lowest memoTest_datime of
            // the ones that are pending
            alarmMemoLevel = "next after L1 ";
            memoryTest_dateTime = db.getLowestMemoTestDateTime();
        }
        /* 2. Set new Alarm
         * 2.1. Determine which phrases will go into this new alarm */
        List<Phrase> nextMemoryTestPhrases = db.getNextMemoryTestPhrases(memoryTest_dateTime);

        for(Phrase phrase : nextMemoryTestPhrases) {
            phrase.setState(Phrase.MEMORY_TEST_SCHEDULED);
            db.updatePhrase(phrase);
        }
        // 2.3 set alarm for required dateTime
        AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, Alarm.class);
        PendingIntent pendingInt = PendingIntent.getBroadcast(context, 0, intent, 0);
        alarmMgr.set(AlarmManager.RTC_WAKEUP, memoryTest_dateTime, pendingInt);

        // 2.4 save the alarm.dateTime in the preferences so it can be used in the "upcoming test" activity

        SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
        Editor editor = preferences.edit();
        editor.putLong("NEXT_TEST_DATETIME", memoryTest_dateTime);
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(memoryTest_dateTime);
        String nextTestDateStr = sdf.format(calendar.getTime());
        Toast.makeText(context, "Alarm set to " + alarmMemoLevel + nextTestDateStr, Toast.LENGTH_LONG).show();
        editor.commit();

    }

    public void Cancel(Context context)
    {
        Intent intent = new Intent(context, MyBroadcastReceiver.class);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(sender);
    }
}

我有一个广播接收器,以防手机重启:

public class MyBroadcastReceiver extends BroadcastReceiver {

public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;

@Override
public void onReceive(Context context, Intent intent) {
    // TODO setup alarm again (get datetime from system)
    Alarm alarm = new Alarm();
    if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
    {
        SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
        long nextTestDateInMillis = preferences.getLong("NEXT_TEST_DATETIME", 0);
            if(nextTestDateInMillis > 0){
            alarm.Set(context);
        }
    }

}

}

从我发现的研究中,我的清单中似乎缺少/错误。这就是我在那里:

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

以下是申请内容:

<receiver android:name="liliana.phrasememo.util.MyBroadcastReceiver">  
    <intent-filter>  
        <action android:name="android.intent.action.BOOT_COMPLETED" />  
    </intent-filter>  
</receiver>
<receiver android:process=":remote" android:name="liliana.phrasememo.util.Alarm"/>

另外,如果您在我的警报+通知实施中看到其他任何错误,那么让我头脑清醒是很棒的。非常感谢你: - )

2 个答案:

答案 0 :(得分:0)

设置闹钟可能是这段代码可以帮助你

   Intent myIntent = new Intent(yourcontext, Alarm.class);
   PendingIntent pendingIntent = PendingIntent.getService(act, 0, myIntent, 0);
   AlarmManager alarmManager = (AlarmManager)act.getSystemService(act.ALARM_SERVICE);
   Calendar calendar = Calendar.getInstance();
   calendar.set(Calendar.HOUR_OF_DAY, 8);
   calendar.set(Calendar.MINUTE,22);
   calendar.set(Calendar.SECOND, 0);


   alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

你也必须实现服务而不是broadcastreciever才能在闹钟时间运行

答案 1 :(得分:0)

非常感谢回答发布的here,我的代码中缺少的是通知图标,我已添加如下:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(context)
        .setSmallIcon(R.drawable.ic_launcher) // this was missing
        .setContentTitle(context.getResources().getString(R.string.memo_test_ready))
        .setContentText(context.getResources().getString(R.string.click_to_start));

事实上,如果我们查看documentation,它会指定小图标必须位于通知中:

Required notification contents

A Notification object must contain the following:

A small icon, set by setSmallIcon()
A title, set by setContentTitle()
Detail text, set by setContentText()

LogCat确实找不到文件错误:

05-05 12:39:39.191: A/NetworkStats(89): Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)

但它不会造成任何崩溃,所以你可能没有意识到这一点。我不确定是否可以向通知构造函数本身添加任何内容,以便用户立即看到缺少某些内容。我没有非常先进的Java知识。