So I have been working with ExoPlayer for streaming content in MP4 Dash File Format, and everything works fine, until I decide to change the Seekbar to a new position. On changing the Seekbar to a new position, the audio plays absolutely fine, but the video is stuck at a frame like a picture. Not sure why it's happening. Any help would be greatly helpful.
Edit:
PlayerView ep;
SimpleExoPlayer player;
boolean secondTouch=false;
boolean isPlaying=false;
boolean isLandscape=false;
long lastTimeTouched;
//ON SCREEN CONTROLS
LinearLayout mcContainer;
ImageButton ivPlay;
ImageButton ivSize;
TextView totalDuration;
RelativeLayout buffer;
SeekBar progress;
int totalTime;
Runnable runnable;
LinearLayout commentsContainer;
Intent i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
getSupportActionBar().hide();
i=getIntent();
setContentView(R.layout.activity_video);
details=findViewById(R.id.textView11);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
isLandscape=getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE;
ep=findViewById(R.id.videoViewPlay);
ivSize=findViewById(R.id.imageButton2);
player = new SimpleExoPlayer.Builder(this).build();
ep.setPlayer(player);
mcContainer=findViewById(R.id.mcContainer);
ivPlay=findViewById(R.id.buttonPlay);
totalDuration=findViewById(R.id.textViewTotalDuration);
buffer=findViewById(R.id.bufferContainer);
progress=findViewById(R.id.seekBarProgress);
ivPlay.setOnClickListener(v -> {
if(isPlaying)
{
player.setPlayWhenReady(false);
isPlaying=false;
ivPlay.setBackgroundResource(android.R.drawable.ic_media_play);
}
else
{
player.setPlayWhenReady(true);
isPlaying=true;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
ivPlay.setBackgroundResource(android.R.drawable.ic_media_pause);
}
});
ep.setOnClickListener(v -> {
ViewGroup.LayoutParams params = mcContainer.getLayoutParams();
params.height = Tools.convertDpToPx(this,48);
mcContainer.setLayoutParams(params);
lastTimeTouched=System.currentTimeMillis();
if(secondTouch==true){
params = mcContainer.getLayoutParams();
params.height = 0;
mcContainer.setLayoutParams(params);
}
secondTouch=!secondTouch;
});
progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser) {
player.setPlayWhenReady(false);
player.seekTo(progress * 1000);
player.setPlayWhenReady(true);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "eTuitionPro"), bandwidthMeterA);// This is the MediaSource representing the media to be played.
String media=Uri.parse(Tools.baseAddress+"VIDEO/"+i.getStringExtra("ModuleID")+"/index.php").buildUpon().appendQueryParameter("token", Tools.token).build().toString();//NEEDS CHANGE
MediaSource videoSource =new DashMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(media));// Prepare the player with the source.
player.prepare(videoSource);
Handler handler = new Handler();
runnable = () -> {
progress.setProgress(((int)(player.getCurrentPosition()/1000)));
if(((int)(player.getCurrentPosition()/1000))==progress.getMax())
{
player.setPlayWhenReady(false);
isPlaying=false;
ivPlay.setBackgroundResource(android.R.drawable.ic_media_play);
progress.setProgress(0);
}
else
handler.postDelayed(runnable, 1000);
};
player.addListener(new Player.EventListener() {
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch(playbackState)
{
case ExoPlayer.STATE_READY:
totalTime = (int)(player.getDuration()/1000);
progress.setMax(totalTime);
totalDuration.setText(msToString(player.getDuration()));
buffer.setVisibility(View.INVISIBLE);
handler.postDelayed(runnable, 0);
break;
case ExoPlayer.STATE_BUFFERING:
buffer.setVisibility(View.VISIBLE);
break;
}
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
});
...
In the above program I tried to make a custom Control Player UI for the ExoPlayer. Not sure if I did anything wrong, if there is a better way to do this, I will honoured to know more.
Related
I want to change the brightness using seekBar it changes but the notification brightness bar progress is not the same as the progress value.
public class MainActivity extends AppCompatActivity {
private SeekBar seekBright;
private TextView txtProgress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBright=findViewById(R.id.seekBright);
txtProgress=findViewById(R.id.txtProgress);
if(Build.VERSION.SDK_INT> Build.VERSION_CODES.M) {
boolean canWriteSettings = Settings.System.canWrite(this);
if (!canWriteSettings) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
startActivity(intent);
}
}
seekBright.setMax(255);
seekBright.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
setScreenBrightness(MainActivity.this,i);
txtProgress.setText(i+"/"+seekBar.getMax
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// finally use the below method to set the brightness
new LoadApplications().execute();
}
public void setScreenBrightness(Context mContext, int brightnessValue){
// Make sure brightness value between 0 to 255
if(brightnessValue >= 0 && brightnessValue <= 255){
Settings.System.putInt(
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS,
brightnessValue
);
}
}
}
This Output of my code
When set to 0 progress is displayed anywhere.
when set to 1 it displays proper
** Screenshot emulator version I SDK-33**
I had this problem too. I did a lot of searches and built it together:
public class Brightness extends AppCompatActivity {
SeekBar seekBar;
TextView br_value;
Handler handler = new Handler();
Runnable refresh;
public static int CODE_WRITE_SETTINGS_PERMISSION = 42;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brightness);
seekBar = findViewById(R.id.seekBar);
br_value = findViewById(R.id.brightness_status_info);
int brightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0);
seekBar.setMax(getMaxBrightness(getApplicationContext(), brightness));
seekBar.setProgress(brightness);
int br_in_perc = seekBar.getProgress();
br_value.setText(String.valueOf(100*br_in_perc/seekBar.getMax())+" %");
writeSettings();
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Context context = getApplicationContext();
boolean canWrite = Settings.System.canWrite(context);
if (canWrite) {
int sBrightness = seekBar.getMax()-(seekBar.getMax()-progress);
Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, sBrightness);
refresh = new Runnable() {
#SuppressLint("SetTextI18n")
public void run() {
int br_in_perc = seekBar.getProgress();
br_value.setText(String.valueOf(100*br_in_perc/seekBar.getMax())+" %");
handler.postDelayed(refresh, 100);
}
};
handler.post(refresh);
} else {
br_value.setText(R.string.write_settings_not_allowed);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public int getMaxBrightness(Context context, int defaultValue){
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if(powerManager != null) {
Field[] fields = powerManager.getClass().getDeclaredFields();
for (Field field: fields) {
//https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/PowerManager.java
if(field.getName().equals("BRIGHTNESS_ON")) {
field.setAccessible(true);
try {
return (int) field.get(powerManager);
} catch (IllegalAccessException e) {
return defaultValue;
}
}
}
}
return defaultValue;
}
public void writeSettings() {
boolean canWrite = Settings.System.canWrite(getApplicationContext());
if (!canWrite) {
AlertDialog.Builder writeSettingsDialog = new AlertDialog.Builder(Brightness.this, R.style.AlertDialog);
writeSettingsDialog.setTitle(R.string.bright_alert_title)
.setMessage(R.string.bright_alert_text)
.setCancelable(false)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
Toast.makeText(Brightness.this, R.string.settings_cancelled, Toast.LENGTH_SHORT).show();
}
});
AlertDialog alertDialog = writeSettingsDialog.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.black));
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.black));
}
}
}
At the end of the code is AlertDialog which checks for permission to write settings.
Hope it helps ๐๐
Im creating an app in android studio where I want 10 clips to be played at the same time side by side. Im having some problems with some lags already at three clips and I wounder if Im better off using threads? In that case how?
Any hint would be very much apreciated
Here is my code so far. I know it is not very efficient and I am better off using an array of a player object for example but Im just testing so far:
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private MediaPlayer mp1, mp2, mp3;
private TextureView tv1, tv2, tv3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = findViewById(R.id.textureView1);
tv2 = findViewById(R.id.textureView2);
tv3 = findViewById(R.id.textureView3);
tv1.setSurfaceTextureListener(this);
tv2.setSurfaceTextureListener(this);
tv3.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Surface surface = new Surface(surfaceTexture);
mp1 = MediaPlayer.create(this, R.raw.a7);
mp1.setSurface(surface);
// mp1.prepareAsync(); //
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp1) {
mp1.start();
}
});
Surface surface2 = new Surface(surfaceTexture);
mp2 = MediaPlayer.create(this, R.raw.a9);
mp2.setSurface(surface2);
// mp1.prepareAsync(); //
mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp2) {
mp2.start();
}
});
Surface surface3 = new Surface(surfaceTexture);
mp3 = MediaPlayer.create(this, R.raw.a10);
mp3.setSurface(surface3);
// mp1.prepareAsync(); //
mp3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp3) {
mp3.start();
}
});
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
#Override
protected void onPause() {
if (mp1 != null && mp1.isPlaying()) {
mp1.pause();
}
super.onPause();
}
#Override
protected void onResume() {
if (mp1 != null) {
mp1.start();
}
super.onResume();
}
#Override
protected void onDestroy() {
if (mp1 != null) {
mp1.stop();
mp1.release();
mp1 = null;
}
super.onDestroy();
}
}
You should play media in a different non-ui thread. like this:-
public class MediaService extends Service {
private MediaPlayer mp1, mp2, mp3;
private static final String ACTION_START = TAG + ".ACTION_START";
private IBinder mBinder = new MyBinder();
private MediaPlayer.OnPreparedListener mMediaPrepared = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "MediaPlayer.onPrepared");
onCommandPlay(mp);
}
};
#Override
public IBinder onBind(Intent intent) {
Log.v(TAG, "onBind");
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
m1 = MediaPlayer.create(this, R.raw.a1);
m2 = MediaPlayer.create(this, R.raw.a2);
m3 = MediaPlayer.create(this, R.raw.a9);
}
#Override
public void onDestroy() {
super.onDestroy();
if (m1 != null) m1 .release();
if (m2 != null) m2 .release();
if (m3 != null) m3 .release();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
Log.d(TAG, "onStartCommand: " + intent.getAction());
if (ACTION_START.equals(action)) {
onCommandStart();
return START_STICKY;
}
stopSelf();
return Service.START_STICKY_COMPATIBILITY;
}
/**
* Performs actions related to media player when Service onStartCommand method is called
*
*/
private void onCommandStart() {
// Create Notifications with remote views
mNotification = new NotificationCompat.Builder(this).setTicker("Media Service started...")
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(collapsed)
.setAutoCancel(false)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_ID, mNotification);
startPlaying();
}
private void onCommandPlay(MediaPlayer mp) {
try {
mp.start();
} catch (IllegalStateException e) {
Log.e(TAG, "onCommandPlay", e);
}
}
/**
* Start playing the provided media item
*
*/
private void startPlaying() {
mCurrent = item;
try {
mp1.reset();
mp1.setOnPreparedListener(mMediaPrepared);
mp2.reset();
mp2.setOnPreparedListener(mMediaPrepared);
mp3.reset();
mp3.setOnPreparedListener(mMediaPrepared);
AssetFileDescriptor afd1 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a9););
AssetFileDescriptor afd2 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a10););
AssetFileDescriptor afd3 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a8););
mp1.setDataSource(afd1 .getFileDescriptor(), afd1 .getStartOffset(), afd1.getLength());
mp2.setDataSource(afd2 .getFileDescriptor(), afd2 .getStartOffset(), afd2 .getLength());
mp3.setDataSource(afd3 .getFileDescriptor(), afd3 .getStartOffset(), afd3 .getLength());
mp1.prepareAsync();
mp2.prepareAsync();
mp3.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "startPlaying", e);
}
}
public class MyBinder extends Binder {
public MediaService getService() {
return MediaService.this;
}
}
}
then start the service from Activity like this:
Intent intent = new Intent(context, MediaService.class);
intent.setAction(ACTION_START);
startServie(intent);
You should also handle different media playing use-cases. You can refer this link for more.
I am trying to create a flashlight app with a strobe effect. My goal is that I can turn ON/OFF the flashlight with a switch Btn and increase the strobe frequency with a seekbar. If the seekbar value is 0 and the switch Btn is ON the flashlight should be ON (without any strobe). But right now it is still blinking (strobe effect ON) if the seekbar value is 0. Do you know how I can change that?
Here is some of the code which I think is important (I really can't find the part which keeps the stobe effect still on:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySwitch = (Switch) findViewById(R.id.mySwitch);
//listener to check changes in state
mySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
turnOnOff(isChecked);
}
});
skBar = (SeekBar) findViewById(R.id.seekBar);
skBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
freq = progress;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
#Override
protected void onResume() {
super.onResume();
try {
cam = Camera.open();
camParams = cam.getParameters();
cam.startPreview();
hasCam = true;
}catch(Exception e){
}
}
private void turnOnOff(boolean on){
if(on) {
if(freq != 0){
sr = new StroboRunner();
t = new Thread(sr);
t.start();
return;
}else{
camParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
}
}else if(!on){
if(t != null){
sr.stopRunning = true;
t =null;
return;
}else{
camParams.setFlashMode(Parameters.FLASH_MODE_OFF);
}
}
cam.setParameters(camParams);
cam.startPreview();
}
private class StroboRunner implements Runnable {
boolean stopRunning = false;
#Override
public void run() {
Camera.Parameters paramsOn = cam.getParameters();
Camera.Parameters paramsOff = camParams;
paramsOn.setFlashMode(Parameters.FLASH_MODE_TORCH);
paramsOff.setFlashMode(Parameters.FLASH_MODE_OFF);
try {
while (!stopRunning) {
cam.setParameters(paramsOn);
cam.startPreview();
Thread.sleep(100 - freq);
cam.setParameters(paramsOff);
cam.startPreview();
Thread.sleep(100 - freq);
}
}catch(Exception e){
}
}
}
}
I've created a simple music player in Android which has a seekbar which displays the current position in the song playing. The forward, rewind, play and pause functions work correctly. What I am trying to do is have the seekbar actually move the position within the song. (at present the seekbar does not change the position within the song. Heres my code
public class MusicPlayerA extends Activity {
private MediaPlayer mediaPlayer;
public TextView songName, duration;
private double timeElapsed = 0, finalTime = 0;
private int forwardTime = 2500, backwardTime = 2500;
private Handler durationHandler = new Handler();
private SeekBar seekbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set the layout of the Activity
setContentView(R.layout.musicplayerview);
//initialize views
initializeViews();
}
#Override
protected void onPause() {
super.onPause();
if (mediaPlayer != null) {
mediaPlayer.pause();
if (isFinishing()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
}
public void initializeViews(){
songName = (TextView) findViewById(R.id.songName);
mediaPlayer = MediaPlayer.create(this, R.raw.druidsad);
finalTime = mediaPlayer.getDuration();
duration = (TextView) findViewById(R.id.songDuration);
seekbar = (SeekBar) findViewById(R.id.seekBar);
songName.setText("Druids Ad");
seekbar.setMax((int) finalTime);
seekbar.setClickable(true);
}
// play mp3 song
public void play(View view) {
mediaPlayer.start();
timeElapsed = mediaPlayer.getCurrentPosition();
seekbar.setProgress((int) timeElapsed);
durationHandler.postDelayed(updateSeekBarTime, 100);
}
//handler to change seekBarTime
private Runnable updateSeekBarTime = new Runnable() {
public void run() {
//get current position
timeElapsed = mediaPlayer.getCurrentPosition();
//set seekbar progress
seekbar.setProgress((int) timeElapsed);
//set time remaining
double timeRemaining = finalTime - timeElapsed;
duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));
//repeat yourself that again in 100 miliseconds
durationHandler.postDelayed(this, 100);
}
};
// pause mp3 song
public void pause(View view) {
mediaPlayer.pause();
}
// go forward at forwardTime seconds
public void forward(View view) {
//check if we can go forward at forwardTime seconds before song endes
if ((timeElapsed + forwardTime) <= finalTime) {
timeElapsed = timeElapsed + forwardTime;
//seek to the exact second of the track
mediaPlayer.seekTo((int) timeElapsed);
}
}
// go backwards at backwardTime seconds
public void rewind(View view) {
//check if we can go back at backwardTime seconds after song starts
if ((timeElapsed - backwardTime) > 0) {
timeElapsed = timeElapsed - backwardTime;
//seek to the exact second of the track
mediaPlayer.seekTo((int) timeElapsed);
}
}
// handler for back button used on music player screen
public void BackButton2 (View view) {
MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
mMediaPlayer.start();
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(200);
Intent mus = new Intent (this, Music.class);
startActivity(mus);
}
// handler for home button used on all screens
public void BackButton (View view) {
MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
mMediaPlayer.start();
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(200);
Intent mn = new Intent (this, Music.class);
startActivity(mn);
}
}
Its easy. Follow these steps :-
Add a seek bar change Listener.
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int seeked_progess;
#Override
public void onProgressChanged(final SeekBar seekBar, int progress, boolean fromUser) {
seeked_progess = progress;
seeked_progess = seeked_progess * 1000;
if (fromUser) {
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Now in if(fromUser), U need to add the implementation.
if (fromUser) {
Runnable mRunnable = new Runnable() {
#Override
public void run() {
int min, sec;
if (mediaPlayer != null /*Checking if the
music player is null or not otherwise it
may throw an exception*/) {
int mCurrentPosition = seekBar.getProgress();
min = mCurrentPosition / 60;
sec = mCurrentPosition % 60;
Log.e("Music Player Activity", "Minutes : "+min +" Seconds : " + sec);
/*currentime_mm.setText("" + min);
currentime_ss.setText("" + sec);*/
}
mHandler.postDelayed(this, 1000);
}
};
mRunnable.run();}
At last add this in onStopTrackingTouch()
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo(seeked_progess);
}
});
Note :-
mHandler in a global variable.
Initialize it as follows.
Handler mHandler = new Handler();
Secondly currentime_mm and currentime_ss are text views which display the current seek time of the seek bar.
and most Important,
dont forgot to add these when a song starts
seekBar.setProgress(0);// To set initial progress, i.e zero in starting of the song
seekBar.setMax(mediaDuration);// To set the max progress, i.e duration of the song
Put this code inside onCreate() method
seekbar.setMax(mediaPlayer.getDuration());
seekbar.setProgress(mediaPlayer.getCurrentPosition());
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run()
{
seekbar.setProgress(mediaPlayer.getCurrentPosition());
}
},0,1000);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b)
{
mediaPlayer.seekTo(i);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
What Punam did is good but add a condition in your "onProgressChanged" function like this:
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b)
{
if(b)
mediaPlayer.seekTo(i);
}
In my SMS app, I have a dialog that opens when the user clicks on an attached image to expand it.
Everything worked fine until I decided to add animations. This dialog has 3 buttons (one close ImageButton in the top right corner and two buttons in a bottom bar of the dialog). When the user clicks on the image, the buttons anime out/in. This all works fine except the buttons are still clickable even after they're hidden.
Before Animations:
After Animations:
My code for the dialog below:
// Declare these here to increase scope. (Listeners)
private static boolean ContainerChanged;
private static boolean ActionsHidden;
private static boolean AnimStarted;
private static boolean closeAnimFinished;
private static boolean barAnimFinished;
private void showExpandedImageDialog(Uri imgUri)
{
// Initialize Dialog
final Dialog dialog = new Dialog(ActivitySend.this, R.style.FullHeightDialog);
dialog.setContentView(R.layout.dialog_attachment_image_send);
// Initialize Views
final RelativeLayout Container = (RelativeLayout) dialog.findViewById(R.id.Container);
final LinearLayout actions = (LinearLayout) dialog.findViewById(R.id.Actions);
final ImageButton btnClose = (ImageButton) dialog.findViewById(R.id.btnClose);
Button btnReplace = (Button) dialog.findViewById(R.id.btnReplace);
Button btnRemove = (Button) dialog.findViewById(R.id.btnRemove);
ImageView image = (ImageView) dialog.findViewById(R.id.Image);
// Load Image & Make Zoomable
PhotoViewAttacher mAttacher = new PhotoViewAttacher(image);
image.setImageURI(imgUri);
mAttacher.update();
// Get animations ready
final Animation fiCloseAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.fade_in);
fiCloseAnim.setFillEnabled(true);
fiCloseAnim.setFillAfter(true);
final Animation foCloseAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.fade_out);
foCloseAnim.setFillEnabled(true);
foCloseAnim.setFillAfter(true);
final Animation dBarAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.slide_down);
dBarAnim.setFillEnabled(true);
dBarAnim.setFillAfter(true);
final Animation uBarAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.slide_up);
uBarAnim.setFillEnabled(true);
uBarAnim.setFillAfter(true);
// Reset static variables
ActionsHidden = false;
AnimStarted = false;
closeAnimFinished = false;
barAnimFinished = false;
// Initialize listeners
AnimationListener closeAnimListener = new AnimationListener()
{
#Override
public void onAnimationEnd(Animation animation)
{
closeAnimFinished = true;
if (closeAnimFinished && barAnimFinished)
{
AnimStarted = false;
closeAnimFinished = false;
barAnimFinished = false;
if (ActionsHidden)
{
actions.setVisibility(View.VISIBLE);
btnClose.setVisibility(View.VISIBLE);
}
else
{
actions.setVisibility(View.GONE);
btnClose.setVisibility(View.GONE);
}
ActionsHidden = !ActionsHidden;
}
}
#Override
public void onAnimationRepeat(Animation animation)
{
// Nothing
}
#Override
public void onAnimationStart(Animation animation)
{
AnimStarted = true;
}
};
AnimationListener barAnimListener = new AnimationListener()
{
#Override
public void onAnimationEnd(Animation animation)
{
barAnimFinished = true;
if (closeAnimFinished && barAnimFinished)
{
AnimStarted = false;
closeAnimFinished = false;
barAnimFinished = false;
if (ActionsHidden)
{
actions.setVisibility(View.VISIBLE);
btnClose.setVisibility(View.VISIBLE);
}
else
{
actions.setVisibility(View.GONE);
btnClose.setVisibility(View.GONE);
}
ActionsHidden = !ActionsHidden;
}
}
#Override
public void onAnimationRepeat(Animation animation)
{
// Nothing
}
#Override
public void onAnimationStart(Animation animation)
{
AnimStarted = true;
}
};
// Set listeners
fiCloseAnim.setAnimationListener(closeAnimListener);
foCloseAnim.setAnimationListener(closeAnimListener);
dBarAnim.setAnimationListener(barAnimListener);
uBarAnim.setAnimationListener(barAnimListener);
// Actions Appear/Disappear onTap (Animate)
mAttacher.setOnPhotoTapListener(new OnPhotoTapListener()
{
#Override
public void onPhotoTap(View view, float x, float y)
{
if (!AnimStarted && ActionsHidden)
{
actions.startAnimation(uBarAnim);
btnClose.startAnimation(fiCloseAnim);
}
else if (!AnimStarted)
{
actions.startAnimation(dBarAnim);
btnClose.startAnimation(foCloseAnim);
}
}
});
// Make dialog square
ContainerChanged = false;
ViewTreeObserver vto = Container.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
public boolean onPreDraw()
{
// Set boolean to save processing power
if (!ContainerChanged)
{
int width = Container.getMeasuredWidth();
Container.getLayoutParams().height = width;
ContainerChanged = true;
}
return true;
}
});
// Set button listeners
btnClose.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
dialog.dismiss();
}
});
btnReplace.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
}
});
btnRemove.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
}
});
// Show dialog
dialog.show();
}
Everything works perfectly if I remove the animations and only use view.setVisibility(View.GONE) but I really like the animations...
Any ideas on what I could do to fix this?
I could probably use view.setClickable(false); but I'm sure there's a better solution than that.
You can do it like this:
Let your activity implement AnimationListener. Then there will be an overridden method public void onAnimationEnd(Animation arg0), write setClickable(false) or setEnabled(false) in this method for all three of your buttons, enable them again when you are starting your animation....hope you got me..