Android SurfaceView: Better way to tell if screen is touched (java) - android

I need a way to tell if there is at least one finger touching the screen. I had no problem doing this in LibGDX but now I can't do it without it. This is how I have it setup:
public static boolean screenTouched = false;
//This methods is run at 60FPS by the main thread (it's the main game loop)
public static void update(){
//Run other updates...
screenTouched = false;//Called after other updates
}
public boolean onTouchEvent(MotionEvent e){
screenTouched = true;
}
By the way, this is all in the main activity class.
This seems like it would work fine, right? It doesn't, onTouchEvent(MotionEvent e) is only called by android when the user's finger moves on the screen and doesn't care about whether they are just touching it or not. The problem with this is that if the user touches the screen and keeps their finger in place while still touching the screen, onTouchEvent will not be called and screenTouched will stay false. Anyone know a way around this to be able to tell if the screen is being touched even if the users finger isn't moving?

Related

applicationDidEnterBackground + Director->stopAnimation() = black screen

In my AppDelegate's applicationDidEnterBackground() I call cocos2d::Director::getInstance()->stopAnimation() and in applicationWillEnterForeground() I call cocos2d::Director::getInstance()->startAnimation().
But applicationDidEnterBackground can be called with the game still visible on screen, and not only when the game is minimized with the home button (and becomes invisible), for example when you start a buy process in your game, and google billing shows it's popup. If you now rotate the screen with this popup active, the game screen goes all black and the result is a black screen with only the google billing dialog visible.
The same happens if the google billing dialog is visible, and you minimize the app and then bring it back.
The only way I can fix this, is by NOT calling stopAnimation.
Does this have a negative impact on battery life, or will cocos2d-x automatically pause all actions while minimized?
The only way I can see how this can be fixed properly, is by knowing whether or not the game is still visible when it's being put in the background, which I could do by overriding the onStop() function on Android.
So how did others solve this?
Did you chose to stop the animation and see the black screen as a minor side effect, or do you leave the animation running?
Pause/Resuming the Director has the same effect btw...
Any help would be greatly appreciated!
Kind regards,
Mich
If your game/app enters background mode, its Activity will stop update, so all OpenGL draw calls will be hold no matter you called stopAnimation() or not. So it won't affect battery life if your game doesn't have any background job to do.
Furthermore, why screen goes black when you called stopAnimation()? Let's read some code:
void CCDisplayLinkDirector::mainLoop(void)
{
if (m_bPurgeDirecotorInNextLoop)
{
m_bPurgeDirecotorInNextLoop = false;
purgeDirector();
}
else if (! m_bInvalid)
{
drawScene();
// release the objects
CCPoolManager::sharedPoolManager()->pop();
}
}
void CCDisplayLinkDirector::stopAnimation(void)
{
m_bInvalid = true;
}
If stopAnimation() was called, it will also stop OpenGL draw call. The last frame of your game will still be shown, but if your game enters background or another Activity or something pops at front, since there's no new draw call updates the game's Activity, it will become whole black.

How to recognize touch on the home screen

