Values in onClick not fix in onResume - android

I am new in android. I write a program that ball moves via accelerometer sensor and this good works. I use Timer and schedule method for this(schedule(mTimerTask, delay,period);) I have two buttons in my screen and i want when user click in positive button, period and delay value increases and when clicked in negative button, these values decreases. I write this code but the changes values in onClick method not fix in onResume method. I know onResume method called as a part of the life cycle but i dont know how can i solve my problem! please help me :) thanks
public class MainActivity extends Activity {
float result=0;
BallView ball=null;
Handler redrawHandler=new Handler();
//
Timer mTimer;
TimerTask mTimerTask;
//
int mSrcWidth,mSrcHeight;
PointF mBallPos,mBallSpd;
//
Button positiveBtn;
Button negativeBtn;
//
int delay=10;
int period=10;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
positiveBtn=(Button)findViewById(R.id.positiveBtn);
negativeBtn=(Button)findViewById(R.id.negativeBtn);
Log.e("onclick", "in oncreate");
getWindow().setFlags(0xFFFFFFFF, LayoutParams.FLAG_FULLSCREEN|LayoutParams.FLAG_KEEP_SCREEN_ON);
final FrameLayout frame=(FrameLayout)findViewById(R.id.main_view);
//
Display display=getWindowManager().getDefaultDisplay();
mSrcWidth=display.getWidth();
mSrcHeight=display.getHeight();
mBallPos=new PointF();
mBallSpd=new PointF();
mBallPos.x=mSrcWidth/2;
mBallPos.y=mSrcHeight/2;
mBallSpd.x=0;
mBallSpd.y=0;
ball=new BallView(this,mBallPos.x,mBallPos.y,10);
frame.addView(ball);
//
ball.invalidate();
positiveBtn.setOnClickListener(onClickListener);
negativeBtn.setOnClickListener(onClickListener);
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
sm.registerListener(new SensorEventListener(){
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
//
mBallSpd.x=-event.values[0];
mBallSpd.y=event.values[1];
}
//
},sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0), SensorManager.SENSOR_DELAY_NORMAL);
Log.e("onclick", "in onsensor");
}
private OnClickListener onClickListener=new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.negativeBtn:
if(delay<=5&&period<=5)
delay=period=5;
else{
delay=delay-10;
period=period-10;
}
break;
case R.id.positiveBtn:
if(delay>=50&&period>=50)
delay=period=150;
else{
delay=delay+10;
period=period+10;
}
break;
}
Log.e("delay","="+ delay);
Log.e("period","="+ period);
}
} ;
#Override
public void onPause(){
mTimer.cancel();
mTimer=null;
mTimerTask=null;
super.onPause();
}
#Override
public void onResume(){
mTimer=new Timer();
mTimerTask=new TimerTask(){
public void run(){
//Log.e("in ", "onResume()");
//positiveBtn.setOnClickListener(onClickListener);
//negativeBtn.setOnClickListener(onClickListener);
mBallPos.x+=mBallSpd.x;
mBallPos.y+=mBallSpd.y;
if(mBallPos.x>=mSrcWidth)
mBallPos.x=mSrcWidth;
if(mBallPos.y>=mSrcHeight)
mBallPos.y=mSrcHeight;
if(mBallPos.x<=0)
mBallPos.x=0;
if(mBallPos.y<=0)
mBallPos.y=0;
ball.x=mBallPos.x;
ball.y=mBallPos.y;
redrawHandler.post(new Runnable(){
public void run() {
// TODO Auto-generated method stub
ball.invalidate();
}
});
}
};
mTimer.schedule(mTimerTask, delay,period);
super.onResume();
}

Implement onSaveInstanceState like so:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt("STATE_DELAY", delay);
savedInstanceState.putInt("STATE_PERIOD", period);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
and then inside your onCreate try to restore them (if they have been set) like so:
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
delay = savedInstanceState.getInt("STATE_DELAY");
period = savedInstanceState.getInt("STATE_PERIOD");
}
And finally as I wrote in the comments of the question have a look at the Recreating an Activity training page.

Related

Check game state in activity

