一次-对于长期通知的AlarmManager?

问题描述 投票:0回答:1

我见过类似的问题,但没有合适或正确的答案,有些甚至是矛盾的。

问题很简单:alarmManager不能长时间(超过几个小时)工作吗?

我有一个具有消息数组的应用。第一次运行时,每个msg都会获得一个个人计时(Calendar obj),该应用会为每个msg设置一个alarmManager并将其全部保存在sharedPrefference中。即使我将设备重新启动了几个小时(由于sharedPref),然后停止发送通知,下面的代码(我只复制了相关的代码)仍然可以正常工作。

如果我将整个味精时间设置为短期(让我们说:10味精,每5分钟1个),则效果很好,并且它们都已发送。但是,如果我将其安排为每小时进行一次,则它仅在前2-3个小时内有效。

[我看过一些答案说,alarmManager不适合lomg术语,而其他答案说,这是它的完美服务:(有人可以给我一个专业的答案吗?

我也尝试过alarmManager.setAlarmClock()和setExactAndAllowWhileIdle(),但结果相同。

*

消息活动

// somewhere at the code:
createNotificationChannel ();
myMsg.msgAddTimes (); // adding Calendar for each msg
addAlerts (myMsg); // add alerts for each msg


private void addAlerts (MyMsg myMsg) {
        MyReceiver rc = new MyReceiver ();

        for (int i = 1; i < myMsg.totalMsgNum; i++)
            rc.setSingleNotifications (this, myMsg.msg[i]);
   }


 private void createNotificationChannel () {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            CharSequence name = "myMessagesApp";
            String description = "daily alert";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel (CHANNEL_ID, name, importance);
            channel.setDescription (description);

            NotificationManager notificationManager = getSystemService (NotificationManager.class);
            notificationManager.createNotificationChannel (channel);
        }
    }

MyReciever.java

public class MyReceiver extends BroadcastReceiver {

    final String CHANNEL_ID = "777";
    SharedPreferences pref;
    SharedPreferences.Editor editor;


    @RequiresApi (api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onReceive (Context context, Intent intent)
    {
        // get the relevant content
        pref = context.getSharedPreferences ("SAVED_FILE", Context.MODE_PRIVATE);

        int atMsgNum = pref.getInt ("CURRENT", 1);

        String json = pref.getString ("MSG_OBJ", "");
        Gson gson = new Gson ();
        MyMsg myMsg = gson.fromJson (json, MyMsg.class);

        String titleStr = myMsg.msg [atMsgNum].title;
        String contentStr = myMsg.msg [atMsgNum].msg;

        atMsgNum++;


        // update current msg num
        editor =  pref.edit ();
        editor.putInt ("CURRENT", atMsgNum);
        editor.commit ();


        // intent for showing the msg activity
        intent.setClass (context, OnPressTipNotificationActivity.class);
        intent.putExtra ("ID", atMsgNum);
        intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);


        // notification
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addNextIntentWithParentStack(intent);

        PendingIntent pendingIntent =  stackBuilder.getPendingIntent(atMsgNum, 0);

        NotificationCompat.Builder builder;

        builder = new NotificationCompat.Builder (context, CHANNEL_ID)
                .setSmallIcon (R.drawable.single_pics_logo)
                .setContentTitle (titleStr)
                .setContentText (contentStr)
                .setStyle (new NotificationCompat.BigTextStyle ()
                        .bigText (contentStr))
                .setPriority (NotificationCompat.PRIORITY_HIGH)
                .setContentIntent (pendingIntent)
                .setAutoCancel (true)
                .setBadgeIconType (NotificationCompat.BADGE_ICON_SMALL)
                .setVisibility (NotificationCompat.VISIBILITY_PUBLIC); 

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from (context);
        notificationManager.notify (atMsgNum, builder.build ());
    }


    public void setSingleNotifications (Context context, Msg msg) {


        Intent intent = new Intent (context, MyReceiver.class);

        PendingIntent alarmIntent = PendingIntent.getBroadcast (context, msg.num, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        Calendar calendar = Calendar.getInstance ();
        calendar.setTimeInMillis (System.currentTimeMillis ());
        calendar.set (Calendar.YEAR, msg.calendar.get (Calendar.YEAR));
        calendar.set (Calendar.MONTH, msg.calendar.get (Calendar.MONTH));
        calendar.set (Calendar.DAY_OF_MONTH, msg.calendar.get (Calendar.DAY_OF_MONTH));
        calendar.set (Calendar.HOUR_OF_DAY, msg.calendar.get (Calendar.HOUR_OF_DAY));
        calendar.set (Calendar.MINUTE, msg.calendar.get (Calendar.MINUTE));
        calendar.set (Calendar.SECOND, msg.calendar.get (Calendar.SECOND));
        calendar.add (Calendar.SECOND, 1);

        AlarmManager alarmManager = (AlarmManager) context.getSystemService (ALARM_SERVICE);
        alarmManager.set (AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis (), alarmIntent);


    }
}

清单包括:


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

android:excludeFromRecents="true"

<receiver
            android:name=".MyReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />

                <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
                <action android:name="android.media.action.DISPLAY_NOTIFICATION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
</receiver>
android broadcastreceiver alarmmanager
1个回答
0
投票

[好吧,经过长时间的挖掘,我想我明白了。它现在可以工作,并且在重新启动后,通知又回来了。

我在这里发布我的代码,首先是给寻求解决方案的任何人,其次-我想听听您的意见-如果我做对了,等等。Tnx

消息活动

private void addAlerts (MyMsg myMsg) {
        MyReceiver rc = new MyReceiver ();

        for (int i = 1; i < myMsg.totalMsgNum; i++)
            rc.setSingleNotifications (this, myMsg.msg[i]);
}

MyReciever.java

public class MyReceiver extends BroadcastReceiver {

    final String CHANNEL_ID = "777";
    SharedPreferences pref;
    SharedPreferences.Editor editor;


    @Override
    public void onReceive (Context context, Intent intent) {

            // get the relevant content
            pref = context.getSharedPreferences ("SAVED_FILE", Context.MODE_PRIVATE);

            int atMsgNum = pref.getInt ("CURRENT", 1);

            String json = pref.getString ("USER_OBJ", "");
            Gson gson = new Gson ();
            User user = gson.fromJson (json, User.class);

            String titleStr = user.msg[atMsgNum].title;
            String contentStr = user.msg[atMsgNum].msg;


            // update current msg num
            editor = pref.edit ();
            editor.putInt ("CURRENT", atMsgNum + 1);
            editor.commit ();


            // intent for showing the msg activity
            intent.setClass (context, OnPressNotificationActivity.class);
            intent.putExtra ("ID", atMsgNum);
            intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);


            // notification
            createNotificationChannel (context);

            TaskStackBuilder stackBuilder = TaskStackBuilder.create (context);
            stackBuilder.addNextIntentWithParentStack (intent);

            PendingIntent pendingIntent = stackBuilder.getPendingIntent (atMsgNum, 0);

            NotificationCompat.Builder builder;

            builder = new NotificationCompat.Builder (context, CHANNEL_ID)
                    .setSmallIcon (R.drawable.single_pics_logo)
                    .setContentTitle (titleStr)
                    .setContentText (contentStr)
                    .setStyle (new NotificationCompat.BigTextStyle ()
                            .bigText (contentStr))
                    .setPriority (NotificationCompat.PRIORITY_HIGH)
                    .setContentIntent (pendingIntent)
                    .setAutoCancel (true)
                    .setBadgeIconType (NotificationCompat.BADGE_ICON_SMALL)
                    .setVisibility (NotificationCompat.VISIBILITY_PUBLIC); 

            NotificationManagerCompat notificationManager = NotificationManagerCompat.from (context);
            notificationManager.notify (atMsgNum, builder.build ());
        }



    public void setSingleNotifications (Context context, Msg msg) {


        Intent intent = new Intent (context, MyReceiver.class);

        PendingIntent alarmIntent = PendingIntent.getBroadcast (context, msg.num, intent, PendingIntent.FLAG_UPDATE_CURRENT);


        Calendar calendar = Calendar.getInstance ();
        calendar.setTimeInMillis (System.currentTimeMillis ());
        calendar.set (Calendar.YEAR, msg.calendar.get (Calendar.YEAR));
        calendar.set (Calendar.MONTH, msg.calendar.get (Calendar.MONTH));
        calendar.set (Calendar.DAY_OF_MONTH, msg.calendar.get (Calendar.DAY_OF_MONTH));
        calendar.set (Calendar.HOUR_OF_DAY, msg.calendar.get (Calendar.HOUR_OF_DAY));
        calendar.set (Calendar.MINUTE, msg.calendar.get (Calendar.MINUTE));
        calendar.set (Calendar.SECOND, msg.calendar.get (Calendar.SECOND));
        calendar.add (Calendar.SECOND, 2);

        AlarmManager alarmManager = (AlarmManager) context.getSystemService (ALARM_SERVICE);


       AlarmManager.AlarmClockInfo almInfo = new AlarmManager.AlarmClockInfo (calendar.getTimeInMillis (), null);

        alarmManager.setAlarmClock (almInfo, alarmIntent);
    }



    private void createNotificationChannel (Context context) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            CharSequence name = "myMsgApp";
            String description = "daily alert";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel (CHANNEL_ID, name, importance);
            channel.setDescription (description);

            NotificationManager notificationManager = context.getSystemService (NotificationManager.class);
            notificationManager.createNotificationChannel (channel);
        }
    }
}

