is my do loop code for java correct? - android

is this correct?
im modifying a source code from github : USB CHARGE COMMANDER
when battery goes down from 20 percent it will charge
when batter goes 80 it wont
and countdown timer is for it to do this every 5 mins
i set 20000 just for testing
boolean startcountdown=true;
do{
new CountDownTimer(20000, 1000) {
Intent intent = _context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level*100)/scale;
public void onTick(long millisUntilFinished) {}
public void onFinish() {
if(percent <= 20){
_iIsCharging = 1;
}
else if (percent >=80){
_iIsCharging = 0;
}
else{
_iIsCharging = 1;
}
}
}.start();
}while(startcountdown);

There is no way for this do/while loop to end, it's an infinite loop at the moment. The boolean "startcountdown" needs some way to eventually go to the value of FALSE. For example
if (_iIsCharging == 0) {
startcountdown = false;
}

Related

Set progressbar position

I need progress bar witch position depends on two timestamp values in millis, so it depends on future timestamp, past timestamp and current timestamp.
For example, I have timestamp of 08:46:11 30.06.2019 and 10:46:11 30.06.2019. But current time is 09:46:11 30.06.2019, so now progressbar should be filled on 50% and going up to 100 until 10:46:11 30.06.2019
I have tried the next code but now I have understood that using CountDownTimer is useless and it is not for my task which described above:
private void progressBar(){
prBar.setProgress(i);
mCountDownTimer=new CountDownTimer(ltimestampStop * 1000,ltimestampStart * 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.v("Log_tag", "Tick of Progress"+ i+ millisUntilFinished);
i++;
int Start = ltimestampStart.intValue();
int Stop = ltimestampStop.intValue();
prBar.setProgress((int)i*100/(Stop/Start));
}
#Override
public void onFinish() {
//Do what you want
i++;
prBar.setProgress(100);
}
};
mCountDownTimer.start();
}
So what should I done for creating progressbar on certain position which depends on future time, past time and present time?
You can try to following:
long startTimeInMillis = ...; // 08:46:11 30.06.2019
long stopTimeInMillis = ...; // 10:46:11 30.06.2019
long currentTimeInMillis = ...; // 09:46:11 30.06.2019
long totalTimeInMilis = stopTimeInMillis - startTimeInMillis;
// Standart logic
long remainingTimeInMillis = stopTimeInMillis - currentTimeInMillis;
// But this line assures remaining time is not greater than total time
long remainingTimeInMillis = currentTimeInMillis < startTimeInMillis ?
totalTimeInMilis : stopTimeInMillis - currentTimeInMillis;
// Update every second
long countDownIntervalInMillis = 1000;
// Alternatively you can adjust interval such that it is called only in integer percent changes
int remainingSteps = (int) (((double) remainingTimeInMillis / totalTimeInMilis) * 100);
long countDownIntervalInMillis = remainingTimeInMillis / remainingSteps;
mCountDownTimer = new CountDownTimer(remainingTimeInMillis, countDownIntervalInMillis) {
#Override
public void onTick(long millisUntilFinished) {
int completedPercent = (int) ((1 - (double) millisUntilFinished / totalTimeInMilis) * 100);
prBar.setProgress(completedPercent);
}
#Override
public void onFinish() {
// Do what you want
prBar.setProgress(100);
}
};
mCountDownTimer.start();

Android Download Manager with progress dialog