I'm trying to make a simple android game. I have a surfaceview named: surfaceviewgame, which is responsible for the drawing, updating and handling touch events of the game. At this point I'm checking if the gamestate is "game-over" in this surfaceview by setting the "pause" boolean to true. Now, I want to read this pause variable like this:
SurfaceViewGame v;
if(v.pause == true){
setcontentview(R.Layout.pause)
}
But I can't simply paste that if statement in the activity below. Does someone know how to approach this problem?
public class StartGame extends Activity {
SurfaceViewGame v;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
v = new SurfaceViewGame(this);
setContentView(v);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
v.pause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
v.resume();
}
}
You can pass some callback object from your activity to your SurfaceView, or make your activity such a callback and notify it about any changes in game flow. Then in your callback method you can resolve next behaviour.

Saving the state of a button onSaveInstanceState

Ok, this one is really tricky to me. The idea of this is a time log for EMS. You press a button by the action taken, and it logs the time for later use. I managed to figure out how to save the TextView into a string. Now, how on earth do I save the logTime1.setEnabled(false); so that on rotation or on leaving the activity, it restores it disabled? Eventually I will have another button beside it that will allow you to edit which will unlock the button. Here is the code.
public class TimeLog extends Activity{
boolean logTimeDis1=true;
Button logTime1;
String time1;
TextView ivTimeStamp;
int counter=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.time_log);
logTime1 = (Button) findViewById(R.id.logTime1);
ivTimeStamp = (TextView) findViewById(R.id.ivTimeStamp);
if(savedInstanceState != null) logTime1.setEnabled(savedInstanceState.getBoolean("logTimeDis1", true));
logTime1.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
time1 = new SimpleDateFormat("HH:mm", Locale.US).format(new Date());
ivTimeStamp.setText(time1);
logTime1.setEnabled(false);
logTimeDis1 = false;
return false;
}
});
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
counter++;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putString("ivTimeStamp", ivTimeStamp.getText().toString());
outState.putBoolean("logTimeDis1", logTimeDis1);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
ivTimeStamp.setText(savedInstanceState.getString("ivTimeStamp"));
}
}
So, in this line
if(savedInstanceState != null) logTime1.setEnabled(savedInstanceState.getBoolean("logTmeDis1", false));
you don't check if savedInstanceState contains logTmeDis1. Say, savedInstanceState is not null, but does not have logTmeDis1, you'll get false and your button locked. Actually, you don't have to check it in this case, just change false to true, and it should work correctly.

Difference between oncreate and onRestoreInstanceState method in activity

Guys I am stuck in a problem with these two methods:-
When I change the orientation of device and set the text in edit text after retriving the text from bundle,it does't work.But the same code is working in onrestoreStoreInstante method.
Please have a look at my code:-
public class LifeCycleActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
EditText user;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
user=(EditText)findViewById(R.id.et_user);
if(savedInstanceState!=null){
String s =savedInstanceState.get("Key").toString();
user=(EditText)findViewById(R.id.et_user);
user.setText(savedInstanceState.get("Key").toString());
Toast.makeText(this, s,Toast.LENGTH_SHORT).show();
}
Toast.makeText(this, "onCreate",Toast.LENGTH_SHORT).show();
Button b=(Button)findViewById(R.id.button1);
b.setOnClickListener(this);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Toast.makeText(this, "onSaveInstanceState",Toast.LENGTH_SHORT).show();
outState.putString("Key", "Deepak");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//String s =savedInstanceState.get("Key").toString();
//user.setText(s);
Toast.makeText(this, "onRestoreInstanceState",Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Toast.makeText(this, "onStart",Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Toast.makeText(this, "onResume",Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Toast.makeText(this, "onPause",Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Toast.makeText(this, "onStop",Toast.LENGTH_SHORT).show();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "onDEstroy",Toast.LENGTH_SHORT).show();
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Toast.makeText(this, "onRestart",Toast.LENGTH_SHORT).show();
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(LifeCycleActivity.this,SecondActivity.class));
}
}
when I set the text in edit text in oncreate method after getting the value from Bundle,it doesn't work.But the same code works in onRestoreInstanceState() method.
According to me , it should work for oncreate also as we can get the Bundle class object there.
Please help me to sort out this problem..
EditText and most of other views have their own methods to save/restore their own data. So in general it's not necessary to save/restore them on your code.
You can see this here on the Android TextView source code (remember that EditText extends from TextView) on line 3546:
if (ss.text != null) {
setText(ss.text);
}
so the reason you can't set it onCreate and can do it onRestoreInstanceState it's because during your activity super.onRestoreInstanceState(savedInstanceState) the activity calls the EditText.onRestoreInstanceState and the EditText restore it self to the previous value.
You can see it happening on the Activity source code on line 940
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (mWindow != null) {
Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
if (windowState != null) {
mWindow.restoreHierarchyState(windowState);
}
}
}
hope it helps.
Overview
onSaveInstanceState() is used to put the data to bundle
onRestoreInstanceState() is used to set the data available in
bundle to your activity
So do as follows:
i Guess until the activity is created onorientation change the
bundle is not available, that's way you are not able to retrieve it
in oncreate
Let the activity create in oncreate
Then restore the instance in onRestoreInstanceState
Hope this helps !

