Lower continuously my media volume with a button - java

I want to lower (or upper) my media volume in my application when an "OnLongClickEvent" is detected.
Here my sources :
buttongauche.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
playSound(R.raw.volumevoixdiminue);
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,AudioManager.ADJUST_LOWER,AudioManager.FLAG_SHOW_UI);
return true;
}
});
Actually, it's work : when I do a longClick on my "buttongauche", the volume is decreased by 1.
Now I would like to know how could I do if I want to lower the sound continuously (for example, decrease sound by 1 every 2 seconde when the button is down).
My button "buttongauche" has already an "onClickEvent", who do other things (change the index of a menu).
Thanks

Declare field boolean touching = false; that says whether or not you are touching the button and use OnTouchListener to change it. When you start touching also start volumeThread that lowers the volume every 1 second, and dies when you stop touching.
buttongauche.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touching = true;
Thread volumeThread = new Thread() {
public void run() {
while (touching) {
audio.adjustStreamVolume(
AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER,
AudioManager.FLAG_SHOW_UI);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
volumeThread.start();
break;
case MotionEvent.ACTION_UP:
touching = false;
break;
}
return false;
}
});

Related

Send continuous data via bluetooth while button pressed

I want to send data via bluetooth while a button is pressed. I am using an ontouchlistener. After the button down event happens the data transfer is started but when the button up event happens the transfer is not stopped immediately. At the bluetooth receiver side I see a lot of data incoming still after the button is released for a specific amount of time.
I tried to solve this issue with an flag which is evaluate in a while statement in the called methode. But this brings me to the above descriped issue.
Then I tried to solve this via an additional thread which is killed during the button up event. But the result did not changed.
Here is my code. Maybe somebody can help me.
mButtonMoveRight.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
moveRight p = new moveRight();
Thread th = new Thread(p);
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
pressed_right = true;
th.start();
break;
case MotionEvent.ACTION_UP:
pressed_right = false;
th.interrupt();
break;
}
return false;
}
});
private class moveRight implements Runnable
{
#Override
public void run()
{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
while (pressed_right == true) {
if (btSocket != null) {
try {
btSocket.getOutputStream().write("r".toString().getBytes());
} catch (IOException e) {
msg("Error");
}
}
}
}
}

How do I get an image view to continually move across the screen when a button is held down?

I have searched high and low for an answer to this and can't find one anywhere that works.
For my university assignment i need to create an adventure game in android studio. I want it so when I click down and hold an arrow button (so in the case given its the up button), that the ImageView (player) will continually move across the screen until I release the button. Ive tried OnTouchListeners and mouse events using ACTION_UP and ACTION_DOWN and that works but not for what i need as it still only moves one step when clicked.
ImageView IV_player;
Button ButtonUp;
IV_player = (ImageView) findViewById(R.id.IV_player);
ButtonUp = (Button) findViewById(R.id.ButtonUp);
ButtonUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
IV_player.setY(IV_player.getY() - 32);
}
});
Treat your touch listener like a state machine. When an ACTION_DOWN event occurs, start doing whatever action you want to do. When an ACTION_UP/ACTION_CANCEL event occurs stop your action. So how do you go about implementing this?
Your state flag can be a simple boolean:
boolean shouldCharacterMove = false;
Define your touch listener for the view.
ButtonUp.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
setShouldCharacterMove(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
setShouldCharacterMove(false);
break;
}
return true;
}
});
Before we define setShouldCharacterMove we need to figure out a way to move items. We can do this through a Runnable that runs after X milliseconds.
private final Runnable characterMoveRunnable = new Runnable() {
#Override
public void run() {
float y = IV_player.getTranslationY();
IV_player.setTranslationY(y + 5); // Doesn't have to be 5.
if (shouldCharacterMove) {
IV_player.postDelayed(this, 16); // 60fps
}
}
};
Now we can define setShouldCharacterMove:
void setShouldCharacterMove(boolean shouldMove) {
shouldCharacterMove = shouldMove;
IV_player.removeCallbacks(characterMoveRunnable);
if (shouldMove) {
IV_player.post(characterMoveRunnable);
}
}

How to properly set custom long click listener?

I'm trying to set my own long click listener on Unlock button. Whenever I press the Unlock button it summarize duration and I can unlock permanently clicking.
Unlock.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(final View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Unlock.setText("Press to unlock");
isLongPress = true;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (isLongPress) {
Unlock();
}
}
}, longClickDuration); //amount of time of long click
} else if (event.getAction() == MotionEvent.ACTION_UP) {
Unlock.setText("Unlock");
isLongPress = false;
}
return true;
}
});
}catch (Exception e) {
// TODO: handle exception
}
}
If you want to just handle long clicks consider using the following code:
Unlock.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
your code
}
});
But if the Unlock(); should be invoked after a certain (customizable) amount of time, you should measure this time in MotionEvent.ACTION_UP handler. As #Attaullah Khan said, use SystemClock.elapsedRealtime() system timer to correctly count number of milliseconds at two moments (when button was pressed and released) and if the time is greater than longClickDuration then invoke Unlock
The handler.postDelayed that you call in MotionEvent.ACTION_DOWN handler just invokes a check of pressed state after longClickDuration interval and if your button gets suddenly pressed at that moment, the verification passes that is not correct

Double Tap in android View

