Android: Letting the touch event through my transparent view (service) - java

I wrote a service class which creates a transparent view (LinearLayout).
If the user is holding down, some music starts to play.
This runs fine, but the problem is that if I am in the android menu or in another app, I am not able to press any buttons. (My view seems to don't let the TouchEvents pass)
I have tried a lot of things like returning false or stopping the interception, but I am still not able to press any gui controls when the service is running.
How do I correctly pass the TouchEvent back to the System?
#Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() ==
MotionEvent.ACTION_UP)
Log.i(TAG, "Action :" + event.getAction() + "\t X :" + event.getRawX()
+ "\t Y :" + event.getRawY());
if(event.getAction() == MotionEvent.ACTION_DOWN) {
if(!mp.isPlaying())
mp.start();
}
if(event.getAction() == MotionEvent.ACTION_UP) {
mp.pause();
}
//View parent = (View) v.getParent().getParent();
//parent.onTouchEvent(event);
v.onTouchEvent(event);
return false;
}

This runs fine, but the problem is that if I am in the android menu or in another app, I am not able to press any buttons. (My view seems to don't let the TouchEvents pass)
This is by design.
How do I correctly pass the TouchEvent back to the System?
You don't. If you have the ability to see a touch event via a system window, that touch event will not be dispatched to another app. This prevents "tapjacking" attacks.

Related

Custom hardware button events/intents

I have a custom device with a custom button and I need to handle an hardware Button Events/Intents:
every time I press the button it generates a PTT Press Action and I need to open my custom application, is there a way to do this?
If by custom device, you mean custom AOSP. Then make sure, it's button bound to events, this should be done with low level device driver configuration. And it's complicated work. Next, make sure you receive your click in next events.
Try to either use dispatch key event on Activity work:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
if (event.getAction() == KeyEvent.ACTION_UP){
enter();
return true;
}}
return super.dispatchKeyEvent(event);
};
On on key event with Android View which is in focus.
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
/* This is a sample for handling the Enter button */
return true;
}
return false;
}

Drag a view onLongClick and start activity onClick

I'm banging my head with this problem which probably is simple but since I'm new to this topic I somehow haven't been able to figure it out yet.
I've successfully implemented dragging a view with onTouch method. I've also successfully implemented onLongClick and onClick methods. But both of these functionalities were implemented separately.
The problem, like the title says is when I want to join these functionalities. I want the onTouch method to be called when a user long clicks a view and I want a new activity to start when a user clicks a view.
Here is the pseudo code:
public class Website extends AppCompatActivity implements View.OnTouchListener{
TextView longpress;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_website);
longpress = (TextView) findViewById(R.id.longpress);
longpress.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view){
//I don't really know how to do this part
onTouch(View view, Motion Event event);
return true;
}
});
longpress.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
//Code for new activity comes here (I know how to do this part)
}
});
}
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction(){
case MotionEvent.ACTION_DOWN:
//Save initial coordinates of view <-- view.getX(), view.getY()
break;
case MotionEvent.ACTION_MOVE:
//Calculate dX and dY and setX and Y of the view (move view)
break;
case MotionEvent.ACTION_UP:
//If view is certain distance away from initial points do something
break;
}
}
}
Like I said, onTouch works on itself if I don't try to call it from onLongClick method. If I try to call onTouch(View view, MotionEvent event) from onLongClick method the problem occurs because onLongClick only receives one out of two arguments onTouch method should receive (onLongClick only receives view argument but it should also receive event argument).
Maybe I'm trying to do this in a totally wrong way but I have been looking at some documentation e.g. https://developer.android.com/training/gestures/ but still won't get an idea what to do.
(I would like to have a similar functionality to notifications on android phones)
So I've come to a solution which might or might not be a good one but for now it serves my functionality. If someone has a better solution and thinks mine is bad in some way please say so.
Here is the code:
boolean flag;
public boolean onTouch(View view, MotionEvent event){
int action = event.getAction() & MotionEvent.ACTION_MASK;
if(action == MotionEvent.ACTION_DOWN){
//do something on a down press
flag = true;
return true;
}
if(action == MotionEvent.ACTION_UP && flag == true){
//do something if we move finger away from screen we
//didn't move the view first
return true;
}
if(action == MotionEvent.ACTION_UP && flag == false){
//do something if we move finger away from screen and we moved
//the view before we moved the finger away from screen
}
if(action == MotionEvent.ACTION_MOVE){
//do something when moving the view
flag = false;
}

Custom gesture detection inside CollapsingToolbarLayout

I'm trying to use a custom view that I've written inside a CollapsingToolbarLayout, but it seems that the touch events are not propagating properly to my custom view with gesture detection. The result is that scrolling and interactions with the view are not working as expected or smoothly. My custom view makes heavy use of GestureDetector.SimpleOnGestureListener
Is it possible to embed a custom view which has it's own touch events inside CollapsingToolbarLayout?
After some investigation, I found that the problem was with onTouchEvent, specifically, you need to requestDisallowInterceptTouchEvent for the parent view so that the paraent view does not process the touch event:
public boolean onTouchEvent(MotionEvent event) {
// Do stuff on touch
// prevent parent container from processing ACTION_MOVE events
if(event.getAction() == MotionEvent.ACTION_MOVE) {
getParent().requestDisallowInterceptTouchEvent(true);
} else if(event.getAction() == MotionEvent.ACTION_CANCEL) {
getParent().requestDisallowInterceptTouchEvent(false);
}
// Do some more stuff
return true;
}

Detecting ACTION_UP after moving finger

Trying to get functionality for an image preview working, where holding the finger over a thumbnail displays the full image. Releasing the finger will make the full image disappear.
This was easy enough to implement, but if the user moves their finger off the ImageView before release, the ACTION_UP will not fire.
#Override
public boolean onTouch(View v, MotionEvent e)
{
if (v.getId() == R.id.gallery_iv_pose_thumb)
{
// This works fine
if (e.getAction() == MotionEvent.ACTION_DOWN)
{
preview.setImageBitmap(galleryAdapter.getGalleryItemFromChildView(v).getImage());
preview.setVisibility(View.VISIBLE);
return true;
}
// This only fires if a finger is released over the initial view
else if (e.getAction() == MotionEvent.ACTION_UP)
{
preview.setVisibility(View.INVISIBLE);
return true;
}
}
I attempted to simply listen to the ACTION_UP event for the entire layout, but this requires to have handled the ACTION_DOWN for the layout as well... which stops me from listening for the ACTION_DOWN event for the thumbnail.
Any help would be appreciated!
If you move outside of the bounds, ACTION_CANCEL will be called.
So this should work:
else if (e.getAction() == MotionEvent.ACTION_UP || e.getAction() == MotionEvent.ACTION_CANCEL)

Android- Swiping Across Multiple Buttons

I've implemented a grid of buttons using a grid layout. I'm trying to allow for a single swipe to activate multiple buttons. When the user touches any one of the buttons, I call a function with the specific button pressed to take the according action. But, currently, I can only activate one button per touch. Multi-touch works, but not a single swipe. The problem is that while the onTouch function is called continuously the view object that I use to determine the button pressed is only updated on the initial touch. What I need to do is get the id's of all of the buttons that were swiped across.
Thanks.
#Override
public boolean onTouch(View v, MotionEvent event)
{
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_MOVE)
{
switch (v.getId())
{
case R.id.padZeroZero:
padTouch(0,0);
break;
case R.id.padZeroOne:
padTouch(0,1);
break;
case R.id.padZeroTwo:
padTouch(0,2);
break;
//There's a lot more cases (it's a 9x8 grid), but they all do the same thing.
}
}
return false;
}

Categories