how to stop the timer in android

This is my code following,I am changing some iamges dynamically in my image view.
public class LoadingScreen extends Activity{
public static Integer[] imageList={R.drawable.food_pics1,R.drawable.food_pics2,R.drawable.food_pics3,
R.drawable.food_pics4,R.drawable.food_pics5,R.drawable.food_pics6,R.drawable.food_pics7,
R.drawable.food_pics8,R.drawable.food_pics9};
Thread thread;
ImageView foodImageView;
final Handler myHandler=new Handler();
public int currentImageIndex=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.load_xml);
foodImageView=(ImageView)findViewById(R.id.imageView_food);
// final int i=0;
final Runnable runnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
animateImages();
}
};
final int delay=500;
final long period=1000;
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
myHandler.post(runnable);
}
}, delay, period);
}
private void animateImages() {
// TODO Auto-generated method stub
foodImageView.setImageResource(imageList[currentImageIndex%imageList.length]);
currentImageIndex++;
foodImageView.getAnimation();
}
I want to stop the timer and finish this activity after 20 secs.how can I do that.
Try using this,
View v = new View(this);
v.postDelayed(new Runnable(){
public void run() {
// TODO Auto-generated method stub
//cancel your animation and finish the Activity here.
finish();
}
}, (long) 20000.0);
You can say something like this :
timer.cancel();
timer = null;
Save the TimerTask instance in the class and invoke cancel on it.
Here's a tip I found very useful without using Java's Timer: Try synchronizing things in the UI thread, especially if you want to do UI tasks. Example:
... onCreate() {
getUiThreadHandler().post(new Runnable(){
if (canceled()) {
return;
}
// Actual work
...
// Invoke again after delay
getUiThreadHandler().postDelayed(this, 500);
});
Good luck

SurfaceView implements Runnable - Thread does not start

Have been looking on some tutorials for drawing canvas using SurfaceView, but the only thing that shows up is a black background.
public class FighterActivity extends Activity implements OnTouchListener {
/** Called when the activity is first created. */
SurfaceController surface;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
surface = new SurfaceController(this);
surface.setOnTouchListener(this);
setContentView(surface);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
surface.pause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
surface.resume();
}
public class SurfaceController extends SurfaceView implements Runnable{
Thread thread = null;
SurfaceHolder holder;
public SurfaceController(Context context) {
super(context);
// TODO Auto-generated constructor stub
holder = getHolder();
System.out.println("HERE");
}
public void run() {
// TODO Auto-generated method stub
System.out.println("Hello World2");
while(true){
if(!holder.getSurface().isValid()){
System.out.println("NOT VALID");
continue;
}
System.out.println("VALID!");
Canvas can = holder.lockCanvas();
can.drawARGB(255, 150, 150, 0);
holder.unlockCanvasAndPost(can);
}
}
public void pause(){
}
public void resume(){
}
}
public boolean onTouch(View view, MotionEvent me) {
// TODO Auto-generated method stub
return false;
}
}
It gets to the System.out.println("HERE"); and prints out HERE, but nothing more happends, In other words the thread does not get started since "Hello World2" is not printed, what is the problem?
Thanks for any help
I'm assuming you're building off of this: http://android-coding.blogspot.ca/2011/05/drawing-on-surfaceview.html
You'll notice there the onResumeMySurfaceView and onPauseMySurfaceView (resume and pause in your SurfaceController, respectively) start the actual thread. You'll need to do that in your code, too, e.g. in SurfaceController:
protected boolean running = false;
public void resume() {
running = true;
thread = new Thread(this);
thread.start();
}

Categories

Resources