I need to return the value from my countdowntimer so I can update a textView. I'm not sure how I can do this, I've added a comment where I've tried adding a return but no luck.
public class BrewTimer extends Activity{
public String secsRemain = "not set";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("Timer Created, we're in the onCreate Method.");
}
public void startBrewTimer(long remaningMillis) {
// Start the Brew Timer
System.out.println("Timer object fired!");
new CountDownTimer(remaningMillis, 1000) {
public void onTick(long millisUntilFinished) {
secsRemain = "seconds remaining: " + millisUntilFinished / 1000;
System.out.println(secsRemain);
return secsRemain; // <-- This is what I want to do
}
public void onFinish() {
System.out.println("Timer Finished!!!");
}
}.start();
}
public void stopBrewTimer() {
//Stop the Brew Timer
}
}
I need to return the value from my countdowntimer so I can update a
textView.
There is no need to do that. It runs on the ui thread. You can update textview in onTick itself.
Example:
public class MainActivity extends Activity {
TextView tv;
public String secsRemain = "not set";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
startBrewTimer(200000);
}
private void startBrewTimer(long remaningMillis){
CountDownTimer counter = CountDownTimer(remaningMillis, 1000){
public void onTick(long millisUntilDone){
secsRemain = "seconds remaining: " + millisUntilFinished / 1000;
tv.setText(secsRemain);
}
public void onFinish() {
tv.setText("DONE!");
}
}.start();
}
}
You can get values through broadcast receiver......as follows,
First create your own IntentFilter as,
Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");
Then create inner class BroadcastReceiver as,
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
/** Receives the broadcast that has been fired */
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction()=="YOUR_INTENT_FILTER"){
//HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////
String receivedValue=intent.getStringExtra("KEY");
}
}
};
Now Register your Broadcast receiver in onResume() as,
registerReceiver(broadcastReceiver, intentFilter);
And finally Unregister BroadcastReceiver in onDestroy() as,
unregisterReceiver(broadcastReceiver);
Now the most important part...You need to fire the broadcast from wherever you need to send values..... so do as,
Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);
don't forget to accept my answer if you find this ans satisfactory....cheers :)
Related
Please guide me in this. Appreciate all your help.
My background service is toasting ABC
//-------------------String displayingText = "ABC";-----------------
And I have two strings, ABC and DEF declared in mainactivity.java
How do I pass the value displayingText from main activity to this service.
How do I change the displayingText to DEF after the toast ABC finished.
MyService.Java
public class MyService extends Service {
public static final long INTERVAL=3000;//variable to execute services every 5 second
private Handler mHandler=new Handler(); // run on another Thread to avoid crash
private Timer mTimer=null; // timer handling
//the get intent dont work. where or how should i put it?
Intent myIntent = getIntent();
if (myIntent !=null && myIntent.getExtras()!=null)
String value = myIntent.getExtras().getString(PassToService);
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("unsupported Operation");
}
#Override
public void onCreate() {
// cancel if service is already existed
if(mTimer!=null)
mTimer.cancel();
else
mTimer=new Timer(); // recreate new timer
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(),0,INTERVAL);// schedule task
}
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();///its will stop service
super.onTaskRemoved(rootIntent);
}
#Override
public void onDestroy() {
Toast.makeText(this, "In Destroy", Toast.LENGTH_SHORT).show();//display toast when method called
mTimer.cancel();//cancel the timer
super.onDestroy();
}
//inner class of TimeDisplayTimerTask
private class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast at every 10 second
//String displayingText = "ABC";
String displayingText = myIntent.getStringExtra("PassToService");
final Toast Notify = Toast.makeText(getApplicationContext(), displayingText, Toast.LENGTH_SHORT);
Notify.setGravity(Gravity.CENTER, 0, 0);
Notify.show();
Handler cancelToast = new Handler();
cancelToast.postDelayed(new Runnable() {
#Override
public void run() {
Notify.cancel();
}
}, 1000);
}
});
}
}
}
You can do it by passing value from activity to service-
startService(new Intent(YourActivity.Service.class).putExtra("key","value"));
i try almost code in the internet, but i can't solve it.
i want to send data from specific method in the service to activity.
i use intent(putExtra), but it doesn't go to activity class.
here is my RecoBackgroundRangingService.java
(i omit unnecessary code)
private static final String TAG = "RecoBackgroundRangingService";
public static final String BROADCAST_ACTION = "com.example.hello ";
private final Handler handler = new Handler();
Intent intent;
int counter = 0;
#Override
public void onCreate() {
Log.i("BackRangingService", "onCreate()");
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
Toast.makeText(getBaseContext(),"on create", Toast.LENGTH_SHORT).show();
}
#Override
public void didEnterRegion(RECOBeaconRegion region, Collection<RECOBeacon> beacons) {
/**
* For the first run, this callback method will not be called.
* Please check the state of the region using didDetermineStateForRegion() callback method.
*
//Get the region and found beacon list in the entered region
Log.i("BackRangingService", "didEnterRegion() - " + region.getUniqueIdentifier());
this.popupNotification("Inside of " + region.getUniqueIdentifier());
//Write the code when the device is enter the region
DisplayLoggingInfo();
Toast.makeText(getBaseContext(),"did enter region", Toast.LENGTH_SHORT).show();
//this.startRangingWithRegion(region); //start ranging to get beacons inside of the region
//from now, stop ranging after 10 seconds if the device is not exited
}
private void DisplayLoggingInfo() {
//Log.d(TAG, "entered DisplayLoggingInfo");
//intent.putExtra("time", new Date().toLocaleString());
//intent.putExtra("counter", String.valueOf(++counter));
intent.putExtra("status", 1);
sendBroadcast(intent);
Toast.makeText(getBaseContext(),"display logging", Toast.LENGTH_SHORT).show();
}
here is my CheckActivity.java
(when i receive data, my purpose is that store data to the server. therefore, i don't need to use layout. So, in order to check data, i use toast "hello". but toast never popup my phone...)
public class CheckActivity extends Activity {
private static final String TAG = "CheckActivity";
private Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_check);
intent = new Intent(this, RecoBackgroundRangingService.class);
Toast.makeText(getBaseContext(), "check activity", Toast.LENGTH_SHORT).show();
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(RecoBackgroundRangingService.BROADCAST_ACTION));
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
private void updateUI(Intent intent) {
int status = intent.getIntExtra("status", -1);
Toast.makeText(getBaseContext(), "hello", Toast.LENGTH_SHORT).show();
}
}
I am having a problem with the Timer in my quiz Game. Essentially it's a multiple choice game and the player is timed on each question. I have the timer starting when the application starts and the player sees the first question. My issue is that if the player answers the question correctly or Incorrectly the timers starts giving random values, even though I reset the timer to 30 seconds on the onclick method. How do I get the timer to start at 30 seconds and countdown normally.
public class MainActivity extends AppCompatActivity {
//Views
TextView questionTextView;
TextView mscoreTextView;
TextView mtimerTextView;
Button mchoice1;
Button mchoice2;
Button mchoice3;
Button mchoice4;
//Constructors
private questions Question = new questions();
private Answers cAnswers = new Answers();
private choices Choices = new choices();
//Variables
private int questionNumber = 0;
private int mScore = 0;
private String correctAnswer;
public void onClick(View view) {
Button answer1 = (Button) view;
if(answer1.getText() == correctAnswer) {
mScore = mScore + 1;
Toast.makeText(getApplicationContext(), "CORRECT!!", Toast.LENGTH_SHORT).show();
mtimerTextView.setText("30s");
runTimer();
} else {
Toast.makeText(getApplicationContext(), "WRONG!!", Toast.LENGTH_SHORT).show();
mtimerTextView.setText("30s");
runTimer();
}
updateScore(mScore);
updateUI();
}
private void updateScore(int points) {
mscoreTextView.setText("" + points + "/" + Question.getLength());
}
public void runTimer() {
new CountDownTimer(30100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String tick = String.valueOf(millisUntilFinished/1000 + "s");
mtimerTextView.setText(tick);
}
#Override
public void onFinish() {
Toast.makeText(getApplicationContext(), "TIME RAN OUT!!", Toast.LENGTH_LONG).show();
mtimerTextView.setText("0s");
updateUI();
}
}.start();
}
private void updateUI () {
if (questionNumber < Question.getLength()) {
questionTextView.setText(Question.getQuestion(questionNumber));
mchoice1.setText(Choices.getChoices(questionNumber, 1));
mchoice2.setText(Choices.getChoices(questionNumber, 2));
mchoice3.setText(Choices.getChoices(questionNumber, 3));
mchoice4.setText(Choices.getChoices(questionNumber, 4));
correctAnswer = cAnswers.getAnswer(questionNumber);
questionNumber ++;
} else {
Toast.makeText(getApplicationContext(), "This is the last question", Toast.LENGTH_LONG).show();
//Intent intent = new Intent(MainActivity.this, HighScoreActivity.class);
//intent.putExtra("Score", mScore);
//startActivity(intent);
}
runTimer();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
questionTextView = (TextView) findViewById(R.id.questionTextView);
mchoice1 = (Button) findViewById(R.id.choice1);
mchoice2 = (Button) findViewById(R.id.choice2);
mchoice3 = (Button) findViewById(R.id.choice3);
mchoice4 = (Button) findViewById(R.id.choice4);
mtimerTextView = (TextView) findViewById(R.id.timerTextView);
mscoreTextView = (TextView) findViewById(R.id.scoreTextView);
updateScore(mScore);
updateUI();
}
}
The thing is, you never really cancel a timer you've launched. Along with this, for every time you need a timer - you create a new one, which is not essential. The following must solve your problem:
You need to store CountDownTimer in a class field:
private CountDownTimer timer;
Then you can create it once on the start of app:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
timer = createTimer();
...
}
CreateTimer function:
public void createTimer() {
timer = new CountDownTimer(30100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
...
}
#Override
public void onFinish() {
...
}
}
}
So when you need to run timer you just call:
timer.start();
And when user gives an answer, you need to cancel timer first, then start it again:
public void onClick(View view) {
...
timer.cancel();
timer.start();
...
}
Also: you have some duplicated code in your OnClick() method. Regardless of user's answer correctness you need to run timer and set a value to mtimerTextView, so basically you want to do it outside of if-else construction.
You have to define a variable inside a CountDownTimer class.
public void runTimer() {
new CountDownTimer(30100, 1000) {
private int time = 30;
#Override
public void onTick(long millisUntilFinished) {
mtimerTextView.setText(time--+"s");
}
#Override
public void onFinish() {
Toast.makeText(getApplicationContext(), "TIME RAN OUT!!", Toast.LENGTH_LONG).show();
mtimerTextView.setText("0s");
updateUI();
}
}.start();
}
Cancelable Timer
If you want your Timer cancelable you have to define it as a global variable.
private CountDownTimer timer; // global variable
start the timer by calling the below runTimer() method.
public void runTimer() {
timer = new CountDownTimer(30100, 1000) {
private int time = 30;
#Override
public void onTick(long millisUntilFinished) {
mtimerTextView.setText(time--+"s");
}
#Override
public void onFinish() {
Toast.makeText(getApplicationContext(), "TIME RAN OUT!!", Toast.LENGTH_LONG).show();
mtimerTextView.setText("0s");
updateUI();
}
}.start();
}
You can cancel the timer by calling the below method.
public void stopTimer(){
if(timer != null){
timer.cancel();
}
}
Hope this will help
Here's code for a timer that plays a sound once it reaches 0 (timer works fine). The problem is the sound persists even through onPause() in MainActivity.java called.
I implemented onDestroy() in SimpleIntentService.java to stop the sound, but apparently it's never called even with finish() in the calling Activity. How am I supposed to make the sound stop when the app is paused?
Here's my MainActivity.java
public class MainActivity extends Activity {
private BroadcastReceiver broadcastReceiver;
NumberPicker picker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
picker = (NumberPicker) findViewById(minutePicker);
Log.i("TurnToTech", "Project Name - SimpleBackgroundService");
picker.setMinValue(0);
picker.setMaxValue(20);
broadcastReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent intent) {
String text = intent.getStringExtra(SimpleIntentService.PARAM_OUT_MSG);
Toast.makeText(getApplicationContext(),
text, Toast.LENGTH_SHORT).show();
}
};
}
Intent msgIntent;
public void startTimer(View view) {
setContentView(R.layout.activity_main);
msgIntent = new Intent(this, SimpleIntentService.class);
msgIntent.putExtra(SimpleIntentService.PARAM_IN_MSG, "Alarm: ");
msgIntent.putExtra("time", picker.getValue());
startService(msgIntent);
}
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(SimpleIntentService.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(broadcastReceiver,filter);
}
public void onPause() {
finish();
unregisterReceiver(broadcastReceiver);
super.onPause();
}
}
And the SimpleIntentService.java
public class SimpleIntentService extends IntentService {
public static final String PARAM_IN_MSG = "in_msg";
public static final String PARAM_OUT_MSG = "out_msg";
int time;
public static final String ACTION_RESP = "org.turntotech.intent.action.MESSAGE_PROCESSED";
public SimpleIntentService() {
super("SimpleIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("SimpleIntentService Called");
String msg = intent.getStringExtra(PARAM_IN_MSG);
int time = intent.getIntExtra("time", 0);
// Timer implementation
if (time == 0 ){
playSound();
}
while(time > 0){
SystemClock.sleep(5000); // 5 seconds
time -= 5;
String resultTxt = msg + time + " seconds remaining";
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ACTION_RESP);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra(PARAM_OUT_MSG, resultTxt);
broadcastIntent.putExtra("time", time);
sendBroadcast(broadcastIntent);
if (time == 0) {
playSound();
}
}
}
Uri alert;
public void playSound(){
alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), alert);
r.play();
}
public void onDestroy() {
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), alert);
r.stop();
super.onDestroy();
}
}
In your IntentService you're not really stopping the same alarm in your onDestroy function. Because each time you're getting a new instance of it.
So I would like to suggest to keep a public static variable of Ringtone so that it can be accessed from everywhere. Declare them in your MainActivity.
public static Ringtone r;
public static Uri alert;
Initialize them in the onCreate function of your MainActivity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ... Other statements
// Initialize ringtone here
initializeRingtone();
}
private void initializeRingtone() {
alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
r = RingtoneManager.getRingtone(getApplicationContext(), alert);
}
Now the onPause() function of your MainActivity should look like this
public void onPause() {
unregisterReceiver(broadcastReceiver);
r.stop();
super.onPause();
}
And if you want to play the sound after you resume the application from background and then the timer runs out, you might consider doing something like this in the onResume function of your MainActivity
public void onResume() {
super.onResume();
registerReceiver(broadcastReceiver);
initializeRingtone(); // Initialize it again.
}
And the playSound() function in the IntentService might look like this.
public void playSound(){
// Initialize the alert and ringtone again.
MainActivity.alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
MainActivity.r = RingtoneManager.getRingtone(getApplicationContext(), alert);
MainActivity.r.play();
}
public void onDestroy() {
MainActivity.r.stop();
super.onDestroy();
}
Hope that helps!
i tired this a few months ago but failed.
what i'm trying to do is count the number of times the user unlocks his phone and show it on the screen but i'm getting vague numbers each time i unlock the phone.
my code is a follows.
My main activity oncreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(getApplicationContext(), LockService.class));
TextView ticker;
ticker = (TextView) findViewById(R.id.textView);
ticker.setText(String.valueOf(Tick.tick));
Log.e("but this is awesome ", String.valueOf(Tick.tick));
}
The Service class
public class LockService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
final BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
return super.onStartCommand(intent, flags, startId);
}
public class LocalBinder extends Binder {
LockService getService() {
return LockService.this;
}
}
}
The BroadcastReceiver Class
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
#Override
public void onReceive(final Context context, final Intent intent) {
Log.e("test", "onReceive");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
wasScreenOn = false;
Log.e("test", "wasScreenOn" + wasScreenOn);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
wasScreenOn = true;
Log.e("test", "wasScreenOn and user present" + wasScreenOn);
} else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Tick.tick ++;
Log.e("test", "userpresent" + Tick.tick);
}
}
}
please help me understand what i'm doing wrong
I believe what's happening is this:
each time you open your activity, you call start service. So even if your service is already running, onStartCommand is being called. This way, you register your broadcast multiple times, and then when you unlock your device your counters are being incremented for each time you reciver has been registered.
You should do one of these options:
1. Define your recievers in your manifest so you won't have to deal with registration and unregisteration each time.
2. Register you recievers in your service onCreate instead onStartCommand. Also, make sure you unregister them in your service onDestroy.