长期通知的AlarmManager - 它的工作原理

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

跳过我的回答

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

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

我有一个应用程序,它有一个消息数组。在第一次运行时,每个msg都会得到一个个人计时(Calendar obj),应用程序为每个msg设置一个alarmManager,并将所有的消息保存在sharedPrefference。下面的代码(当然我只复制了相关的代码)工作正常,即使我重启设备(感谢sharedPref)几个小时,然后停止发送通知。

如果我把整个msg时间设置为短期(比如说:10个msg,每5分钟1个),它的工作效果很好,而且都能发送。但如果我把它安排为每小时,它只在前2-3小时工作。

我看到一些答案说 alarmManager 不适合长期使用,而其他答案则说它是完美的服务 :( 谁能给我一个专业的答案?

我也试过 alarmManager.setAlarmClock()和setExactAndAllowWhileIdle(),但结果一样。

android broadcastreceiver alarmmanager
1个回答
0
投票

好了,经过长时间的挖掘,我想我弄明白了。现在可以用了,重启后,通知又回来了。

我把我的代码贴在这里,首先是为了任何人寻找解决方案,其次--我想听听你的意见--如果我做的对不对等等。Tnx

msg.activity

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);
        }
    }
}

重启接收机.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);
        }
    }
}

重新启动服务.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]);
    }
}

列表 包括:

<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.