Reputation: 21
So I'm new to android and I have developed a simple alarm clock app. Problem is that my alarms resets when I reboot my phone, so I created a receiver which starts at boot. This receiver is supposed to get my list of quickAlarms from my shared preference, loop through it and then send them to my AlarmService. The problem is that I am unable to get hold of the sharedPreference. I have tried these methods:
sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
sharedPref = context.getSharedPreferences("my_pref", Context.MODE_PRIVATE);
This is the broadcastReceiver called upon boot:
@Override
public void onReceive(Context context, Intent intent) {
Log.d("BootReceiver", "BootReceiver called");
sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
//sharedPref = context.getSharedPreferences("my_pref", Context.MODE_PRIVATE);
if(sharedPref.contains("alarm")){
Log.d("BootReceiver", "SharedPreference do contain alarms, trying to set them...");
alarmService= new AlarmService(context);
activate(context);
}else{
Log.d("BootReceiver", "SharedPreference does not contain any alarms.");
//I always get this message, so sharedPref never contains anything here!
}
}
/**
* Loops through the stored list of QuickAlarms, checks if the are set to on and then reshedules them.
* @param context
*/
public void activate(Context context) {
Gson gson = new Gson();
Type type = new TypeToken<List<QuickAlarm>>() {}.getType();
List<QuickAlarm> alarmList = gson.fromJson(sharedPref.getString("alarm", ""), type);
Iterator<QuickAlarm> alarmIterator = alarmList.iterator();
while(alarmIterator.hasNext()){
if(alarmIterator.next().isActive()){
alarmService.onHandleIntent(new Intent(context, AlarmReceiver.class).putExtra("time", alarmIterator.next().getTime()).setAction("CREATE").putExtra("repeat", alarmIterator.next().getRepeat()).putExtra("id" , alarmIterator.next().getID()).putExtra("desc", alarmIterator.next().getDesc()));
}
}
Log.d("BootReceiver", "All alarms are set again!");
}}
Here is the code in MainActivity were I declare the sharedpreference and use it in the Controller class:
private SharedPreferences sharedPref;
//...
sharedPref = this.getPreferences(Context.MODE_PRIVATE);
controller = new Controller(sharedPref, this.getApplicationContext());
Then it's really the Controller which use it:
public Controller(SharedPreferences sharedPref, Context context) {
this.context = context;
this.sharedPref = sharedPref;
editor = sharedPref.edit();
}
//...
public void addQuickAlarm(QuickAlarm qa, int id) {
Gson gson = new Gson();
Type type = new TypeToken<List<QuickAlarm>>() {
}.getType();
List<QuickAlarm> alarms;
if (gson.fromJson(sharedPref.getString("alarm", ""), type) == null) {
alarms = new ArrayList<>();
} else {
alarms = gson.fromJson(sharedPref.getString("alarm", ""), type);
}
if (id == -10) {
alarms.add(qa);
Log.d("Controller", "QuickAlarm added to pref");
} else {
alarms.remove(id);
alarms.add(id, qa);
Log.d("Controller", "QuickAlarm edited to pref");
}
String jsonAlarm = gson.toJson(alarms); //converting list to json and saving back
editor.putString("alarm", jsonAlarm);
editor.commit();
}
public void activateAlarm(boolean on, int id) {
Gson gson = new Gson();
Type type = new TypeToken<List<QuickAlarm>>() {
}.getType();
List<QuickAlarm> alarmList = gson.fromJson(sharedPref.getString("alarm", ""), type);
QuickAlarm qa = alarmList.get(id);
qa.setActive(on);
int[] repeat = qa.getRepeat();
addQuickAlarm(qa, id);
if (on) {
alarmService.onHandleIntent(new Intent(context, AlarmReceiver.class).putExtra("time", qa.getTime()).setAction("CREATE").putExtra("repeat", repeat).putExtra("id" , id).putExtra("desc", qa.getDesc()));
} else {
alarmService.onHandleIntent(new Intent(context, AlarmReceiver.class).putExtra("time", qa.getTime()).setAction("CANCEL").putExtra("id" , id));
}
}
Upvotes: 2
Views: 106
Reputation: 914
Unable to start receiver com.example.user.alarmclock.Local.StartMyServiceAtBootReceiver: java.util.NoSuchElementException
because after alarmIterator.next().isActive()
this you are calling another next()
like this alarmIterator.next().getTime()
which mean you are asking for List<QuickAlarm >
next item object(QuickAlarm
) which is not there so only you are getting the error. change your code to this because even you mean if
in this object(QuickAlarm
) isActive()
is true then pull other info from this object(QuickAlarm
) like getTime()
,getRepeat()
etc.
while(alarmIterator.hasNext()){
QuickAlarm qm=alarmIterator.next()
if(qm.isActive()){
alarmService.onHandleIntent(new Intent(context, AlarmReceiver.class).putExtra("time", qm.getTime()).setAction("CREATE").putExtra("repeat", qm.getRepeat()).putExtra("id" , qm.getID()).putExtra("desc", qm.getDesc()));
}
}
Upvotes: 1
Reputation: 914
you need to add the "alarm" key and its value to your sharedpreference when you are setting the alarm alert something like this
sharedPref = context.getSharedPreferences("my_pref", Context.MODE_PRIVATE);
or
sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor=sharedPref.edit();
editor.putString("alarm", "value u want to keep");
editor.commit();
Upvotes: 1