Is it possible to implement a fast forward button using the onLongClick button event?
EDIT
i used runnable inside the onlongclicklistner and adding the code for reference who needs :)
Button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final Runnable r = new Runnable()
{
public void run()
{//do the forwarding logic here
if(Button.isPressed()){
Button.postDelayed(this, 1000); //delayed for 1 sec
}else{
Button.postInvalidate();
Button.invalidate();
}
}
};
Button.post(r);
return true;
}
});
In your onLongClick event, set a member variable (example: mShouldFastForward) to true.
In the rest of your code (perhaps each frame played?) check if mShouldFastForward == true; if so, perform a fast-forward on that frame.
Use an onTouch event to capture the MotionEvent.ACTION_UP to set mShouldFastForward to false.
I have done it in this project (the project is not finished (ie polished) but fast forward works):
https://bitbucket.org/owentech/epileptic-gibbon-android
Take a look at playerfragment.java :
I handle this by using Threads to fast forward the mediaplayer.
Example code from project:
/*******************************/
/* Fast-Forward button actions */
/*******************************/
ffbutton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
switch (event.getAction() ) {
case MotionEvent.ACTION_DOWN:
arrays.fastforwardpressed = true;
FastForwardThread newFFThread = new FastForwardThread();
arrays.fastforwardfrom = mp.getCurrentPosition();
arrays.fastforwardto = arrays.fastforwardfrom;
newFFThread.start();
break;
case MotionEvent.ACTION_UP:
arrays.fastforwardpressed = false;
mp.seekTo(arrays.fastforwardto);
break;
}
return true;
}
});
public class FastForwardThread extends Thread
{
public FastForwardThread()
{
super("FastForwardThread");
}
public void run()
{
while (arrays.fastforwardpressed == true)
{
arrays.fastforwardto = arrays.fastforwardto + 10000;
int fastforwardseconds = arrays.fastforwardto / 1000;
int hours = fastforwardseconds / 3600, remainder = fastforwardseconds % 3600, minutes = remainder / 60, seconds = remainder % 60;
String Hours = Integer.toString(hours);
String Minutes = Integer.toString(minutes);
String Seconds = Integer.toString(seconds);
if (Hours.length() == 1)
{
Hours = "0" + Hours;
}
if (Minutes.length() == 1)
{
Minutes = "0" + Minutes;
}
if (Seconds.length() == 1)
{
Seconds = "0" + Seconds;
}
arrays.formattedfftime = Hours + ":" + Minutes + ":" + Seconds;
fastforwardHandler.sendEmptyMessage(0);
try
{
sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
Related
public void startCountdownTimer() {
currentCountdown = startCountdown;
// stopTimer=false;
if (stopTimer == true) {
return;
}
for (int i = 1; i <= startCountdown + 1; i++) {
task = new TimerTask() {
#Override
public void run() {
countdownHandler.post(doA);
}
};
countdownTimer = new Timer();
countdownTimer.schedule(task, i * 1000);
}
}
final Runnable doA = new Runnable() {
#Override
public void run() {
//reset timer when switching to another question
if (currentCountdown != -1 && btn_next.getText().equals("CHECK") && stopTimer != true) {
if (currentCountdown == 0) {
relative_stop.setVisibility(View.INVISIBLE);
currentCountdown = startCountdown;
btn_next.setText("NEXT");
toast = Toasty.warning(getApplicationContext(), "Time's UP", 1000);
toast.show();
toast = Toasty.info(getApplicationContext(), correctAnswer, 1000);
toast.show();
countdownTimer.cancel();
countdownTimer.purge();
}
tv_timer.setText("" + currentCountdown);
currentCountdown--;
}
}
};
I'm trying to make a timer that counts down for 10 seconds, it works normally when it runs for the first time, and when it runs consecutively, the timer caused by delay suddenly speeds up.
I have following code in my service.
countDownTimer = new CountDownTimer(60000 * 3, 1000) {
#Override
public void onTick(long l) {
intentDSU.putExtra("remaind", TimeUnit.MILLISECONDS.toSeconds(l));
sendBroadcast(intentDSU);
}
#Override
public void onFinish() {
postHandler();
intentDSU.putExtra("remaind", 0);
sendBroadcast(intentDSU);
countDownTimer.start();
}
};
countDownTimer.start();
That's work fine, but when i try convert seconds to minutes and remaind of seconds on my activity
private void updateGUI(Intent intent){
if(intent.getExtras() != null){
long remaind = intent.getLongExtra("remaind", 0);
if(remaind == 0){
onRefresh();
}
long minutes = TimeUnit.SECONDS.toMinutes(remaind) - (TimeUnit.SECONDS.toHours(remaind)* 60);
long seconds = TimeUnit.SECONDS.toSeconds(remaind) - (TimeUnit.SECONDS.toMinutes(remaind) *60);
MenuItem menuItem = menu.findItem(R.id.action_timer);
if(menuItem != null){
if(minutes > 0){
menuItem.setTitle(String.format("%o min.", minutes));
}
else {
menuItem.setTitle(String.format("%o sec.", seconds));
}
}
}
}
I become notice unusual results, seconds will start 73 instead 60. I haven't idea, what's wrong?
you're code is correct, I quess you get problem in String.format("%o min.", minutes) and here String.format("%o sec.", seconds).
Try to use this.
MenuItem menuItem = menu.findItem(R.id.action_timer);
if(menuItem != null){
if(minutes > 0){
menuItem.setTitle(String.format("%s min.", Long.toString(minutes)));
}
else {
menuItem.setTitle(String.format("%s sec.", Long.toString(seconds)));
}
}
try this
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
long sec=TimeUnit.MILLISECONDS.toSeconds(passmillitimer);
My intention is to create an timer which starts from 00:00:00 and hangs together with a recording function. This recording is done in a service so, the timer is also in the same service. If the app moves to the background, the recording and thus the timer keep on going and the app picks the time up at the onResume with a myService.getTime().
But I experience two strange things. The first is that my timer sometimes goed faster than a second, sometimes slower, sometimes jumps from for example 00:00:04 to 00:00:06 etc. There is no consitency in it. I use the code below, but there might be a better option to solve this? The second is that it is causing a lag on my button, although I am starting it in a service?
SERVICE
//////////TIMER FUNCTION START//////////
private void startTimerClick() {
if (stopped) {
startTime = System.currentTimeMillis() - elapsedTime;
} else {
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer);
mHandler.postDelayed(startTimer, 0);
}
private void pauseTimerClick() {
mHandler.removeCallbacks(startTimer);
stopped = true;
}
private void stopTimerClick() {
mHandler.removeCallbacks(startTimer);
stopped = false;
}
private void startTimer() {
startTimer = new Runnable() {
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
mHandler.postDelayed(this, REFRESH_RATE);
}
};
}
private void updateTimer(float time) {
secs = (long) (time / 1000);
mins = (long) ((time / 1000) / 60);
hrs = (long) (((time / 1000) / 60) / 60);
/*
* Convert the seconds to String and format to ensure it has a leading
* zero when required
*/
secs = secs % 60;
seconds = String.valueOf(secs);
if (secs == 0) {
seconds = "00";
}
if (secs < 10 && secs > 0) {
seconds = "0" + seconds;
}
/* Convert the minutes to String and format the String */
mins = mins % 60;
minutes = String.valueOf(mins);
if (mins == 0) {
minutes = "00";
}
if (mins < 10 && mins > 0) {
minutes = "0" + minutes;
}
/* Convert the hours to String and format the String */
hours = String.valueOf(hrs);
if (hrs == 0) {
hours = "00";
}
if (hrs < 10 && hrs > 0) {
hours = "0" + hours;
}
}
//////////TIMER FUNCTION END////////////
public String getHours(){
return hours;
}
public String getMinutes(){
return minutes;
}
public String getSeconds(){
return seconds;
}
}
ACTIVITY(/FRAGMENT)
private void timerStart() {
handler = new Handler();
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
handler.post(new Runnable() {
#Override
public void run() {
timer.setText(myService.getHours()+":"+myService.getMinutes()+":"+myService.getSeconds());
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
}
You are using Threads both in your Service and in your Activity/Fragment code.
Using threads for time sensitive tasks in Android is a problem because Android is able to significantly delay threads.
I have been using a ScheduledThreadPoolExecutor for a similar task and it worked great.
You are then using it like this:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); // where 1 is the number of needed concurrent threads. 1 should last for your needs.
executor.scheduleWithFixedDelay(new TimerTask() {
// your recurringly executed code here
}, 0, 1, TimeUnit.SECONDS);
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
public class MainActivity extends Activity {
private Button Start, Reset, Stop;
private EditText stop_watch, lblDate, lblTime;
public MainActivity() {
init();
}
private final UpdateClockThread ucThread = new UpdateClockThread();
private final StopwatchThread swThread = new StopwatchThread();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Start = (Button)findViewById(R.id.button1);
Stop = (Button)findViewById(R.id.button3);
Reset = (Button)findViewById(R.id.button2);
stop_watch = (EditText)findViewById(R.id.editText3);
lblTime = (EditText)findViewById(R.id.editText2);
lblDate = (EditText)findViewById(R.id.editText1);
Start.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
startactionPerformed();
}
});
Stop.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
stopactionPerformed();
}
});
Reset.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
resetactionPerformed();
}
});
}
public void init() {
swThread.setDaemon(true);
ucThread.setDaemon(true);
swThread.start();
ucThread.start();
}
/** Listens to the Start/Stop/Resume button. */
void startactionPerformed() {
swThread.go();
//init();
}
void stopactionPerformed() {
swThread.noGo();
}
void resetactionPerformed() {
swThread.reset();
}
/** A thread that updates the current date & time. */
private class UpdateClockThread extends Thread {
/** The actual work of the thread. */
public void run() {
while (true) {
lblTime.setText("ampm");
Calendar now = Calendar.getInstance();
String month = Integer.toString(now.get(Calendar.MONTH)+1);
String date = Integer.toString(now.get(Calendar.DAY_OF_MONTH));
String year = Integer.toString(now.get(Calendar.YEAR));
String hour = Integer.toString(now.get(Calendar.HOUR));
if (hour.equals("0")) hour = "12";
String minute = Integer.toString(now.get(Calendar.MINUTE));
if (minute.length() == 1) minute = "0" + minute;
String second = Integer.toString(now.get(Calendar.SECOND));
if (second.length() == 1) second = "0" + second;
String ampm = now.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";
lblDate.setText(month + "/" + date + "/" + year);
lblTime.setText(hour + ":" + minute + ":" + second + " " + ampm);
try {
sleep(500);
} catch (InterruptedException e) {}
}
}
}
/** A thread that keeps track of the stop watch & updates
* the display accordingly.
*/
class StopwatchThread extends Thread {
/** Whether or not stop watch is running. */
private boolean going = false;
/** Stores elapsed milliseconds of previous runs. */
private long prevElapsed = 0;
/** Stores beginning time of this run. */
private Date startDate = new Date();
/** Returns elapsed time in milliseconds.
*#return The elapsed time
*/
private long elapsedTime() {
return prevElapsed + (going ? new Date().getTime() - startDate.getTime() : 0);
}
/** Changes the number of elapsed milliseconds into a string.
*#param time Number of elapsed milliseconds
*#return The elapsed time as a string.
*/
private String msToString(long time) {
String ms, sec, min;
if (time % 10 >= 5) //round to nearest hundredth
time += 5;
ms = Long.toString(time % 1000);
while (ms.length() < 3)
ms = "0" + ms;
ms = ms.substring(0, ms.length() - 1);
time /= 1000;
sec = Long.toString(time % 60);
if (sec.length() == 1) sec = "0" + sec;
time /= 60;
min = Long.toString(time);
return min + ":" + sec + "." + ms;
}
/** Called when the stop watch is to go.
*/
public void go() {
startDate = new Date();
going = true;
}
/** Called when the stop watch is to stop.
*/
public void noGo() {
prevElapsed = elapsedTime();
going = false;
}
/** Resets the stop watch.
*/
public void reset() {
going = false;
prevElapsed = 0;
}
/** Adds a lap to the list.
*/
/** Main code of the thread.
*/
public void run() {
while (true) {
stop_watch.setText(msToString(elapsedTime()));
yield();
}
}
}
}
What is my app getting force close? There is some error with the thread. But i'm not able to figure it out?
Try make all interaction with UI from threads in runOnUiThread method of Activity http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29
EDIT
private class UpdateClockThread extends Thread {
public void run() {
/* Do somthing expensive */
......
/* Update UI */
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
/* Do UI update */;
lblTime.setText("ampm");
......
}
});
}
}
You should run adb logcat on your developer machine. Usually if you get a force close a traceback is displayed in the log.
Your class StopwatchThread contains the line:
stop_watch.setText(msToString(elapsedTime()));
This will not work, and neither will the UI updates within UpdateClockThread. This is because you cannot modify the UI from a background thread. Your background thread should either:
send a message to a Handler that has been created on the UI thread, so that the Handler then makes the update to the UI, or
you can pass a runnable into runOnUiThread that performs the UI update.
I'm trying to change images on buttons and turn them back to the original image, and to do it one after the other in 4 different images.
I have tried the following code, but it didn't work, the result causes only to one of the images to blink for a milisecond:
ArrayList<Integer> scenario = new ArrayList<Integer>();
...
void delayedPlay(){
// each button should be posted in 1 second spacing
int count = 1;
for (final int btnid : scenario){
// turn off
final Runnable r2 = new Runnable(){
public void run(){
imagebuttons[btnid].setImageBitmap(imagesTurnedOff.get(btnid));
}
};
// turn on and call turn off
Runnable r1 = new Runnable(){
public void run(){
imagebuttons[btnid].setImageBitmap(imagesTurnedOn.get(btnid));
imagebuttons[btnid].postDelayed(r2, 1000);
}
};
// post the above delayed
imagebuttons[btnid].postDelayed(r1, 1000 * count++);
}
}
Can anyone help me, and suggest why it doesn't working for me?
It worked for me. Are you sure that imagesTurnedOn/imagesTurnedOff are returning the correct values?
This solution leaves a lot to be desired in terms of timing -- it will be quite uneven. Perhaps something like this would work better (using an AsyncTask)
public void deplayedPlay2() {
if (mTaskHandler == null) {
mTaskHandler = new AsyncTask<Void, Void, Void>() {
#Override
public Void doInBackground(Void... params) {
long now = System.currentTimeMillis();
try {
for (final int btnid : mScenario) {
Log.d(TAG,
"ON: " + btnid + " (" + (System.currentTimeMillis() - now) + ")");
mButtons[btnid].post(new Runnable() {
public void run() {
mButtons[btnid]
.setBackgroundDrawable(GoodbyeAndroidActivity.this
.getResources()
.getDrawable(
R.drawable.on_icon));
}
});
Thread.sleep(1000);
Log.d(TAG,
"OFF: " + btnid + " (" + (System.currentTimeMillis() - now) + ")");
mButtons[btnid].post(new Runnable() {
public void run() {
mButtons[btnid]
.setBackgroundDrawable(GoodbyeAndroidActivity.this
.getResources()
.getDrawable(
R.drawable.off_icon));
}
});
}
} catch (InterruptedException ex) {
Log.d(TAG, "Interrupted.");
}
return null;
}
#Override
public void onPostExecute(Void param) {
Log.d(TAG, "Done!");
mTaskHandler = null;
}
};
mTaskHandler.execute();
}
}
Don't forget to handle this in onPause():
public void onPause() {
super.onPause();
if (mTaskHandler != null) {
mTaskHandler.cancel(true);
// May want to reset buttons too?
}
}