I am very new to android. I just want to know how can i recognize the touch on the screen of android phone.
Till now what i did, created an application and on that application view i am able to recognize the touch.
Please refer screen shot to know that where i am able to recognize touch.
Please refer screen shot where i am not able to recognize touch.
Please give me some suggestion how to recognize touch on main screen of android phone.
What you are looking for is the onTouchListener.
Here is an example code, you can use any view to trigger this method:
yourView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){ //When finger is lifted off the screen
// Do what you want, for example, raise a Toast:
Toast.makeText(yourActivity.this, "Screen has been touched", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
Read more Here
Hope this has helped!
You cannot do that outside your own app. Home screen is like another app(System) for your app. Detecting actions in another app is a kind of intrusion and android won't allow that.
If you create your own launcher, you can. But cannot detect touches with the system default launcher.

Displaying a ProgressDialog while Android GL context reloads

I am working on a game that takes a bit of time to reload its textures when the app loses focus. During this time, the app is unresponsive to the user.
I have setup a handler to tell the main Activity class when the textures are done loading so it can hide a ProgressDialog that I start when the user leaves the app as shown below:
#Override
public void onWindowFocusChanged(final boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus) {
if (this.windowLocked && this.gamePaused) {
this.gamePaused = false;
Cocos2dxHelper.onResume();
this.mGLSurfaceView.onResume();
}
this.windowLocked = false;
} else {
this.windowLocked = true;
}
}
#Override
protected void onResume() {
super.onResume();
if (!this.windowLocked && this.gamePaused) {
this.gamePaused = false;
Cocos2dxHelper.onResume();
this.mGLSurfaceView.onResume();
}
if (!this.dialogShowing && this.gamePaused) {
displayResumingDialog();
}
}
#Override
protected void onPause() {
super.onPause();
this.gamePaused = true;
Cocos2dxHelper.onPause();
this.mGLSurfaceView.onPause();
}
The functions to show and hide the dialog look like this:
static public void displayResumingDialog() {
dialogShowing = true;
resumingDialog = ProgressDialog.show(sContext, "Re-Initializing", "Please Wait...", true);
}
static public void hideResumingDialog() {
if (resumingDialog != null && resumingDialog.isShowing()) {
resumingDialog.dismiss();
dialogShowing = false;
}
}
This works absolutely fine if the user leaves the app via the home button and then comes back by opening the apps drawer and clicking the icon again. If they lock the screen and return, or hold down the home button and return from the list of running apps however, the dialog never gets hidden. In fact, everything except for the dialog stops running. If I setup the dialog to be dismissed when it is touched outside, and I dismiss it, the app is still hung until I press the Back button. Then after a few seconds the textures are reloaded and the game begins.
I've done a fair bit of logging trying to figure it out. All of the calls seem to be the same, except sometimes when the screen is locked, onResume gets called twice. I think my code accounts for that though. If I don't allow it to display when the screen is locked the code run through to the end with no problem. With the dialog up and the screen returns from being locked, the code stops once the dialog shows up so onSurfaceCreated never get called and the textures never have a chance to load. As I said, it doesn't resume until I dismiss the dialog and press the back button.
What would cause the ProgessDialog to completely take over like that? Perhaps more importantly, why does it do it when returning from a locked screen or running apps list but not when clicking on the app icon?
Well, I hate to answer my own question, but I figured out the problem and figured it might help someone else.
The dialog comes into focus when it is created, so the onWindowFocusChanged code never gets called, so the textures never get reloaded. I fixed it by making my dialog not focusable, like so:
resumingDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
Although the dialog locks up with the rest of the UI if the user returns from a locked screen at least it is there. I tried showing the dialog in an asynctask to get it to spin while the rest of the UI was locked up, but no such luck. If anyone can tell me how to get the dialog to spin I'd be glad to award the answer to that person. It spins if they come back to the app via the running apps list or the app's icon, just not from a locked screen.

Android Camera Button Half Way Pressed Listener

I am building a custom camera app and have got the basics to work. I have also been able to block the camera button from initializing the real camera app. The only thing that I would like to do is build in autofocus when the camera button is half pressed.
I am comfortable using camera.autofocus, but cannot find a way to listen for the camera button to be halfway pressed (like the default camera app does) to start the autofocus call.
Is there a keycode or another way to listen for the camera button being depressed to its half way point?
I got a little creative and just toasted any key down event in android. I ended up finding out that the key code for camera focus is 80 this way. This also matches up with the android documentation once I knew what I was looking for.
http://developer.android.com/reference/android/view/KeyEvent.html
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction()==KeyEvent.ACTION_DOWN){
Toast.makeText(this, new Integer(keyCode).toString(), Toast.LENGTH_LONG).show();
return true;
}
return false;
}
Hope this helps others.
The camera button is a virtual button on the screen, I am not sure how it can the half pressed, or even could be mimicked in any way.

OnTouch event, finger on screen but not moving

I'd like to perform an action when the user let his finger on a View more than 1 sec.
With OnTouch, I can access to ACTION_UP,ACTION_DOWN and ACTION_MOVE.
The problem is that if the user has his finger on the screen and doesn't move his finger, ACTION_MOVE is not triggered and thus I can't perform my action.
I precise that I'd like to perform my action after 1sec but while the user still have its finger on screen.
In fact I'd need to sense that the user has his finger on the screen even if he's not moving it.
Thanks for your help.
You can Make Use of the TimerTask class and schedule a Task which will run after a specific time.
Here is an Example.
In case the user has lifted his finger before 1000 ms then just cancel the task scheduled upon ACTION_UP event.
Or you could use a longclickListener :)
View myView = findViewById(R.id.myView);
wv.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
//DO SOMETHING HERE
return true;
}
});

Categories

Resources