Minor Android tweak...

Monkey Forums/Monkey Programming/Minor Android tweak...

marksibly(Posted 2013) [#1]
Hi,

I've got a little tweak I'd like to apply to the Android target related to how suspend/resume works.

It's a minor code change, but it's the kind of thing I suspect could potentially be highly sensitive to OS version, device manufacturer etc so I'd appreciate it if any Android devs could give it a go before I publish it!

To apply, please replace this code at the bottom of targets/android/modules/native/androidgame.java...

	@Override
	public void onResume(){
		super.onResume();
		_view.onResume();
		_game.ResumeGame();
	}
	
	@Override 
	public void onPause(){
		super.onPause();
		_game.SuspendGame();
		_view.onPause();
	}


...with this...

	public void onWindowFocusChanged( boolean hasFocus ){
		if( hasFocus ){
			_view.onResume();
			_game.ResumeGame();
		}else{
			_game.SuspendGame();
			_view.onPause();
		}
	}


...run your apps and thrash suspend/resume behavior.

This came about due to reports that Monkey apps were prematurely resuming at the unlock screen. This was noticeable if the app was playing audio, ie: you'd hear app audio while viewing the unlock screen!

I suspect it's an OS version issue (my 2.2 LG does it;my 4.2.2 Nexus 7 doesn't) but the above is apparently the preferred way to resume games anyway and seems to work fine here.


Xaron(Posted 2013) [#2]
Hmm... my app got rejected because of that reason. Interesting, will check it out!


DGuy(Posted 2013) [#3]
FWIW ...

I've added code to monitor the state of the lock-screen and only tell Monkey to resume when certain the lock-screen is not up/has been removed:

NOTE:
- These edits are to V66b (have not moved to a newer version yet)
- Based on: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/

Added near top of 'public class MonkeyGame extends Activity' in 'mojo.android.java':
private KeyguardManager		mKeyguard;
private BroadcastReceiver	mReceiver;
private boolean			mScreenWasOff;

public class ScreenReceiver extends BroadcastReceiver
{
	@Override
	public void onReceive( Context context, Intent intent )
	{
       		if( intent.getAction().equals( Intent.ACTION_SCREEN_OFF ) )
		{
			// screen has turned off
			mScreenWasOff = true;
       		}
		else if( intent.getAction().equals( Intent.ACTION_SCREEN_ON ) )
		{
			// screen has turned on ...
               		if( mKeyguard.inKeyguardRestrictedInputMode() )
			{
				// ... but lock-screen is up, do not signal resume
       			}
               		else
			{
				// ... and lock-screen is NOT up, signal resume
				mScreenWasOff = false;
				onResume();
       			}
		}
		else if( intent.getAction().equals(Intent.ACTION_USER_PRESENT ) )
		{
			// user has unlocked-screen, signal resume
			mScreenWasOff = false;
			onResume();
		}
	}
}


Added to bottom of 'onCreate':
// setup for handling of screen off/on + lock-screen
mKeyguard = (KeyguardManager)getSystemService( Context.KEYGUARD_SERVICE );
IntentFilter filter = new IntentFilter( Intent.ACTION_SCREEN_ON );
filter.addAction( Intent.ACTION_SCREEN_OFF );
filter.addAction( Intent.ACTION_USER_PRESENT );
mReceiver = new ScreenReceiver();
registerReceiver( mReceiver, filter );


Added to 'onResume':
if( app!=null ){
	// If reason for 'onPause' was screen turning off, do not
	// signal monkey-app to resume until lock-screen is removed
 	if( mScreenWasOff ) return;
	app.InvokeOnResume();
	}


Added to 'onDestroy':
if( mReceiver != null )
	{
	unregisterReceiver( mReceiver );
	mReceiver = null;
	}