Android AlarmManager在重启后继续/从RecentTaskManager中删除

pea*_*mak 5 notifications android alarmmanager intentservice

我想在用户预先设置之前使用AlarmManager从服务器向用户发送通知.代码如下:

主要活动:

public void set_Retrival_then_notifcation_Alarm(Context context, int year, int month, int day, int hour, int min, int sec) 
    {
        Calendar updateTime = Calendar.getInstance();
        updateTime.setTimeZone(TimeZone.getDefault());
        updateTime.set(Calendar.YEAR, year);
        updateTime.set(Calendar.MONTH, month-1);
        updateTime.set(Calendar.DATE, day);
        updateTime.set(Calendar.HOUR_OF_DAY, hour);
        updateTime.set(Calendar.MINUTE, min);
        updateTime.set(Calendar.SECOND, sec);
        Intent downloader = new Intent(context, AlarmBroadcastReceiver.class);
        downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);           
        alarmManager.set(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), pendingIntent);                        
    }
Run Code Online (Sandbox Code Playgroud)

ParseService:

public class ParseService extends IntentService 
{
    static String Parse_AppID = "abc";  
    static String Parse_ClientKey = "abckey";
    String notification_next_price = "";
    String notification_next_date = "";
    SharedPreferences settings;

    public class LocalBinder extends Binder 
    {
        public ParseService getService() 
        {
            return ParseService.this;
        }
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent,flags,startId);
        return START_STICKY ;
    }

    @Override
    protected void onHandleIntent(Intent intent) 
    {
        Log.d("MyService", "About to execute MyTask");
        new MyTask().execute();
    }

    private class MyTask extends AsyncTask<String, Void, Boolean> 
    {
        @Override
        protected Boolean doInBackground(String... strings) 
        {
            Log.d("MyService - MyTask", "Calling doInBackground within MyTask");
            initParse(ParseService.this);
            get_notification_info(ParseService.this);
            return false;
        }
    }

    private void sendNotification(Context context, String title, String content) 
    {
        Log.d("MyService - MyTask", "A - sendNotification");
        settings = context.getSharedPreferences("MyApp",0);
        boolean notify_is_on = settings.getBoolean("notify_is_on", true);
        int saved_amount = settings.getInt("saved_amount", 800);

        NumberFormat numberFormat = NumberFormat.getInstance();
        int k = 0;
        try
        {
            k = numberFormat.parse(notification_next_price).intValue();
            if (notify_is_on && (k >= (saved_amount*10000)))
            {
                setNotificationContent(context, k, ""+title, content + "");
            }
            else
            {
                Toast.makeText(getApplicationContext(), "No need notification", Toast.LENGTH_SHORT).show();
            }
        }
        catch (Exception ex)
        {
            setNotificationContent(context, k, "Title2", "Content2");
        }
    } 

    public void setNotificationContent(Context context, int k, String title, String content)
    {
        Intent notificationIntent = new Intent(context, CurrentResult.class);
        PendingIntent pi = PendingIntent.getActivity(context, 0, notificationIntent, 0);
        Notification noti = new Notification.Builder(context)
            .setTicker("Hello")
            .setSmallIcon(R.drawable.b06)
            .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher))
            .setAutoCancel(true)
            .setOngoing(true) 
            .setOnlyAlertOnce(true)
            .setContentTitle(""+title)
            .setContentText(""+content)
            .setContentIntent(pi)
         .build();

        startForeground(1337, noti);

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, noti);

        stopSelf();
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    public void initParse(Context context) 
    {
        try 
        {
            ...connection to Parse.com
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }

    public void get_notification_info(Context context)
    {       
        ParseQuery<ParseObject> query = ParseQuery.getQuery("Record_db");
        //....getting records from server
        sendNotification(ParseService.this, ""+notification_next_price, ""+notification_next_date);
                    }                   
                } 
                else 
                {
                    Toast.makeText(getApplicationContext(), "Getting server content error", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

AlarmBroadcastManager

public class AlarmBroadcastReceiver extends BroadcastReceiver 
{
    public AlarmBroadcastReceiver () {
    }

    @Override
     public void onReceive(Context context, Intent intent) 
     {
         Intent dailyUpdater = new Intent(context, ParseService.class); 
         context.startService(dailyUpdater);
         Log.d("AlarmReceiver", "Called context.startService from AlarmReceiver.onReceive");
     }
}
Run Code Online (Sandbox Code Playgroud)

表现:

<service android:name="com.abc.abc.ParseService" 
                android:enabled="true"
                android:exported="true" />
        <receiver 
            android:name="com.abc.abc.AlarmBroadcastReceiver"
            android:enabled="true"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>         
Run Code Online (Sandbox Code Playgroud)

题:

当应用程序位于最近的任务列表中时,从服务器获取记录并发送到通知正常工作.

但是,如果从最近的任务列表中手动删除应用程序,则会取消alarmManager并因此取消通知,从而不会收到通知.

我用Google搜索和大多数解决方案都返回START_STICKYonStartCommand,在清单登记,但我没有成功尝试.

你能帮忙看看问题是什么吗?为什么在从最近的任务列表中手动删除应用程序后无法重新启动通知?有没有这样的例子,这ParseService是在用户的预设时间?

谢谢!

Hos*_*laa 5

  • 您需要将注册的警报存储在本地数据库中
  • 然后创建一个启动时完成的接收器
    • 在此接收器中加载所有警报并再次注册它们
  • 在 AlarmBroadcastReceiver 类中从数据库中删除此警报

就是这样