In a view I want to detect both single tap and double tap. It works fine with me. I can detect both single and double tap. Please find my code
#Override
public boolean onTouch(View view, MotionEvent me) {
// No dragging during animation at the moment.
// TODO: Stop animation on touch event and return to drag mode.
boolean result = true;
result = gestureDetector.onTouchEvent(me);//return the double tap events
if(result)
return false;
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
private String fileName;
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
// event when double tap occurs
#Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
if(player!=null && player.isPlaying())
{
player.stop();
}
else
{
setFileName(x);
player = new AudioPlayer(fileName);
player.play();
}
return true;
}
}
I am doing some code in Action_UP event. So even when I do a double tap, for the first tap the ACTION_UP event is called and the corresponding code is executed. I want to prevent this from happening. How can I do this. I just want to make sure that the ACTION_UP is called only when the user is done with his gesture. Not immediately after his partial gesture . In this case its being called on finger up of first tap.
How can I make this work in android?
Thanks
According to gesture listener documentation, you need to return true for onSingleTapConfirmed & onDoubleTap. Otherwise the event is not consumed and gestureDetector.onTouchEvent(me); returns false.

How to determine a long touch on android?

I am looking for a way for when a user long touches a mapview (lets say for 1000ms) that i can some how do a certain action.
How would i go about judging how long a user long touches a mapsview(or any view).
It would be similar to android google maps app, when you long touch, it brings up a balloon overlay item.
Edit added
mapView.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
Toast.makeText(mapView.getContext(), "Hello 123", 2000);
return false;
}
});
the above does not work... any ideas why?
Edit added
This is what i am trying at the moment, but it does not seem to work, even if i only press on the phone, it says the event is an action_move,
i am using an inner class in my MapActivity
private long startTime=0;
private long endTime=0;
class MapOverlay extends Overlay {
#Override
public boolean onTouchEvent(MotionEvent ev, MapView mapView) {
if(ev.getAction() == MotionEvent.ACTION_DOWN){
//record the start time
startTime = ev.getEventTime();
Log.d("LC", "IN DOWN");
}else if(ev.getAction() == MotionEvent.ACTION_UP){
//record the end time
endTime = ev.getEventTime();
Log.d("LC", "IN UP");
}else if(ev.getAction() == MotionEvent.ACTION_MOVE){
Log.d("LC", "IN move");
endTime=0;
}
//verify
if(endTime - startTime > 1000){
//we have a 1000ms duration touch
//propagate your own event
Log.d("LC", "time touched greater than 1000ms");
Toast.makeText(getBaseContext(), "Hello 123", Toast.LENGTH_SHORT).show();
startTime=0;
endTime=0;
return true; //notify that you handled this event (do not propagate)
}
return false;//propogate to enable drag
}
}
and here is my error log that does not make any sense to me
06-29 14:29:55.509: DEBUG/LC(7693): IN move
06-29 14:29:56.149: DEBUG/LC(7693): IN UP
06-29 14:29:56.149: DEBUG/LC(7693): 6346707 6349261
06-29 14:29:56.149: DEBUG/LC(7693): time touched greater than 1000ms
the end time should be set to zero...but it is not...any idea why?
This is how do you normally create an onLongClickListener. Try this:
mapView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View arg0) {
Toast.makeText(mapView.getContext(), "Hello 123", 2000);
return false;
}
});
Reference to your edit:
This might be the way to get what you want.
private final Handler handler = new Handler();
private final Runnable runnable = new Runnable() {
public void run() {
checkGlobalVariable();
}
};
// Other init stuff etc...
#Override
public void onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
// Execute your Runnable after 1000 milliseconds = 1 second.
handler.postDelayed(runnable, 1000);
mBooleanIsPressed = true;
}
if(event.getAction() == MotionEvent.ACTION_UP) {
if(mBooleanIsPressed) {
mBooleanIsPressed = false;
handler.removeCallbacks(runnable);
}
}
}
And now you can check with checkGlobalVariable function:
if(mBooleanIsPressed == true)
This is how you can handle this case. Good luck.
Your are probably looking for a normal long click?
You will have to set your view to be long clickable by adding android:longClickable to your views xml, or by calling setLongClickable(true).
Then you can add an OnLongClickListener to the view.
I dont know of a way to determine exactly how long the long click is. But the default long click is the same as the google maps long click that you mentioned.
OnLongClickListener
You can set up a longClickListener and a touchListener. Add a boolean class data member variable longClicked and set it to false initially. This is how you can set the longClickListener.
view.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
longClicked = true;
return false;
}
});
For touchListener
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(longClicked){
//Do whatever you want here!!
longClicked = false;
}
return false;
}
});
It will give you the same effect as google maps long click. Hope it helps.
use System.currentTimeMillis() instead of ev.getEventTime();
When MotionEvent.ACTION_UP, endTime will be set to ev.getEventTime(), this make setting endTime to zero when MotionEvent.ACTION_MOVE be not affect.
Instead of setting endTime to zero, you should set startTime to ev.getEventTime()
This is how I use long and short touches
View.setOnTouchListener(new View.OnTouchListener() {
double firsttouch=0;
boolean isup=false;
int millistotouch=1000;
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction()==MotionEvent.ACTION_DOWN) {
firsttouch = (double) System.currentTimeMillis();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (!isup) {
//
// Do your long click work
//
}
else
{
firsttouch=0;
isup=false;
}
}
}
}, millistotouch);
return true;
}
if (motionEvent.getAction()==MotionEvent.ACTION_UP) {
if (((double) System.currentTimeMillis()-firsttouch)<millistotouch)
{
isup=true;
//
// Do your short click work
//
}
}
return false;
}
});

Categories

Resources