重新启动设备后,频繁发送短信也会在打开时再发送短信

我经常发送短信,同时重新启动我的设备再发送短信,同时我们“开启”。之后发送短信正确的间隔。但是当我们打开我们的设备时再发送短信。

public class BootCompletedIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context ctxt, Intent i) { try { scheduleAlarms(ctxt); } catch (java.text.ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @SuppressLint("SimpleDateFormat") static void scheduleAlarms(Context ctxt) throws java.text.ParseException { String share_pref_file = "IMS"; SharedPreferences prefs = ctxt.getSharedPreferences(share_pref_file, Context.MODE_PRIVATE); String number = prefs.getString("extraSmsNumber", ""); String message= prefs.getString("extraSmsText", ""); String mytime = prefs.getString("Mytime", ""); int year= prefs.getInt("Year", 0); int month= prefs.getInt("Month", 0); int dmonth= prefs.getInt("DMonth", 0); int hour= prefs.getInt("Hour", 0); int time= prefs.getInt("Time", 0); String nyear = String.valueOf(year); String nmonth = String.valueOf(month); String ndmonth = String.valueOf(dmonth); String nhour = String.valueOf(hour); String ntime = String.valueOf(time); //int tottime = dmonth + month + year + hour + time; String newtime = ndmonth + "-" + nmonth + "-" + nyear + "/" + nhour + ":" + ntime; SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy/hh:mm"); Date startDate=null; try { startDate = df.parse(newtime); String newDateString = df.format(startDate); } catch (ParseException e) { e.printStackTrace(); } AlarmManager alarmManager = (AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE); Intent i=new Intent(ctxt, MyAlarmService.class); PendingIntent pendingIntent=PendingIntent.getService(ctxt, 0, i, 0); SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy/hh:mm"); //SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/YYYY/HH:mm"); String currentLocalTime =sdf.format(new Date()); Date startTDate = null; try { startTDate = sdf.parse(currentLocalTime); String newDateString = df.format(startTDate); System.out.println(newDateString); } catch (ParseException e) { e.printStackTrace(); } if(startDate.compareTo(startTDate) < 0) { Toast.makeText( ctxt, "Welcome", Toast.LENGTH_LONG).show(); } if (mytime.equals("Once")) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } else if (mytime.equals("Every 5 Minutes")) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 5, pendingIntent); // Millisec * Second * // Minute } else if (mytime.equals("Every hour")) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60, pendingIntent); // Millisec * Second * // Minute } else if (mytime.equals("Every day")) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent); } else if (mytime.equals("Weekly")) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 7 * 24 * 60 * 60 * 1000, pendingIntent); } else if (mytime.equals("Weekdays(Mon-Fri)")) { forWeekdays(ctxt, year, month, dmonth, hour, time); } else if (mytime.equals("Weekend")) { forWeekend(ctxt, year, month, dmonth, hour, time); } else if (mytime.equals("Every month")) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 30 * 24 * 60 * 60 * 1000, pendingIntent); } else { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dmonth, hour, time, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 365 * 24 * 60 * 60 * 1000, pendingIntent); } } 

这是我的服务类

 public void onStart(Intent intent, int startId) { super.onStart(intent, startId); String share_pref_file = "IMS"; SharedPreferences prefs = getSharedPreferences(share_pref_file, Context.MODE_PRIVATE); String number = prefs.getString("extraSmsNumber", ""); String message = prefs.getString("extraSmsText", ""); Toast.makeText(this, "MyAlarmService.onStart()", Toast.LENGTH_LONG) .show(); Toast.makeText( this, "MyAlarmService.onStart() with \n" + "smsNumberToSend = " + number + "\n" + "smsTextToSend = " + message, Toast.LENGTH_LONG).show(); SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage(number, null, message, null, null); } 

发生错误是在我们打开时再发送一个短信

如果我每隔5分钟发送一次短信,我在5.0时钟开始发送5.00和5.05然后我在5.07关闭我的设备并在5.08开启,这样5.08也发送短信,然后它继续像5.01,5.15一样发送短信。只有5.08发送短信是问题所在。

重新启动一次后,服务类自动启动。

重新启动一次后,服务类自动启动。

许多用户在此问题上发布了很多问题“重新启动后服务自动启动”。

作为一个解决方案,他们中许多人建议使用START_NOT_STICKY返回值onStartCommand()方法(它可能适用于许多人,但不适合我)。

注意:它适用于较低版本的android 2.3.3和3.0,但不适用于4.0及更高版本。

在分析了bit之后,知道startID似乎在自动启动时和用户调用时给出了不同的值。

所以对我来说startID起了作用

 @Override public int onStartCommand(Intent intent, int flags, int startId) { if(startId!=2) { //to do } return super.onStartCommand(intent, flags, startId); } 

并且即使重新启动后也可以跟踪您的时间

我不确定android是否提供用于跟踪时间的API,但它可以通过简单的数学计算来实现。

为此,您需要跟踪Alarm上次触发的时间(使用sharedpreference存储日期/时间,以毫秒为单位)。

 long lastInvoked = preferences.getLong(AndroidAlarmSMS.LASTALARAMINVOKED, -1); Log.d("last_time_invoked",""+lastInvoked); long currentTime = System.currentTimeMillis(); long period = 1000*60*5; // using 5 min of interval to repeat long diff = currentTime - lastInvoked; Log.d("difference",""+diff); if(diff > period) { long result= diff % period; long nextInvokeAt; if(result > period) { nextInvokeAt = currentTime + (result - result); } else{ nextInvokeAt = currentTime + (period - result); } Log.d("invoked_next_time",""+nextInvokeAt); setPendingIntent(context,nextInvokeAt,period); } else { long result= period-diff; long nextInvokeAt = currentTime + result; Log.d("next_time_invoked_else",""+nextInvokeAt); setPendingIntent(context,nextInvokeAt,period); } 

并在您的广播接收器类中执行上述操作以执行操作“BOOT_COMPLETED”,并使用生成的时间设置警报

 public static void setPendingIntent(Context ctx,long time,long period){ AlarmManager alarmManager= (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE); Intent myIntent = new Intent(ctx, MyAlarmService.class); PendingIntent pendingIntent = PendingIntent.getService(ctx, 0, myIntent, 0); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time, period , pendingIntent); Toast.makeText(ctx, "repeating --> "+time, Toast.LENGTH_LONG).show(); } 

注意:这不是解决此问题的标准答案,但暂时对我有用,希望它可以帮助您解决此问题。

注意:寻找更好的答案……

嗨Karthi只看看这段代码:

启动设备5分钟后,准确启动服务

 Calendar cal = Calendar.getInstance(); // Start 5 minutes after boot completed cal.add(Calendar.MINUTE, 5); alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), REPEAT_TIME, pendingIntent); 

这里在此cal.getTimeInMillis()时间之前不会触发警报

另外通过这个void android.app.AlarmManager.setInexactRepeating(int类型,long triggerAtMillis,long intervalMillis,PendingIntent操作)

 Just Remove this permission from manifest.xml  and also remove     from  Tag in manifest.xml