I read that after a screen rotation, an android activity is created again. I understood how to recover a view, but i don't understand if i can start from where a method was stopped after a screen rotation.
Recover after screen rotation.
In it's simplest form you save what you need to recreate where you left off in the onSaveInstanceState method. So for your basic flashlight you save the state of the light. For you more complex apps your saving all of the global fields. Flashlight has a global variable isFlashOn.
private boolean isFlashOn = false;
save the state of the flashlight in the onSaveInstanceState
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(ISON, isFlashOn);
}
Then in the oncreate method you recreate the global variable.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
isFlashOn = savedInstanceState.getBoolean(ISON);
}
later in the onstart method process the isFlashOn. This flashlight is turned on by a click so I change the state of isFlashOn and call the click handler.
#Override
protected void onStart() {
super.onStart(); // Always call the superclass method first
if (camera == null) {
camera = Camera.open();
}
//flip the isflashon and then click the button
isFlashOn = !isFlashOn;
onClick(null);
}
process the click.
public void onClick(View arg0) {
ImageButton i = (ImageButton) findViewById(R.id.imageButton1);
final Parameters p = camera.getParameters();
if (isFlashOn) {
i.setImageResource(R.drawable.ic_launcher);
isFlashOn = false;
p.setFlashMode(Parameters.FLASH_MODE_OFF);
} else {
i.setImageResource(R.drawable.ic_launcher2);
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
// Set flag to true
camera.startPreview();
isFlashOn = true;
}
Good Luck
If there was a method that was executing at the moment you turned your screen, the method will finish its work.
It wont be paused or anything else since its "impossible" to do that.
If that particular method was important to your app/activity you should then call it again upon Activity recreation.
Related
I am working on a Tuner app in Android Studio.
I want to have a button that displays "Start Tuning" & when you click it, the ToggleButton above (which has the image of a mic on & mic off) switches from the Muted Mic image to the Unmuted to show that the app is "listening".
As of right now, I have a button that onClick changes the text view from off to on, however there is no way to go back from on to off, and so far I have found no way to make the mic "button" change as well. Is there a way to do this? Here is the Java code I have so far:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beginTuning = findViewById(R.id.toggleButton);
mic = findViewById(R.id.muteButton);
mic_status = findViewById(R.id.micState);
mic_status.setText("Mic off");
tester = findViewById(R.id.test_button);
tester.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (tester.isPressed() && mic.isChecked()) {
mic_status.setText("on");
} else {
mic_status.setText("off");
}
}
});
you have stored mute status in variable 'mic' so when volume is turned on' set mute-check-status to 'false': You just need to add statements marked 1.. and 2.. to your code;
public void onClick(View view) {
if (tester.isPressed() && mic.isChecked()) {
mic_status.setText("on");
mic.setChecked(false); // 1..add just this line so 'else' part of condition will execute next time
} else {
mic_status.setText("off");
mic.setChecked(ture); // 2..also set mute checked..
}
}
});
I've implemented something similar to Android notification of screen off/on, but it's not working the way it should. All I want to do is stop music when the screen is turned off. I created a screen action class like this
public class ScreenAction extends BroadcastReceiver {
public static boolean wasScreenOn = true;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// DO WHATEVER YOU NEED TO DO HERE
wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// AND DO WHATEVER YOU NEED TO DO HERE
wasScreenOn = true;
}
}
}
Then, in my main activities on create I have this
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenAction();
registerReceiver(mReceiver, filter);
In my main activities onPause, I have something like this:
public void onPause() {
super.onPause();
if (ScreenAction.wasScreenOn) {
final MediaPlayer mp = MediaPlayer.create(this, R.raw.pcmouseclick1);
mp.setVolume(.1f, .1f);
mp.start();
if (buttonState) {
mServ.reduceVolume();
}
}
}
I found this from an online source, but I am having issues. It seems that the screen state is always set as true, and I'm not sure how to change this.
How do I utilize this ScreenAction class to turn off music in on Pause ONLY when the user has locked the screen? I feel like I am missing something in the onPause because in onCreate I link to the class.
#Override
protected void onPause() {
// when the screen is about to turn off
// or when user is switching to another application
super.onPause();
}
#Override
protected void onResume() {
// only when screen turns on
// or when user returns to application
super.onResume();
}
Here you can see the entire lifecycle of an Activity in android:
Activity Lifecycle
Maybe you could also start and stop your music directly from the receiver:
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// Pause music player
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// Resume music player
}
}
You're checking ScreenAction.wasScreenOn in onPause, but that's happening before the BroadcastReceiver is called to notify you that the screen is being turned off. So at that point, ScreenAction.wasScreenOn is still true, and then it's set to false, but onPause has already run, so your music never gets paused.
To solve this, you should take the action directly in response to the screen turning off in the BroadcastReceiver. If you need to interact with your UI, consider a solution like LiveData as an abstraction so that you're not reliant on your Activity being paused at the exact moment the screen is turned off (consider also that the onPause solution wouldn't work if your Activity weren't currently visible).
I have an android webview app, with more than 3 different activity my problem is when i lunch new activity and close it using finish(), the main webview activity will refresh again. Is it possible to prevent it from refreshing when i don't want it to and refresh only on the activity i want it to?
I have follow few post but am getting errors on cannot resolve symbol FragmentIdentifier and other ones. Here is the link Prevent Reload Activity / Webview when go Back to app and when press the turn off button
Below is what i have in onresume method to remember last saved url.
protected void onResume() {
super.onResume();
//String message = getIntent().getStringExtra(FSMainActivity.FragmentIdentifier);
if(FSwebview != null) {
SharedPreferences r_prefs = getSharedPreferences(getPackageName(), MODE_PRIVATE);
// String ssn = r_prefs.getString("sessionParameter","");
String lastPage = r_prefs.getString("lastUrl", "");
if(!lastPage.equals("")) {
/*if (message == null || message.compareTo(FSMainActivity.showWebViewFragment) == 0) {
if (!getSavedInstance()){
changeFragment(new WebViewFragment());
}
} else if (message.compareTo(FSMainActivity.showLoginFragment) == 0) {
changeFragment(new LoginFragment());
}*/
appLoadUrl(lastPage, false);
}else{
appLoadUrl(APP_URL, false);
}
}
}
My webview app
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView mWebView = new WebView(this);
//now do whatever u want
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new HelloWebViewClient());
mWebView.loadUrl("https://example.com/index2.php");
mWebView.setInitialScale(130);
//finally
setContentView(mWebView);
}
I store last url below
protected void onPause() {
super.onPause();
SharedPreferences prefs = getSharedPreferences(getPackageName(), MODE_PRIVATE);
SharedPreferences.Editor edit = prefs.edit();
edit.putString("lastUrl", FSwebview.getUrl());
edit.commit();
}
Since you are loading your urls in onResume() too, it will be getting called when your other activity closes and the webview activity comes in focus. Here you have 2 choices to go for.
Only load your urls in onCreate() method as it will not get called again until your activity is restarted.
Before finishing your second activity save some boolean value either in shared preferences or as a static variable for eg.
sharedPreferences.putBoolean("activity finished",true);
And then in your onResume() method check for the above boolean variable value before loading your urls. Remember to set the value back to false according to your needs, preferably in your first activity onStop() method
I currently confused on how I can display my dialog only if the application is first time to load only with orientation change. I have only one activity composed of tabs.
Problem:
I tried using boolean variables and preferences but I can't figure out on where to place them in cases where the activity's view is being destroyed. Destroyed is either by exiting the app or orientation change. Secondly, during orientation changes the dialog should be showed again on first time, but the even if I dismiss dialog and do orientation change - the dialog is displayed again which should not happen. I prefer not using the onConfigurationChanged(Configuration).
boolean FirstTimeActivityOpened = true;
boolean dialogDismissed = false;
boolean orientationChanged = false;
++++++++++
if(FirstTimeActivityOpened && dialogDismissed && orientationChanged ){
loadDialog(this);
}
new OrientationEventListener(MainActivity.this,
SensorManager.SENSOR_DELAY_NORMAL){
#Override
public void onOrientationChanged(int orientation) {
// TODO Auto-generated method stub
orientationChanged = true;
//Toast.makeText(MainActivity.this, "onOrientationChanged"+ orientation, Toast.LENGTH_SHORT).show();
}};
loadDialog
dialog.setOnDismissListener(new OnDismissListener(){
#Override
public void onDismiss(DialogInterface arg0) {
// TODO Auto-generated method stub
dialogDismissed = true;
Toast.makeText(MainActivity.this, "Dialog Dismissed", Toast.LENGTH_SHORT).show();
}});
+++++++++++++
#Override
public void onDestroy() {
super.onDestroy();
if(dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
//or
if(dialog != null) {
dialog.dismiss();
}
}
I found out during my study:
FirstLoad:
onCreate()
onStart()
onResume()
Change or Orientation:
onPause()
onStop()
onDestroy()
onCreate()
onStart()
onRestoreInstantState()
onResume()
Activity not visible but not destroyed
onPause()
onStop()
Activity opened from Pause State:
onRestart()
onStart()
onResume()
Activity not visible and destroyed:
onPause()
onStop()
onDestroy()
Activity Destroyed and Re-opened
onCreate()
onStart()
I think you should store them in shared preferences so that you don't lose them when you restart your application or when the activity reloads.
Edit :
First of all, add this line to your manifest if it is not already done :
android:configChanges="orientation"
Adding this won't let your activity restart when the orientation changes.
In that case, you can set your FirstTimeActivityOpened to true at the beggining of the onCreate() method of your activity and you can set it to false in onDestroy().
Now, you already know when the orientation changes. So when it changes, you just have to prompt your dialog IF it is the first time your app is opened.
Hope this helps
I am new to savedInstanceState. There are some great resources out there, and I have nearly figured it all out. However, my TextView updates like I want it to, but it disappears. I want it to remain there when I rotate the device instead of having to click a button to bring it back. Any idea on where I am going wrong? Thanks!
TextView cashView is where I want to see int cash.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putInt("cash", cash);
savedInstanceState.putInt("anteBet", anteBet);
savedInstanceState.putInt("playBet", playBet);
savedInstanceState.putInt("pairPlusBet", pairPlusBet);
savedInstanceState.putString("cashView", cashView.toString());
// etc.
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
cash = savedInstanceState.getInt("cash");
anteBet = savedInstanceState.getInt("anteBet");
playBet = savedInstanceState.getInt("playBet");
pairPlusBet = savedInstanceState.getInt("pairPlusBet");
cashView.setText(savedInstanceState.getString(cashView.toString()));
}
Haha...after an hour of fiddling with it, i figured it out as soon as I finished asking the question. Thanks for your time though!
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putInt("cash", cash);
savedInstanceState.putInt("anteBet", anteBet);
savedInstanceState.putInt("playBet", playBet);
savedInstanceState.putInt("pairPlusBet", pairPlusBet);
savedInstanceState.putString("cashView", cashView.getText().toString());
// etc.
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
cash = savedInstanceState.getInt("cash");
anteBet = savedInstanceState.getInt("anteBet");
playBet = savedInstanceState.getInt("playBet");
pairPlusBet = savedInstanceState.getInt("pairPlusBet");
cashView.setText(savedInstanceState.getString("cashView"));
}
I changed
savedInstanceState.putString("cashView", cashView.toString());
to
savedInstanceState.putString("cashView", cashView.getText().toString());
and i changed
cashView.setText(savedInstanceState.getString(cashView.toString()));
to
cashView.setText(savedInstanceState.getString("cashView"));
Not sure which one fixed it, but its fixed. Thanks anyways!