Android - Launching an activity from service after force stop / crash - java

I am developing a countdown timer application and want to launch the activity to start after time completes every thing is working fine but after I force stop the app it shows NullPointerException. I can't figure out why it is showing this.
here is my java code
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
x=1;
//final TimerService timerService=this;
r = new Runnable() {
#Override
public void run() {
try {
if ((minutes >= 0) && (seconds >= 0) && (minutes <= 59) && (seconds <= 59)) {
if (seconds == 0 && minutes > 0) {
minutes--;
seconds = 59;
} else if (seconds == 0 && minutes == 0) {
try {
mins.setEnabled(true);
secs.setEnabled(true);
Intent ring = new Intent(getApplicationContext(), TimerComplete.class);
ring.setAction(Intent.ACTION_VIEW);
ring.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ring.setComponent(new ComponentName(getApplicationContext().getPackageName(), TimerComplete.class.getName()));
timerService.startActivity(ring);
stopSelf();
handler.removeCallbacks(this);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
mins.setText(String.format("%02d", minutes));
secs.setText(String.format("%02d", seconds));
if (seconds != 0) {
seconds--;
x++;
handler.postDelayed(this, 1000);
}
} else {
mins.setEnabled(true);
secs.setEnabled(true);
mins.setText("00");
secs.setText("00");
handler.removeCallbacks(this);
Toast.makeText(getApplicationContext(), "Invalid Time", Toast.LENGTH_LONG).show();
}
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
};
handler.post(r);
return START_REDELIVER_INTENT;
}
This function is of static nested class and all the views I am using are of outer class

you can use the timer and set the delay of 1 sec
int myTimeCounter = 60;
Timer myTimer = new Timer();
private void startRepeatedTask() {
myTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if (myTimeCounter == 0) {
myTimer.cancel();
callActivity();
return;
}
//Log.d(TAG, "timer=" + String.valueOf(myTimeCounter));
myTimeCounter--;
}
});
}
}, 0, 1000);
}

Related

Media Player - Seek bar and Time lable is not progressing

