AlarmManager not taking more than one queue Android - java

I just recently started to mess with the alarm manager, and I figured out most of it, but right now its starting to be a bit annoying. So, right now I have it set up with a date and time picker, you type in the date and time and it will pop up a toast message when that times comes, but it seems like it will only take one alarm and any other ones I set get destroyed. Is this something the alarm manager does by itself, or is there something I am missing. Here is my code for my main class, the other is just a broadcast receiver with a toast message in it, so I won't post it.
public class TextScheduler extends ListActivity {
protected Toast mToast;
TimePicker time;
DatePicker date;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(setTime);
time = (TimePicker) this.findViewById(R.id.timePicker1);
date = (DatePicker) this.findViewById(R.id.datePicker1);
}
private OnClickListener setTime = new OnClickListener() {
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
cal.set(date.getYear(), date.getMonth(), date.getDayOfMonth(), time.getCurrentHour(), time.getCurrentMinute());
Intent intent = new Intent(TextScheduler.this, AReceiver.class);
intent.putExtra("caldata", "hooray!!");
PendingIntent sender = PendingIntent.getBroadcast(TextScheduler.this, 1234567, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}
};
}
Let me know if you need any more info, thanks in advance!
WWaldo

AlarmManager compares PendingIntents to see if it already exits. Just change the ID (in your case 1234567), and it will allow you to create additional alarms: one per ID.

Related

How to remember score after app has been restarted?

I am making a two player game where I am able to have a rematch. I am also keeping track of the scores of each player. This is what my code for a rematch looks like:
public void rematch(View view) {
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(i);
}
The above code is called when the user clicks a rematch button. I basically just restart the application because it's easier than resetting all the variables I have. Anyways, to keep track of the scores, I am overriding the onStop() method like this:
#Override
protected void onStop() {
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(SCORES_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("scoreOne", p1Score);
editor.putInt("scoreTwo", p2Score);
editor.commit();
}
I am using shared preferences. Then, in my onCreate method, I get these shared preferences like this:
// Remember scores from previous games
SharedPreferences settings = getSharedPreferences(SCORES_NAME, 0);
p1Score = settings.getInt("scoreOne", 0);
p2Score = settings.getInt("scoreTwo", 0);
updateScores();
SCORES_NAME is
public static final String SCORES_NAME = "MyScores";
This all isn't working. My scores after the game restarts are always back to 0. I was thinking of putting extras onto the intent in rematch() but I'm not sure how to access this intent in my onCreate() method. Any help is greatly appreciated!
You need to override onSaveInstanceState(Bundle savedInstanceState) and write the application state values you want to change to the Bundle parameter like this:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putInt("scoreOne", p1Score);
savedInstanceState.putInt("scoreTwo", p2Score);
// etc.
}
The Bundle is essentially a way of storing a NVP ("Name-Value Pair") map, and it will get passed in to onCreate() and also onRestoreInstanceState() where you'd extract the values like this:
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
int p1Score = settings.getInt("scoreOne", 0);
int p2Score = settings.getInt("scoreTwo", 0);
}
You would usually use this technique to store instance values for your application (selections, unsaved text, etc.).
Problem here is that you made the assumption that the new activity's onCreate() will be called after your first activity's onStop() has completed execution.
That's probably not an assumption you want to make, because they are two not completely related things.
Send the values you need to the newly created activity in the intent
public void rematch(View view) {
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Those next values will be there for sure in the new activity.
i.putExtra("scoreOne", p1Score);
i.putExtra("scoreTwo", p2Score);
finish();
startActivity(i);
}
And in the onCreate of your Activity can extract those values as follows
public void onCreate(Bundle savedInstance) {
super.onCreate();
..
int p1Score = getIntent().getIntExtra("scoreOne", 0);
int p2Score = getIntent().getIntExtra("scoreTwo", 0);
}
You need to take the code from onStop and execute it before your call to finish() from the rematch method. Like this:
private void saveScores() {
SharedPreferences settings = getSharedPreferences(SCORES_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("scoreOne", p1Score);
editor.putInt("scoreTwo", p2Score);
editor.commit();
}
And then call this function from rematch:
(...)
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
saveScores();
finish();
startActivity(i);
However, #elmorabea's solution is better is you are now only using SharedPreferences to pass values between activities.

How to set specific time in Toast?

Can I display a toast message based on user's current time?
I need to make an app, Where when I open the screen from 1:00 am to 11:00 am it will display the toast message "Good morning" whereas if I open the screen at 6:00 pm to 11:00 pm it will display the toast "good night"
public class ToastDisplay extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
Toast.makeText(context,"Good Morning",Toast.LENGTH_SHORT).show();
}
}
}
What you can do i use Calendar class to get the current time. Check the time and display the toast accordingly.
Calendar currentTime = Calender.getInstance();
int hour = currentTime.get(Calendar.HOUR_OF_DAY);
if(Use your condition here) {
Display toast
} else if(Use your other condition) {
Display toast
}
Just a note, your hour would be in 24 hour format so you need to check keeping that in mind.
int toastDurationInMilliSeconds = 10000;
Toast.LENGTH_SHORT is int, so you have to declare new int

Change an image according to time of day

