Is it possible to set the beginning and the end of an open song in the android audio player?
So far I'am tried to get this with a range seekbar (two blue dots on a line that can be adjust) on which user mark the beginning and the end to play and when replay mode is enabled the player will play that marked section over and over again.
Preview
Many thanks for any help.
Here is the logic responsible for playing the song, that is activated when PLAY button is pressed:
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mMediaPlayer != null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
playButton.setText("PLAY");
timer.shutdown();
}else{
mMediaPlayer.start();
playButton.setText("PAUSE");
timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//playProgress();
if (mMediaPlayer != null) {
if (!mSeekBar.isPressed()) {
mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}
}
},10,10, TimeUnit.MILLISECONDS);
}
}
}
});
When button OPEN FILE is pressed:
openButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("audio/*");
startActivityForResult(intent, PICK_FILE);
}
});
The logic responsible for "creating" the player that will form when the song is opened:
public void createMediaPlayer(Uri uri){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mMediaPlayer.setDataSource(getApplicationContext(), uri);
mMediaPlayer.prepare();
title.setText(getNameFromUri(uri));
playButton.setEnabled(true);
mRangeSeekBar.setNotifyWhileDragging(true);
mSeekBar.setMax(mMediaPlayer.getDuration());
mRangeSeekBar.setRangeValues(0, mMediaPlayer.getDuration());
max = mMediaPlayer.getDuration();
mSeekBar.setMax(mMediaPlayer.getDuration());
//mSeekBar.setProgress(0);
long total_secs = TimeUnit.SECONDS.convert(max, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
duration = mins + ":" + secs;
elapse.setText("00:00 / " + duration);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
} catch (IOException e){
title.setText(e.toString());
}
}
Here is code for this double slider that is supposed to set the beginning and end:
mRangeSeekBar.setOnRangeSeekBarChangeListener(new RangeSeekBar.OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
mRangeSeekBar.setNotifyWhileDragging(true);
mMediaPlayer.seekTo(minValue);
max = maxValue;
String infoMax = String.valueOf(max);
Log.i("MAX", infoMax);
}
});
And here for this green bar with one point representing the duration of the song:
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (mMediaPlayer != null){
int millis = mMediaPlayer.getCurrentPosition();
long total_secs = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
elapse.setText(mins + ":" + secs + " / " + duration);
Related
I write in Java music player for Android. It have a special function to trim a fragment of audio with range seekbar. After replay button is turned ON this fragment is looped. It works and selected fragment with range seekbar is played but not always as it would be necessary. Sometimes it gets out of max selected duration and goes to end of song.I can't find the place why this is happening...
Preview
Many thanks for any help and suggestions.
Here is the logic responsible for playing the song, that is activated when PLAY button is pressed:
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mMediaPlayer != null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
playButton.setText("PLAY");
timer.shutdown();
}else{
mMediaPlayer.start();
playButton.setText("PAUSE");
timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
playProgress();
if (mMediaPlayer != null) {
if (!mSeekBar.isPressed()) {
mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}
}
},10,10, TimeUnit.MILLISECONDS);
}
}
}
});
A function that regulates the playback of a fragment in rangeSeekbar
private void playProgress () {
if (mMediaPlayer.getCurrentPosition() == max) {
if(isRepeat == true) {
mMediaPlayer.seekTo(min);
}else{
mMediaPlayer.seekTo(min);
mMediaPlayer.pause();
}
}
if (mMediaPlayer.isPlaying()) {
mRunnable = new Runnable() {
#Override
public void run() {
playProgress();
}
};
mHandler.postDelayed(mRunnable, 0);
}
}
The logic responsible for "creating" the player that will form when the song is opened:
public void createMediaPlayer(Uri uri){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mMediaPlayer.setDataSource(getApplicationContext(), uri);
mMediaPlayer.prepare();
title.setText(getNameFromUri(uri));
playButton.setEnabled(true);
mRangeSeekBar.setNotifyWhileDragging(true);
max = mMediaPlayer.getDuration();
mRangeSeekBar.setRangeValues(0, mMediaPlayer.getDuration());
mSeekBar.setMax(mMediaPlayer.getDuration());
long total_secs = TimeUnit.SECONDS.convert(max, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
duration = mins + ":" + secs;
elapse.setText("00:00 / " + duration);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
} catch (IOException e){
title.setText(e.toString());
}
}
Replay function activated by the REPLAY button
replayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//repeat = false
if(isRepeat){
isRepeat = false;
mMediaPlayer.setLooping(false);
replayButton.setText("Powtórka wyłączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest wyłączony", Toast.LENGTH_SHORT).show();
}else{
isRepeat = true;
mMediaPlayer.setLooping(true);
replayButton.setText("Powtórka włączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest włączony", Toast.LENGTH_SHORT).show();
}
//mediaPlayer.setLooping(true);
// Toast.makeText(PlayerActivity.this, "Repeat if ON", Toast.LENGTH_SHORT).show();
}
});
Here is code for this double slider that is supposed to set the beginning and end:
mRangeSeekBar.setOnRangeSeekBarChangeListener(new RangeSeekBar.OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
//mRangeSeekBar.setNotifyWhileDragging(true);
mMediaPlayer.seekTo(minValue);
max = maxValue;
min = minValue;
String infoMax = String.valueOf(max);
Log.i("MAX", infoMax);
}
});
And here for this green bar with one point representing the duration of the song:
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (mMediaPlayer != null){
int millis = mMediaPlayer.getCurrentPosition();
long total_secs = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
elapse.setText(mins + ":" + secs + " / " + duration);
My SeekBar can work but then it can't auto-run the SeekBar progress
when I clicked on the SeekBar I will auto move to the position with an overlay player. and the runnable thread does not on the SeekBar
the line below is the code of my SeekBar
positionBar.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser && progress != 100) {
player.getDuration();
player.seekTo(progress);
positionBar.setProgress(progress);
Toast.makeText(getApplicationContext(), "seekbar progress: " + progress, Toast.LENGTH_SHORT).show();
}else {
progress = 0;
positionBar.setProgress(progress);
Song nextSong = songCollection.getNextSong(songId);
if(nextSong != null){
songId = nextSong.getId();
title = nextSong.getTitle();
artist = nextSong.getArtist();
fileLink = nextSong.getFileLink();
coverArt = nextSong.getCoverArt();
url = BASE_URL + fileLink;
displaySong(title,artist,coverArt);
stopActivities();
}
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
//
Toast.makeText(getApplicationContext(),"seekbar touch started!", Toast.LENGTH_SHORT).show();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// player.seekTo(musicPostion);
Toast.makeText(getApplicationContext(),"seekbar touch stop!", Toast.LENGTH_SHORT).show();
}
}
);
new Thread(new Runnable() {
#Override
public void run() {
while(player != null){
try{
Message msg = new Message();
msg.what = player.getCurrentPosition();
handler.sendMessage(msg);
positionBar.setProgress(player.getCurrentPosition());
Thread.sleep(1000);
}catch (InterruptedException e){
}
}
}
}).start();
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
int currentPosition = msg.what;
positionBar.setProgress(currentPosition);
}
};`
I make a timer with a count time of 5 seconds, then when I press the exit button the counter automatically stops?
Here is my timer code:
public void startTimer(final long finish, long tick) {
CountDownTimer t;
t = new CountDownTimer(finish, tick) {
public void onTick(long millisUntilFinished) {
long remainedSecs = millisUntilFinished / 1000;
textTimer.setText("" + (remainedSecs / 60) + ":" + (remainedSecs % 60));// manage it accordign to you
}
public void onFinish() {
textTimer.setText("00:00");
Toast.makeText(FloatingVideoWidgetShowService.this, "Waktu Habis", Toast.LENGTH_SHORT).show();
long seek = videoView.getCurrentPosition();
videoView.setKeepScreenOn(false);
stopSelf();
WritableMap args = new Arguments().createMap();
args.putInt("index", index);
args.putInt("seek", (int) seek);
args.putString("url", playingVideo.getString("url"));
args.putString("type", "close");
sendEvent(reactContext, "onClose", args);
onDestroy();
cancel();
}
}.start();
}
And this is my code when pressing the stop / exit button :
floatingWindow.findViewById(R.id.btn_deny).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
long seek = videoView.getCurrentPosition();
videoView.setKeepScreenOn(false);
stopSelf();
WritableMap args = new Arguments().createMap();
args.putInt("index", index);
args.putInt("seek", (int) seek);
args.putString("url", playingVideo.getString("url"));
args.putString("type", "close");
sendEvent(reactContext, "onClose", args);
onDestroy();
}
});
How so when btn_deny is clicked Cuntdowntimer stops and does not force close?
Thanks.
You can't use onDestroy() to close your activity or fragment. Instead, you need to call finish().
To close the CountDownTimer, you need to make it a class scope variable. Prepare the timer at your startTimer then stop the timer by calling t.cancel() like the following code:
public class YourActivity extends Activity {
// Declare the variable to be accessed later.
CountDownTimer t;
...
public void startTimer(final long finish, long tick) {
t = new CountDownTimer(finish, tick) {
...
}.start();
}
private void yourOtherMethod() {
floatingWindow.findViewById(R.id.btn_deny).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(t != null) t.cancel();
...
}
});
}
}
I needed to connect my SeekBar with my MediaPlayer in my App.
I set up the SeekBar via xml like this:
<SeekBar
android:id="#+id/song_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
and followed this SO answer to implement it.
This is my code:
public class Song_main extends AppCompatActivity {
private final int SONG_REQUEST_CODE = 1;
private Uri song;
private TextView selectSong;
private SeekBar seekBar;
private Handler handler;
private MediaPlayer mediaPlayer;
private boolean repeatPressedTwice = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_bar_song_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.song_main_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
seekBar = (SeekBar) findViewById(R.id.song_seekbar);
handler = new Handler();
notSelected();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.song, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.song_plus) {
Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
selectIntent.setType("audio/*");
startActivityForResult(selectIntent, SONG_REQUEST_CODE);
}
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SONG_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
if ((data != null) && (data.getData()!=null)) {
song = data.getData();
setup();
}
}
}
private void notSelected() {
selectSong = (TextView) findViewById(R.id.select_song_textview);
selectSong.setText(getResources().getString(R.string.song_not_selected));
}
public void onPlayButtonClicked(View v) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
pb.setImageResource(R.drawable.pause);
updateSeekBar();
} else {
mediaPlayer.pause();
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
}
public void onControlsClicked(View v) {
if (v.getId() == R.id.fast_forward) {
int pos = mediaPlayer.getCurrentPosition();
pos += 1500;
mediaPlayer.seekTo(pos);
}
else if (v.getId() == R.id.fast_backward) {
int pos = mediaPlayer.getCurrentPosition();
pos -= 1500;
mediaPlayer.seekTo(pos);
}
else if (v.getId() == R.id.skip_backward) {
mediaPlayer.seekTo(0);
}
}
public void onRepeatClicked(View v) {
if (!repeatPressedTwice) {
// TODO: change visual color of repeat button
mediaPlayer.setLooping(true);
Toast.makeText(this, "repeat enabled", Toast.LENGTH_SHORT).show();
repeatPressedTwice = true;
} else {
mediaPlayer.setLooping(false);
}
}
private void setup() {
/* the song has been select setup the interface */
/* displays song name in title */
TextView titleView = (TextView) findViewById(R.id.song_appbar_title);
String songName;
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(song, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
songName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
titleView.setText(songName);
}
/* removes the notSelected String */
selectSong.setVisibility(View.GONE);
/* setup media player */
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(getApplicationContext(), song);
mediaPlayer.prepareAsync();
} catch (IOException e) {
Toast.makeText(this, "file not found", Toast.LENGTH_SHORT).show();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
/* show media player layout */
RelativeLayout mpl = (RelativeLayout) findViewById(R.id.media_player_layout);
mpl.setVisibility(View.VISIBLE);
mediaPlayer.start();
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.pause);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
});
seekBar = (SeekBar) findViewById(R.id.song_seekbar);
seekBar.setMax(mediaPlayer.getDuration());
updateSeekBar();
}
private void updateSeekBar() {
seekBar.setProgress(mediaPlayer.getCurrentPosition()/1000);
handler.postDelayed(runnable, 1000);
}
Runnable runnable = new Runnable() {
#Override
public void run() {
updateSeekBar();
}
};
#Override
public void onStop() {
super.onStop();
if (mediaPlayer!=null)
mediaPlayer.stop();
}
}
The process starts from the onOptionsItemSelected method.
The seekBar behaves correctly, it increments every second. The problem now is that it finishes way before the song finishes.
I tried adding
seekBar.setMax(mediaPlayer.getDuration());
in the setup method, but that causes the bar not to move at all.
You need to define separate Runnable and trigger it every x miliseconds (depends on you) once MediaPlayer starts.
Define a function updateSeekbar like,
private void updateSeekBar() {
audioSeek.setProgress(player.getCurrentPosition());
txtCurrentTime.setText(milliSecondsToTimer(player.getCurrentPosition()));
seekHandler.postDelayed(runnable, 50);
}
And Runnable
Runnable runnable = new Runnable() {
#Override
public void run() {
updateSeekBar();
}
};
Now you just have to call updateSeekbar once when playing starts. In your case:
public void onPlayButtonClicked(View v) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
pb.setImageResource(R.drawable.pause);
updateSeekBar();
} else {
mediaPlayer.pause();
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
}
FYI
Function milliSecondsToTimer works as follows
private String milliSecondsToTimer(long milliseconds) {
String finalTimerString = "";
String secondsString = "";
// Convert total duration into time
int hours = (int) (milliseconds / (1000 * 60 * 60));
int minutes = (int) (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliseconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
// Add hours if there
if (hours > 0) {
finalTimerString = hours + ":";
}
// Prepending 0 to seconds if it is one digit
if (seconds < 10) {
secondsString = "0" + seconds;
} else {
secondsString = "" + seconds;
}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
// return timer string
return finalTimerString;
}
UPDATE
You have called setMax at the wrong place. Update setup() function as follows
private void setup() {
/* the song has been select setup the interface */
/* displays song name in title */
TextView titleView = (TextView) findViewById(R.id.song_appbar_title);
String songName;
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(song, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
songName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
titleView.setText(songName);
}
/* removes the notSelected String */
selectSong.setVisibility(View.GONE);
/* setup media player */
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(getApplicationContext(), song);
mediaPlayer.prepareAsync();
} catch (IOException e) {
Toast.makeText(this, "file not found", Toast.LENGTH_SHORT).show();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
/* show media player layout */
seekBar.setMax(mediaPlayer.getDuration());
RelativeLayout mpl = (RelativeLayout) findViewById(R.id.media_player_layout);
mpl.setVisibility(View.VISIBLE);
mediaPlayer.start();
updateSeekBar();
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.pause);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
});
}
You have implement OnSeekBarChangeListener and in onCreate() add the below line:-
seekBar = (SeekBar) findViewById(R.id.seekBar);
And override the onProgressChanged() method , in this method you can set the progress in the seekbar using the below line:
mPlayer.seekTo(progress);
seekBar.setProgress(progress);
or
After you initialise your MediaPlayer and for example press the play button, you should create an handler and post runnable so you can update your SeekBar (in the UI thread itself) with the current position of your MediaPlayer like this :
private Handler mHandler = new Handler();
//Make sure you update Seekbar on UI thread
MainActivity.this.runOnUiThread(new Runnable(){
#Override
public void run() {
if(mMediaPlayer != null){
int mCurrentPosition = mMediaPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(mCurrentPosition);
}
mHandler.postDelayed(this, 1000);
}
});
and update that value every second.
If you need to update the MediaPlayer's position while user drag your SeekBar you should add OnSeekBarChangeListener to your SeekBar and do it there :
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mMediaPlayer != null && fromUser){
mMediaPlayer.seekTo(progress * 1000);
}
}
});
you need to update your Seek bar when you play a song
public void updateProgressBar() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
});
}
Below Runnable method to update seekbar
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if (MusicService.isRunning()) {
duration = MusicService.getDur();
long currSongPosition = MusicService.getPosn();
totTime.setText(Utility.milliSecondsToTimer(duration));
fromTime.setText(Utility.milliSecondsToTimer(currSongPosition));
int progress = Utility.getProgressPercentage(currSongPosition, duration);
songProgressBar.setProgress(progress);
updateProgressBar();
}
}
};
Using this below function you can get progress percentage from song current position and song duration
public static int getProgressPercentage(long currentDuration, long totalDuration) {
Double percentage;
long currentSeconds = (int) (currentDuration / 1000);
long totalSeconds = (int) (totalDuration / 1000);
percentage = (((double) currentSeconds) / totalSeconds) * 100;
return percentage.intValue();
}
I'm creating a flash light app for android. I'm using service to turn on and off flash. All things are works fine. But when screen locked flash light is automatically turning off and service already running. this happen only device unplugged from charger. when device charging flash light keep turn on after screen locked.How can I avoid this problem.
Here is my FlashLightService.java file
public class FlashLightService extends Service {
Camera camera;
Camera.Parameters parameters;
static boolean isTurnOn;
static int usedTime = 0;
static String TAG = "coretorch_service";
Thread t;
static String formattedTime;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Torch turned on", Toast.LENGTH_SHORT).show();
isTurnOn = true;
t =new Thread(new Runnable() {
#Override
public void run() {
while (isTurnOn){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
usedTime++;
}
usedTime = 0;
}
});
t.start();
camera = Camera.open();
parameters = camera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
camera.startPreview();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameters);
camera.stopPreview();
camera.release();
isTurnOn = false;
super.onDestroy();
Toast.makeText(this, "Torch turned off", Toast.LENGTH_SHORT).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public static boolean getFlashStatus() {
return isTurnOn;
}
public static String getUsedTime(){
formattedTime = toTimeFormat(usedTime);
return formattedTime;
}
static String toTimeFormat(int secs){
String time;
int mins;
int seconds;
if (secs < 60){
time = String.valueOf(secs) + " sec";
}
else {
mins = (secs / 60);
seconds = (secs - (mins * 60));
time = String.valueOf(mins) + " mins " + String.valueOf(seconds) + " sec";
}
return time;
}
}
#Override
protected void onPause() {
Camera.open().getParameters().setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
};
Can you do something like this? I have never played with camera