I have coded an android app using android download manager, and I try to show downloading progress using below code.
myTimer.schedule(new TimerTask() {
public void run() {
try {
DownloadManager.Query q;
q = new DownloadManager.Query();
q.setFilterById(preferenceManager.getLong(strPref_Download_ID, 0));
cursorTimer = downloadManager.query(q);
cursorTimer.moveToFirst();
int bytes_downloaded = cursorTimer.getInt(cursorTimer.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytes_total = cursorTimer.getInt(cursorTimer.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
final int dl_progress = (int) ((double) bytes_downloaded * 100f / (double) bytes_total);
mProgressDialog.setProgress((int) dl_progress);
} catch (Exception e) {
} finally {
}
}
}, 0, 10);
Everthing is working fine, but progress dialog is not showing smooth pregress that means I wish to show 1,2,3,4,5,6,.....100.
It's show initially 0, and suddenly change to 12% then 31% etc 100%.
My file Total size is 26246026 bytes, at the time of 0% my downloaded file size is 6668 bytes,
at the time of 12% my downloaded file size is 3197660 bytes, and etc...
First of all don't query too frequent it may hang your UI and use ValueAnimator for changing progress smoothly.
myTimer.schedule(new TimerTask() {
public void run() {
try {
DownloadManager.Query q;
q = new DownloadManager.Query();
q.setFilterById(preferenceManager.getLong(strPref_Download_ID, 0));
cursorTimer = downloadManager.query(q);
cursorTimer.moveToFirst();
int bytes_downloaded = cursorTimer.getInt(cursorTimer.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytes_total = cursorTimer.getInt(cursorTimer.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
final int dl_progress = (int) ((double) bytes_downloaded * 100f / (double) bytes_total);
changeProgressSmoothly((int) dl_progress);
} catch (Exception e) {
} finally {
}
}
}, 0, 5000);
private void changeProgressSmoothly(int progress) {
ValueAnimator va = ValueAnimator.ofInt(mProgressDialog.getProgress(), progress);
int mDuration = 2000; //in millis
va.setDuration(mDuration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
mProgressDialog.setProgress((int) animation.getAnimatedValue());
}
});
va.start();
}
From documentation,
public void schedule (TimerTask task, long delay, long period)
Schedule a task for repeated fixed-delay execution
after a specific delay.
Parameters
task - the task to schedule.
delay - amount of time in milliseconds before first execution.
period - amount of time in milliseconds between subsequent executions.
Here, you have a period of 10 millis in your code. That might be the problem. Try 1 millis instead.
myTimer.schedule(new TimerTask() {
}, 0, 1);

Android, Use Timer to do a task at different times?

I searched other posts and I didn't find a case matching my problem, so please do not refer me to other posts.
I have a list of hundreds of different times starting like the below list:
timeList = {5, 13, 21, 40, ...}.
Suppose that they are saved in an arraylist. That means some task must be executed at 5 secs, 13 secs,... from a starting point . How can I use a Timer or any other way to achieve this?
Also I may have the timeList in a format like this if it helps:
timeList = {8:05, 8:13, 8:21, 8:40, ...}.
My current timer is like this:
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
synchronized public void run() {
//do some task
}
}, startPoint, Period);
But this is obviously working at fixed rate!
By using Timer.schedule(TimerTask task, long delay), set all your timers and wait for them to execute
Assuming you are getting in MM:SS format (ex: 8:58):
ArrayList<String> your_arraylist = new ArrayList<String>();
//your list above, fill it with MM:SS
final ArrayList<Long> seconds = new ArrayList<Long>();
final ArrayList<Long> minutes = new ArrayList<Long>();
long first_minute;
for (String time : your_arraylist) {
minutes.add(Long.parseLong(time.split(":")[0]));
seconds.add(Long.parseLong(time.split(":")[1]));
}
first_minute = minutes.get(0);
for (int i = 0; i < seconds.size(); i++) {
long waiting_duration;
if (seconds.get(i) < Calendar.SECOND) {
waiting_duration = (60 - Calendar.SECOND + seconds.get(i)) * 1000;
}
else {
waiting_duration = (seconds.get(i) - Calendar.SECOND) * 1000;
}
waiting_duration += (minutes.get(i) - first_minute) * 60 * 1000;
Timer timer = new Timer();
TimerTask timer_task = new TimerTask() {
#Override
public void run() {
// do jobs
}
};
timer.schedule(timer_task, waiting_duration);
}
Don't use Timer use a Handler instead.
private int[] mTimeList = {5000, 2000, 7000, 4000};
private int mCount;
private int mDelay;
private Handler mHandler = new Handler();
private void initRepeatedTimer() {
mHandler.postDelayed(new Runnable() {
public void run() {
Log.e(TAG, "run: " + mCount);
mDelay = mTimeList[mCount];
if (mCount < mTimeList.length - 1)
mCount++;
else
mCount = 0;
mHandler.postDelayed(this, mDelay);
}
}, mDelay);
}
You wil notice that the log is printed as per delay in the list.

getDuration() gives 0 output for one file in Android App