I want the functionality of Google Now app, like when it's day time, the header is a sunny image, when it becomes noon or sundown, the image changes to a sundown image, when it's night the image changes to a night image, and same for the morning one.
I'm trying to implement my background which does this very same thing, how must I go about implementing this? I've searched up on this but the answers are for html and website development.
And most of the others are based on time interval and I think that's what I should use but I would like something like this. Written in non-tech language
01:00/1am - Morning - Image changes to Morning.png on the imageview (R.id.view).
09:00/9am - Normal - Image changes to Daytime.png on the imageview (R.id.view).
12:00/12pm - Noon - Image changes to Noon.png on the imageview (R.id.view).
19:00/7pm - Night - Image changes to Noon.png on the imageview (R.id.view).
How I can achieve something similar to this?
Well the best candidate for this job is an AlarmManager!
Lets assume you only need to change the background when your Activity is running.
You can set up your alarm when you Create your Activity:
private PendingIntent pi=null;
private AlarmManager mgr=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mgr=(AlarmManager)getSystemService(ALARM_SERVICE);
pi=createPendingResult(ALARM_ID, new Intent(), 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
PERIOD (ms) is how often we want to get control (onActivityResult). The createPendingResult(ALARM_ID, new Intent(), 0); line creates an Intent that can be caught in your Activities onActivityResult method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ALARM_ID) {
// This is where you check the time and change your background!
}
}
You also need to cancel your alarm in onDestroy:
#Override
public void onDestroy() {
mgr.cancel(pi);
super.onDestroy();
}
To check if a Date is in a specific interval you can use:
boolean isWithinRange(Date testDate) {
return testDate.getTime() >= startDate.getTime() &&
testDate.getTime() <= endDate.getTime();
}
I advice you write a class which has a listen method. This listen method which checks time and raises a custom event (you can use interface here) on Activity level must be called periodically. You can use Timer and TimerTask or CountdownTimer to call.

Listening for onActivityResault in View.OnCLickListener

So the problem is the following:
I'm generating a contentView in code with multiple for and foreach loops and have all of the listeners for buttons generated dynamically. But if I want to make changes in some TextView or something, I start a new Activity, and I want to listen for on onActivityResult inside a listener.
I'm wondering if that's even possible and I could really use some help.
Here's my code:
Button goliButton = new Button(this);
goliButton.setText("+");
goliButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(TekmaLive.this,DodajStrel.class);
i.putExtra("MINUTA", currTime /1000 + cetrtina * 15 * 60);
i.putExtra("TEKMA", tekmaId);
i.putExtra("IGRALKA", Integer.parseInt(igralka[0]));
i.putExtra("GOL", true);
TekmaLive.this.startActivity(i);
//Insted of startActivity I would use startActivityForResult...
}
});
You cannot have the method "wait" for the activity to return its result, if that's why you're asking, startActivity() is asynchronous. However, you can achieve the same by "remembering" which button fired the event, i.e. by having a variable (pressedButton) in your activity referencing it.
final Button goliButton = new Button(this); // <---
goliButton.setText("+");
goliButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(TekmaLive.this,DodajStrel.class);
i.putExtra("MINUTA", currTime /1000 + cetrtina * 15 * 60);
i.putExtra("TEKMA", tekmaId);
i.putExtra("IGRALKA", Integer.parseInt(igralka[0]));
i.putExtra("GOL", true);
TekmaLive.this.pressedButton = goliButton; // <---
TekmaLive.this.startActivityForResult(i, YOUR_REQUEST_CODE); // <---
}
});
then just read pressedButton in onActivityResult().
Also, you should use startActivityForResult() instead of startActivity() so that onActivityResult() is called afterwards.
I see that in your code you are using startActivity. You should use startActivityForResult if you want a result back.
onActivityResult is a method that belongs to an Activity or a Fragment. If you call startActivityForResult from an Activity the corresponding onActivityResult of that activity instance will be called, when your child activity calls the finish method.
What you can do in your case is to have your activity implement View.OnClickListener. This way your result will return in the listener.

Save and open a TimerTime in the Preferences

I'm currently working on a small Android game. In the options menu you can select the time you wish to play, either 15, 30 or 45 seconds. I have a countdown timer that loads these values. Now on my onPause, I want to save the current time and then onResume proceed from that time.
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
int cTime = Integer.valueOf(sharedPrefs.getString("playTimePref", null));
TimerTime = cTime;
timer = new CountDownTimer(TimerTime, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("Seconds Remaining: " + millisUntilFinished/ 1000);
TimerTime = (int) millisUntilFinished;
}
protected void onPause() {
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putString("playTimePref", "TimerTime");
timer.cancel();
}
I thought this would work. If I'm correct I save the current TimerTime in the playTimePref string at onPause, and open that on onResume. But everytime I recall the app, the time resets to its original time. Hope someone can help.
this method
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
will create the shared preference with your package name (com.xxx.xxx) and will be accessible by all activities you have.
but this method
getPreferences(MODE_PRIVATE)
will create shared Preference with your activity name (MainActivity) and it will be accessible only with your activity because your assign private mode for it , so as you can see you try to save your data in sharedPref and try to access the values from another one , that's why it return null for you
another comment on your code , you can use save time of casting string to int by using strong type mehod
Editor.putInt("Key" , timenumber);
hope it help you

Categories