IDK why but after just coping the entier mainactivty.java file from this video
IDK why my seek bar and timetable are not showing any progress
there is an exception I have 2 audio files but the video show has only one so I have doubled all the methods also the onClick and a dialog which is different from it
MainActivity.java
public class MainActivity extends AppCompatActivity {
MediaPlayer player1;
MediaPlayer player2;
SeekBar seekBar1;
SeekBar seekBar2;
TextView elapsedTimeLable1;
TextView elapsedTimeLable2;
TextView remainingTimeLable1;
TextView remainingTimeLable2;
ImageView play1;
ImageView play2;
int totalTime1;
int totalTime2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// PlayButton * The ButtonClick is in the last if you want to jump directly there *
play1 = findViewById(R.id.playbtn1);
play2 = findViewById(R.id.playbtn2);
// TimeLables
elapsedTimeLable1 = findViewById(R.id.cTime1);
elapsedTimeLable2 = findViewById(R.id.cTime2);
remainingTimeLable1 = findViewById(R.id.tTime1);
remainingTimeLable2 = findViewById(R.id.tTime2);
// MediaPlayer
player1 = MediaPlayer.create(this, R.raw.dog_howl);
player1.setLooping(true);
player1.seekTo(0);
totalTime1 = player1.getDuration();
player2 = MediaPlayer.create(this, R.raw.dog_bark);
player2.setLooping(true);
player2.seekTo(0);
totalTime2 = player2.getDuration();
//SeekBar
seekBar1 = findViewById(R.id.seekbar1);
seekBar2 = findViewById(R.id.seekbar2);
seekBar1.setMax(totalTime1);
seekBar2.setMax(totalTime2);
seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress1, boolean fromUser1) {
if (fromUser1) {
player1.seekTo(progress1);
seekBar1.setProgress(progress1);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress2, boolean fromUser2) {
if (fromUser2) {
player2.seekTo(progress2);
seekBar2.setProgress(progress2);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Thread (Update SeekBar & TimeLabel)
new Thread(() -> {
while (player1 != null) {
try {
Message msg = new Message();
msg.what = player1.getCurrentPosition();
handler1.sendMessage(msg);
Thread.sleep(1000000000);
} catch (InterruptedException e) {
}
}
}).start();
new Thread(() -> {
while (player2 != null) {
try {
Message msg = new Message();
msg.what = player2.getCurrentPosition();
handler2.sendMessage(msg);
Thread.sleep(1000000000);
} catch (InterruptedException e) {
}
}
}).start();
// Admob Banner Ad
MobileAds.initialize(this, initializationStatus -> {
});
AdView mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
// Caution dialog
SharedPreferences preferences = getSharedPreferences("prefs", MODE_PRIVATE);
boolean firstStart = preferences.getBoolean("firstStart", true);
if (firstStart) {
showDialog();
}
}
// Caution dialog
private void showDialog() {
new AlertDialog.Builder(this)
.setTitle("Caution!")
.setMessage("In case you're wearing any kind of headphones please remove it before playing the ' Howl ' audio")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.create().show();
SharedPreferences preferences = getSharedPreferences("prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("firstStart", false);
editor.apply();
}
private Handler handler1 = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition1 = msg.what;
//Update SeekBar
seekBar1.setProgress(currentPosition1);
// Update Timelable
String elapsedTime1 = createTimerLable1(currentPosition1);
elapsedTimeLable1.setText(elapsedTime1);
String remainingTime1 = createTimerLable1(totalTime1 - currentPosition1);
remainingTimeLable1.setText("- " + remainingTime1);
}
};
private Handler handler2 = new Handler() {
#SuppressLint("SetTextI18n")
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition2 = msg.what;
// Update SeekBar
seekBar2.setProgress(currentPosition2);
// Update Timelable
String elapsedTime2 = createTimerLable2(currentPosition2);
elapsedTimeLable2.setText(elapsedTime2);
String remainingTime2 = createTimerLable2(totalTime2 - currentPosition2);
remainingTimeLable2.setText("- " + remainingTime2);
}
};
public String createTimerLable1(int duration) {
String timerLabel1 = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel1 += min + ":";
if (sec < 10) timerLabel1 += "0";
timerLabel1 += sec;
return timerLabel1;
}
public String createTimerLable2(int duration) {
String timerLabel2 = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel2 += min + ":";
if (sec < 10) timerLabel2 += "0";
timerLabel2 += sec;
return timerLabel2;
}
public void playBtnClick1(View view) {
if (player2.isPlaying()) {
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player1.isPlaying()) {
// Stoping
player1.start();
play1.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
public void playBtnClick2(View view) {
if (player1.isPlaying()) {
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player2.isPlaying()) {
// Stoping
player2.start();
play2.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
}
So well why should threads sleep 1000000000 milliseconds.
In that case your thread does its tasks every 1000000 seconds.
1000000000 ms => 1000000 sec => 16666 min => 277 hour
So your thread does its task every 277 hours.
The param of sleep is millisecond so put st like 1000(1 second) or something like that which is a lot shorter.
If this wasn't solution let me know.
Replace Thread.sleep(1000000000) to Thread.sleep(1000) because you just need to update text and seek bar every second
new Thread(() -> {
while (player1 != null) {
try {
Message msg = new Message();
msg.what = player1.getCurrentPosition();
handler1.sendMessage(msg);
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}).start();
new Thread(() -> {
while (player2 != null) {
try {
Message msg = new Message();
msg.what = player2.getCurrentPosition();
handler2.sendMessage(msg);
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}).start();

How to use timer in Android

In my application i have timer for some works.
When my application running after some time my application freeze and not work any View !
In this timer every 500ms i emit socket.io
My Codes:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
socketPingTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (isSendSocketPing) {
checkSocketPingTimer += startSocketPingTimer;
if (checkSocketPingTimer == sendSocketPingTimer) {
currentTimerForSocket = System.currentTimeMillis();
try {
detailSocketUtils.getSendRTTforPing(currentTimerForSocket + "");
} catch (Exception e) {
}
}
//Show ping (from search)
Constants.currentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
if (isShownPing) {
detailToolbar_ping.setVisibility(View.VISIBLE);
if (checkSocketPingTimer > 500) {
detailToolbar_ping.setText(checkSocketPingTimer + "");
detailToolbar_ping.setTextColor(Color.RED);
} else {
detailToolbar_ping.setText(checkSocketPingTimer + "");
detailToolbar_ping.setTextColor(Color.GREEN);
}
} else {
detailToolbar_ping.setVisibility(View.GONE);
}
}
});
socketPing = checkSocketPingTimer;
}
}
}, 500, startSocketPingTimer);
}
});
How can i run this timers in another thread and not freeze my app ?
It should be something similar to this code:
class MyActivity extends Activity
{
private void executeLoop()
{
Handler myHandler = new Handler()
{
public void handleMessage(Message msg)
{
if (isShownPing)
{
detailToolbar_ping.setVisibility(View.VISIBLE);
if (checkSocketPingTimer > 500) {
detailToolbar_ping.setText(checkSocketPingTimer + "");
detailToolbar_ping.setTextColor(Color.RED);
} else {
detailToolbar_ping.setText(checkSocketPingTimer + "");
detailToolbar_ping.setTextColor(Color.GREEN);
}
} else
{
detailToolbar_ping.setVisibility(View.GONE);
}
}
}
socketPingTimer.scheduleAtFixedRate(new TimerTask()
{
#Override
public void run()
{
if (isSendSocketPing)
{
checkSocketPingTimer += startSocketPingTimer;
if (checkSocketPingTimer == sendSocketPingTimer) {
currentTimerForSocket = System.currentTimeMillis();
try {
detailSocketUtils.getSendRTTforPing(currentTimerForSocket + "");
} catch (Exception e) {
}
}
myHandler.sendEmptyMessage();
socketPing = checkSocketPingTimer;
}
}
}, 500, startSocketPingTimer);
}
}
private void startTimerAtFixRate() {
android.os.Handler handler = new android.os.Handler();
Runnable updateTimerThread = new Runnable() {
public void run() {
//write here whatever you want to repeat
// Like I called Log statement
// After every 1 second this below statement will be executed
Log.e("CALLED-->", "TRUE");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(updateTimerThread, 100);
}

Delay For CountDown Timer - Android

I am making a chess clock but in it I need a delay (Like it waits 10 seconds before counting). I used a Handler for it but if the button is clicked in the 10 seconds, nothing happens. Please help! Thanks!
My code:
mHandler.postDelayed(new Runnable() {
public void run() {
// count down timer start
timer2 = new CountDownTimer(totalSeconds, Integer.parseInt(delay.getText().toString())) {
public void onTick(long millisUntilFinished) {
secondsTimer = (int) (millisUntilFinished / 1000) % 60;
minutesTimer = (int) ((millisUntilFinished / (1000 * 60)) % 60);
hoursTimer = (int) ((millisUntilFinished / (1000 * 60 * 60)) % 24);
person2.setText(hoursTimer + ":" + minutesTimer + ":" + secondsTimer);
}
public void onFinish() {
person2.setText("Time Up!");
person2.setBackgroundColor(Color.RED);
mp.start();
}
}.start();
}
}, finalDelay);
I want a delay but I don't want to lock the UI and make the app unresponsive as it is doing right now with the handler. Any help will be appreciated! Thanks in advance!
I think you shouldn't put CountdownTimer into Handler. You could create 2 handler instead. Here is an example.
private void startHandlerAndWait10Seconds(){
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
public void run() {
// Start Countdown timer after wait for 10 seconds
startCountDown();
}
}, 10000);
}
private void startCountDown {
final Handler handler2 = new Handler();
handler2.post(new Runnable() {
int seconds = 60;
public void run() {
seconds--;
mhello.setText("" + seconds);
if (seconds < 0) {
// DO SOMETHING WHEN TIMES UP
stopTimer = true;
}
if(stopTimer == false) {
handler2.postDelayed(this, 1000);
}
}
});
}
If you want to start the timer immediately,
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Handler().post(new Runnable() {
public void run() {
// count down timer start
new CountDownTimer(100000, 1000) {
public void onTick(long millisUntilFinished) {
button.setText(String.valueOf(millisUntilFinished));
}
public void onFinish() {
button.setText("Time Up!");
}
}.start();
}
});
}
});
And if you want to execute it after a certain time period, then
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Handler().postDelayed(new Runnable() {
public void run() {
// count down timer start
new CountDownTimer(100000, 1000) {
public void onTick(long millisUntilFinished) {
button.setText(String.valueOf(millisUntilFinished));
}
public void onFinish() {
button.setText("Time Up!");
}
}.start();
}
}, 1000);
}
});
You can avoid using Handler starting timer immediately
private fun start10SecondsDelayTimer() {
var delayCount = 10
val timer = object : CountDownTimer(1_000_000L, 1000L) {
override fun onTick(millisUntilFinished: Long) {
if (delayCount > 0) {
delayCount--
} else {
//your calculations
}
}
override fun onFinish() {
//some calculations
}
}
timer.start()
}
but first ticks will be without your calculations