My app loads two audio files from database and stores them in an array. User can play any of them by selecting one from radio button group. both are mp3. One is playing fine and it's elapsed and total duration is displaying correctly. But the same functions display 00:00 total duration for other. Seek bar also updates its progress to 100% in this case but the elapsed time is correctly displaying and audio is playing fine. Someone please tell what is the problem? Why this is happening.. and how can I resolve it??
audio_urdu's time is fine.. error is with audio_eng.
private void updateView(int i) throws JSONException
{
idx=0;
_imgBtnPlay.setClickable(false);
_imgBtnStop.setClickable(false);
JSONObject jObject=null;
jObject=Jarray.getJSONObject(i);
audioUrl_eng=jObject.getString("audio_eng");
audioUrl_urdu=jObject.getString("audio_urdu");
lbl_tDuration.setText("00:00");
lbl_cDuration.setText("00:00");
lbl_loading.setText("Loading audio files...");
loadAudio(audioUrl_eng);
}
// Loading audio files from URL
private void loadAudio(String url)
{
// TODO Auto-generated method stub
mMediaPlayer=new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try
{
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepareAsync();
}
catch(IOException e)
{
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
mMediaPlayer.setOnPreparedListener(this);
}
// Notify when audio is ready to be played
#Override
public void onPrepared(MediaPlayer mp)
{
// TODO Auto-generated method stub
audioPlayerList[idx]=mp;
idx++;
if (idx == 1)
{
audioPlayer = mp;
lbl_tDuration.setText(mSecToTimer(mp.getDuration()));
lbl_cDuration.setText(mSecToTimer(mp.getCurrentPosition()));
updateSeekBar();
loadAudio(audioUrl_eng);
}
if (idx == 2)
{
// Enabling the media control buttons
_imgBtnPlay.setClickable(true);
_imgBtnStop.setClickable(true);
rdGrp.setClickable(true);
lbl_loading.setText("");
idx = 0;
}
}
public void onClick(View v)
{
switch(v.getId())
{
// calling search function
case R.id.imgBtnSearch:
onSearchRequested();
break;
// when play/pause button is tapped
case R.id.imgBtnPlay:
if (audioPlayer.isPlaying())
{
audioPlayer.pause();
_imgBtnPlay.setImageResource(R.drawable.ic_action_play);
}
else if (audioPlayer!=null)
{
audioPlayer.start();
_imgBtnPlay.setImageResource(R.drawable.ic_action_pause);
durationHandler.postDelayed(updateSeekBarTime, 100);
}
break;
// when stop button is tapped
case R.id.imgBtnStop:
audioPlayer.pause();
_imgBtnPlay.setImageResource(R.drawable.ic_action_play);
resetProgress();
break;
default:
break;
}
// Updating the seek bar's time after every 100 milliseconds
public void updateSeekBar()
{
durationHandler.postDelayed(updateSeekBarTime, 100);
}
// Updating the progress of seek bar
private Runnable updateSeekBarTime = new Runnable()
{
public void run()
{
long tDuration = audioPlayer.getDuration();
long cDuration = audioPlayer.getCurrentPosition();
lbl_tDuration.setText(mSecToTimer(tDuration));
lbl_cDuration.setText(mSecToTimer(cDuration));
int progress = (int) getProgressPercentage(cDuration, tDuration);
_seekbar.setProgress(progress);
durationHandler.postDelayed(this, 100);
}
};
// Converting milliseconds into min:sec format
public String mSecToTimer(long ms)
{
String finalTimerString = "";
String secString = "";
String minString = "";
// Convert total duration into minutes and seconds
int min = (int)(ms % (1000*60*60)) / (1000*60);
int sec = (int) ((ms % (1000*60*60)) % (1000*60) / 1000);
// Prepending 0 to seconds if it is one digit
if(sec < 10)
secString = "0" + sec;
else
secString = "" + sec;
// Prepending 0 to minutes if it is one digit
if(min < 10)
minString = "0" + min;
else
minString = "" + min;
finalTimerString = minString + ":" + secString;
return finalTimerString;
}
// calculating the percentage progress of seek bar
public int getProgressPercentage(long cDuration, long tDuration)
{
Double percentage = (double) 0;
long cSeconds = (int) (cDuration / 1000);
long tSeconds = (int) (tDuration / 1000);
percentage =(((double)cSeconds)/tSeconds)*100;
return percentage.intValue();
}
// Converting progress of seek bar into time duration in milliseconds
public int progressToTimer(int progress, int tDuration)
{
int cDuration = 0;
tDuration = (int) (tDuration / 1000);
cDuration = (int) ((((double)progress) / 100) * tDuration);
return cDuration * 1000;
}
// Reseting the progress of seek bar when stop button is tapped
public void resetProgress()
{
audioPlayer.seekTo(0);
lbl_cDuration.setText(mSecToTimer(0));
_seekbar.setProgress(0);
}
I have one audio in English and one in Urdu language. both are in the array audioPlayerList. User can select different languages using radio buttons. and idx is variable which tells which audio file is to be played. audio_eng is on index 0 (idx = 0) and audio_urdu is on index 1 (idx = 1). Audio is selected as audioPlayer = audioPlayerList[idx]
code for Radio button selection is this:
rdGrp.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(RadioGroup group, int checkedId)
{
// Find which radio button is selected
if (audioPlayer!=null)
{
if(audioPlayer.isPlaying())
audioPlayer.pause();
_imgBtnPlay.setImageResource(R.drawable.ic_action_play);
resetProgress();
if (checkedId == R.id.rdEng)
audioPlayer = audioPlayerList[0];
else if (checkedId == R.id.rdUrdu)
audioPlayer = audioPlayerList[1];
}
}
});
Duration of your file 'audio_eng' might be less than 1 second. When calculating percentage you convert milliseconds to seconds that results in 0 total length. That's why you get progress bar set to 100% from the beginning (actually, an exception might be thrown in this case - did you check that?).
When calculatng percentage try not to convert xDurationinto xSeconds but divide durations themselves in method getProgressPercentage.
I couldn't find other reasons why you get such result