RestartReceiver.java //用于重新启动

public class RestartReceiver extends BroadcastReceiver {


    @Override
    public void onReceive (Context context, Intent intent) { // restarts alarms only when device restart

        if (intent.getAction ().equals ("android.intent.action.BOOT_COMPLETED")) {

            SharedPreferences sharedPreferences = context.getSharedPreferences ("SAVED_FILE", context.MODE_PRIVATE);
            String json = sharedPreferences.getString ("USER_OBJ", "");

            Intent in = new Intent (context, RestartService.class);
            in.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); // ??
            in.putExtra ("JSON_STRING", json);
            in.putExtra ("CURRENT", sharedPreferences.getInt ("CURRENT", 1));


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                context.startForegroundService (in);
            else
                context.startService (in);
        }
    }
}

RestartService.java

public class RestartService extends IntentService {


    public RestartService () {
        super ("RestartService");
    }

    public RestartService (String name) {
        super (name);
    }

    @Override
    protected void onHandleIntent (@Nullable Intent intent) {

        String json = intent.getExtras ().getString ("JSON_STRING", "");
        Gson gson = new Gson ();
        User user = gson.fromJson (json, User.class);
        user.atMsgNum = intent.getExtras ().getInt ("CURRENT", 1);

        MyReceiver rc = new MyReceiver ();

        for (int i = user.atMsgNum; i < user.totalMsgNum; i++)
            rc.setSingleNotifications (this, user.msg [i]);
    }
}

AndroidManifest包括:

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

<receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
                <action android:name="android.media.action.DISPLAY_NOTIFICATION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <receiver
            android:name=".RestartReceiver"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service android:name="myPackageName.RestartService"
            android:exported="false"/>


© www.soinside.com 2019 - 2024. All rights reserved.