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.
Related
my MediaPlayer stops playing after phone goes to sleep about 20 to 30 seconds after . my failed attempt is below thanks in advance.
MediaPlayer mediaPlayer = new MediaPlayer();
SeekBar seekBar;
boolean wasPlaying = false;
ImageButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mediaplayer);
fab = findViewById(R.id.imageButton);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
playSong();
}
});
final TextView seekBarHint = findViewById(R.id.textView);
seekBar = findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
seekBarHint.setVisibility(View.VISIBLE);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
seekBarHint.setVisibility(View.VISIBLE);
int x = (int) Math.ceil(progress / 1000f);
if (x < 10)
seekBarHint.setText("0:0" + x);
else
seekBarHint.setText("0:" + x);
double percent = progress / (double) seekBar.getMax();
int offset = seekBar.getThumbOffset();
int seekWidth = seekBar.getWidth();
int val = (int) Math.round(percent * (seekWidth - 2 * offset));
int labelWidth = seekBarHint.getWidth();
seekBarHint.setX(offset + seekBar.getX() + val
- Math.round(percent * offset)
- Math.round(percent * labelWidth / 2));
if (progress > 0 && mediaPlayer != null && !mediaPlayer.isPlaying()) {
clearMediaPlayer();
fab.setImageDrawable(ContextCompat.getDrawable(MediaPlayerActivity.this, android.R.drawable.ic_media_play));
MediaPlayerActivity.this.seekBar.setProgress(0);
}
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(seekBar.getProgress());
}
}
});
}
public void playSong() {
try {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
clearMediaPlayer();
seekBar.setProgress(0);
wasPlaying = true;
fab.setImageDrawable(ContextCompat.getDrawable(MediaPlayerActivity.this, android.R.drawable.ic_media_play));
}
if (!wasPlaying) {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
fab.setImageDrawable(ContextCompat.getDrawable(MediaPlayerActivity.this, android.R.drawable.ic_media_pause));
Intent intent = getIntent();
String user_name = intent.getStringExtra("USER_NAME");
String file = intent.getStringExtra("FILE_NAME");
TextView Namee = findViewById(R.id.textView3);
Namee.setText(file);
mediaPlayer.setDataSource(user_name);
mediaPlayer.prepare();
mediaPlayer.setVolume(0.5f, 0.5f);
mediaPlayer.setLooping(false);
seekBar.setMax(mediaPlayer.getDuration());
mediaPlayer.start();
new Thread(this).start();
}
wasPlaying = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
int currentPosition = mediaPlayer.getCurrentPosition();
int total = mediaPlayer.getDuration();
while (mediaPlayer != null && mediaPlayer.isPlaying() && currentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = mediaPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekBar.setProgress(currentPosition);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
clearMediaPlayer();
}
private void clearMediaPlayer() {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
The problem occurs because when your phone sleeps, your activity destroyed after a certain time base on your free ram and other
The point is, for a long running task like music play, an activity is not an option. Activity mostly is, only for tasks which needs user focus, interaction and not running for an infinite time in the background.
Music player and such long running job need to use service, which runs indefinitely until the user or OS destroys it.
From google doc about service
A Service is an application component that can perform long-running operations in the background, and it doesn't provide a user interface. Another application component can start a service, and it continues to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service can handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
To say specifically, for a music app, you need Foreground Service
A foreground service performs some operation that is noticeable to the user. For example, an audio app would use a foreground service to play an audio track. Foreground services must display a Notification. Foreground services continue running even when the user isn't interacting with the app.
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);
}
I am trying to play with progress bars. I have this (below) simple activity which runs a progress bar N times one after the other, when I call Progress(N). It is working great but the problem I am facing is, if I press back button. I get into the mainActivity but the progress bars (the threads) are still running in background one after the other. As soon as they finish N loops, the intent is called and whatever I would be doing would be interrupted by this LOOP_OVER activity.
I tried solving this by my own. I tried using variable of Thread class (before I was directly doing it). And tried to interrupt() it at onDestroy() or even just before the intent is called but its not helping. How should I go about it?
public class Loop extends Activity {
private ProgressBar progressBar;
private CircleProgress circleProgress;
private int progressStatus = 0;
private Handler handler = new Handler();
private TextView myView;
private int started = 0, doneLoop=0;
private Thread th;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loop);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
circleProgress = (CircleProgress) findViewById(R.id.circle_progress);
myView = (TextView) findViewById(R.id.instruction);
progressBar.setScaleY(3f);
// Start long running operation in a background thread
Progress(3);
}
#Override
public void onDestroy() {
// Below, everything I am just
th.interrupt();
Loop.this.finish();
Thread.currentThread().interrupt();
super.onDestroy();
}
public void Progress(final int numberOfRuns){
// QueView.setText(Que);
if(numberOfRuns == 0){
th.interrupt();
Intent myIntent = new Intent(Loop.this, LOOP_OVER.class);
startActivity(myIntent);
super.onDestroy();
finish();
}
th = new Thread(new Runnable() {
public void run() {
genNextSet();
while (progressStatus < 100) {
progressStatus += 1;
// Update the progress bar and display the
//current value in the text view
handler.post(new Runnable() {
public void run() {
circleProgress.setProgress(progressStatus);
progressBar.setProgress(progressStatus);
textView.setText(progressStatus+"/"+progressBar.getMax());
}
});
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
myView.setText(Que);
}
});
// Sleep for 200 milliseconds.
//Just to display the progress slowly
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progressStatus = 0;
Progress(numberOfRuns - 1);
}
});
th.start();
}
private void genNextSet() {
// so some cool here!
}
}
You can think of a class variable that is shared among all threads.
Try to add something like this:
private Boolean LOOP = true;
then
while (progressStatus < 100 && LOOP) {
and
#Override
public void onBackPressed() {
LOOP = false
}
also
if(LOOP == true){
// call intent
}
finish();
Your activity does not get destroyed, if you press the "Back"-key, thus onDestroy() will not be called.I'd override onBackPressed(), if I where you.Alternatively, you could try to put it into the onPause()-method.
You haven't override the back button pressed..try this
#Override
public void onBackPressed() {
th.interrupt();
Loop.this.finish();
Thread.currentThread().interrupt();
super.onBackPressed();
// add finish() if you want to kill current activity
}
This is the code of my testing app:
public class MainActivity extends Activity
{
private TextView text;
private Button start;
private Button stop;
private TestThread Points;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.mainTextView1);
start = (Button) findViewById(R.id.mainButton1);
stop = (Button) findViewById(R.id.mainButton2);
Points = new TestThread();
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View p1)
{
if (! Points.isAlive())
{
Points.start();
}
}
});
stop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View p1)
{
if (Points.isAlive())
{
Points.stop();
}
}
});
}
public class TestThread extends Thread
{
private String points;
#Override
public void run()
{
for (int a = 0; a < 3; a++)
{
try
{
if (a == 0) points = ".";
else if (a == 1) points = "..";
else if (a == 2) {
points = "...";
a = -1;
}
runOnUiThread(new Runnable()
{
#Override
public void run()
{
text.setText(points);
}
});
Thread.sleep(350);
} catch (InterruptedException e) {}
}
}
}
}
When I click on Start button the thread starts successfully but when I click on Stop button the app crashes...
How can i stop the thread successfully without force closing?
Thanks a lot
Thread.stop() function is deprecated and should not be used to stop a thread.
this is according to the java docs.
a good way to stop a thread is make it exit its run method.
a simple way to achive this is by adding a boolean member to your thread class:
public class TestThread extends Thread
{
private String points;
private boolean keepRunning = true;
public cancel(){
keepRunning = false;
}
#Override
public void run()
{
for (int a = 0; a < 3; a++)
{
if(!keepRunning) break;
try
{
if (a == 0) points = ".";
else if (a == 1) points = "..";
else if (a == 2) {
points = "...";
a = -1;
}
runOnUiThread(new Runnable()
{
#Override
public void run()
{
text.setText(points);
}
});
Thread.sleep(350);
} catch (InterruptedException e) {}
}
}
}
call the TestThread.cancel() function in your stop button onClick method.
Other than adding a Boolean to stop it I believe you could catch InterruptException and just call Thread.interrupt(); which would exit the loop this ending the thread
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);
}
};