Stopwatch developed by me is lagging behind other standard stopwatch by 8-10 seconds & increases

I have developed a stopwatch in Android . The stopwatch has the feature of Lap calculation too.
I have started the stopwatch . I tested the stopwatch developed by me with multiple standard stopwatches . The problem is that after 1 minutes , the stopwatch developed keeps lagging behind the other stopwatches & the difference keeps on increasing. I got around 8-10 seconds lagging after the 3 minutes.
The following code I am using:
Two classes I am using , one for the Stopwatch implementation & the other for Stopwatch display
StopwatchImplementation.java
/** The timer used to implement the Stopwatch logic. */
private Timer mSWatch = null;
/**
* Starts the Stopwatch.
*/
public void watchStart() {
if (mSWatch != null)
mSWatch .cancel();
mSWatch = new Timer();
mSWatch .schedule(new TimerTask() {
#Override
public void run() {
mListener.updateUIThread();
}
}, 0, 100);
}
/** Runnable The Timer_ tick where the time is updated */
Runnable Timer_Tick = new Runnable() {
public void run() {
updateTime(); // Updates the time , calculates the lap duration
}
};
private int mHours = 0;
/** The mins. */
private int mMins = 0;
/** The secs. */
private int mSecs = 0;
/** The fraction of a sec. */
private int mFSec = 0;
/** The lap hours. */
private int mLapHours = 0;
/** The lap mins. */
private int mLapMins = 0;
/** The lap secs. */
private int mLapSecs = 0;
/** The lap fraction of sec.... 1/10th of a sec*/
private int mLapFSec = 0;
public void updateTime() {
try {
mLapFSec++;
if (mLapFSec >= 10) {
mLapFSec = 0;
mLapSecs++;
if (mLapSecs >= 60) {
mLapSecs = 0;
mLapMins++;
if (mLapMins >= 60) {
mLapMins = 0;
mLapHours++;
}
}
}
mFSec++;
if (mFSec >= 10) {
mFSec = 0;
mSecs++;
if (mSecs >= 60) {
mSecs = 0;
mMins++;
if (mMins >= 60) {
mMins = 0;
mHours++;
}
}
}
}
StopwatchScreen.java
StopwatchImplementation mStopWatch = new StopwatchImplementation(this);
/**
* Update ui thread.
*/
public void updateUIThread() {
StopWatchScreen.this.runOnUiThread(mStopWatch.Timer_Tick);
}
public void startPressed() {
mStopWatch.watchStart();
}
Kindly provide any inputs regarding where the calculation is going wrong.
Thanks in advance.
Warm Regards,
CB
You cannot rely on the scheduling of a TimerTask for precision timing. You have asked for the updateTime method to be called every 100 milliseconds, but the Android system will only adhere to this roughly - it might take 99 or 101 milliseconds before the next time updateTime is called. Because of this you should avoid timing mechanisms which rely on simply increasing a counter.
For this reason you should record the start time, then compare the current time to the start time to get the amount of time elapsed. For instance:
private long startTime;
public void watchStart() {
startTime = SystemClock.elapsedRealtime();
...
}
public void updateTime() {
final long currentTime = SystemClock.elapsedRealtime();
final long elapsedTime = currentTime - startTime;
// convert elapsedTime in seconds, minutes etc
final int seconds = (elapsedTime/1000)%60;
final int minutes = (elapsedTime/(1000*60))%60;
final int hours = (elapsedTime/(100*60*60))%24;
...
}

Categories

Resources