Change sleep function - java - android

I set a sleep() in the beginning of my code, and later on the code I want to change the time: delay or precede, depends on if term.
for example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread background = new Thread() {
public void run() {
try {
sleep(10000);
Intent i;
i=new Intent(getBaseContext(),Activity8.class);
startActivity(i);
finish();
} catch (Exception ex) { }
}
};
if (connect.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTED || connect.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTING || connect.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTING ||
connect.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTED) {
network = true; }
if (network == true) {
// I want to set sleep to 2 seconds instead of 10 (current setting is 10).
} else { // I don't want to change sleep }
I would create an int to store the amount of time to sleep for somewhere in the class and then modify that for however long you want to sleep for. However this would not update the current sleep. The only way I can think of to combat that would be to interupt the thread and then start it again with the new sleep time. For example:
int sleepTime = 10000;
Thread background;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
background = new Thread() {
public void run() {
try {
sleep(sleepTime);
Intent i;
i=new Intent(getBaseContext(),Activity8.class);
startActivity(i);
finish();
} catch (Exception ex) { }
}
};
if (connect.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTED || connect.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTING || connect.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTING ||
connect.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTED) {
network = true;
}
if (network == true) {
sleepTime = 2000;
background.interrupt();
background.start();
} else {
sleepTime = 10000;
background.interrupt();
background.start();
}
I am not sure if this would work. Correct me if I am wrong.

problem with stopWatch in android

in my app i have placed a stop watch with two buttons. The stop watch works in a proper way. But the problem is at start the timer looks as 0:0:0, when it starts counting the single digits are been changed over to double digits as 0:12:53.
this affects and disturbs the other layers too. At the start itself i want it to be displayed as 00:00:00 by default, so that i cant make changes in the layout.
but i don't know where to give the value for this. Following is my code
b1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(b1.getText().toString().equals("Start"))
{
if(currentThread.getState()==Thread.State.NEW)
{
currentThread.start();
shouldRun = true;
b1.setText("Stop");
}
else
{
shouldRun = false;
b1.setText("Stop");
}
}
else if(b1.getText().toString().equals("Stop"))
{
time=0;
time1=0;
time2=0;
}
}
});
b2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(b2.getText().toString().equals("Pause"))
{
shouldRun = false;
b2.setText("Resume");
}
else if(b2.getText().toString().equals("Resume"))
{
shouldRun = true;
b2.setText("Pause");
}
}
});
}
#Override
public void run()
{
try
{
while(true)
{
while(shouldRun)
{
Thread.sleep(1000);
Log.e("run", "run");
threadHandler.sendEmptyMessage(0);
}
}
}
catch (InterruptedException e) {}
}
private Handler threadHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
sec=time2++;
if(sec == 59)
{
time2=0;
sec = time2++;
min=time1++;
}
if(min == 59)
{
time1=0;
min = time1++;
hr=time3++;
}
stopWatch.setText(""+hr+":"+min+":"+sec);
}
};
}
how to do this please help me............
This should do the work:
String time = String.format("%02d:%02d:%02d", hr, min, sec);
stopWatch.setText(time);
Or the one-line-version:
stopWatch.setText(String.format("%02d:%02d:%02d", hr, min, sec));
set the text like so
stopWatch.setText(""+(hr<10?"0"+hr:hr)+":"+(min<10?"0"+min:min)+":"+(sec<10?"0"+sec:sec));
will:
stopWatch.setText("00:00:00");
not do the trick when you initialise it?
It's simple you just add this code
private Handler threadHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
sec=time2++;
if(sec == 59)
{
time2=0;
sec = time2++;
min=time1++;
if(sec< 10)
sec= "0"+sec
}
if(min == 59)
{
time1=0;
min = time1++;
hr=time3++;
if(min< 10)
min= "0"+min
}
if(hr< 10)
hr= "0"+hr
stopWatch.setText(""+hr+":"+min+":"+sec);
}
};

Categories

Resources