I am using Firebase to sign in the user and have implemented the code to exit the app on double click. But the problem is the same screen is popping up again.
I tried a workaround setting a SharedPreference and then checking that in mAuthListner. But it did not work.
Here are the relevant sections of the code:
mAuthListener = new FirebaseAuth.AuthStateListener(){
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
SharedPreferences d= getSharedPreferences("backPressed", Context.MODE_PRIVATE);
Boolean t = d.getBoolean("back",false);
if (firebaseAuth.getCurrentUser() != null && !t) {
startActivity(new Intent(MainActivity.this, Second.class));
}
if (t) {
d.edit().putBoolean("back",false);
}
}
};
Code for back button pressed:
boolean doubleBackToExitPressedOnce = false;
private Handler mHandler = new Handler();
private final Runnable mRunnable = new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
};
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
SharedPreferences d= getSharedPreferences("backPressed",Context.MODE_PRIVATE);
d.edit().putBoolean("back",true);
finish();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
mHandler.postDelayed(mRunnable, 2000);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mHandler != null) { mHandler.removeCallbacks(mRunnable); }
}
How can I exit the app on back pressed twice while keeping the user logged in?
This is not a Firebase issue as Firebase will not log out until you specifically call the "Log Out" method.
You do not need SharedPreferences. Just set an Activity level variable BackOnce to False then set it in the OnBackPressed as necessary.
boolean BackOnce = false;
#Override
public void onBackPressed() {
if (BackOnce) {
finish();
} else {
BackOnce = true;
Snackbar sb = Snackbar.make(myView, "Press back again to close app", Snackbar.LENGTH_SHORT);
sb.addCallback(new Snackbar.Callback() {
#Override
public void onDismissed(Snackbar snackbar, int event) {
super.onDismissed(snackbar, event);
BackOnce = false;
}
});
sb.show();
}
}
Related
I'm trying to create an indoor location services app in android studio.There is a scan button which start the discovery of BLE devices. When i click on the scan button,the app crashes. But when i reopen the app and click on the scan button again,it works.
i tried this taken from one of the projects from stackoverflow.
Class variable:
private BluetoothAdapter mBtAdapter = null;
final BluetoothManager btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBtAdapter = btManager.getAdapter();
if (mBtAdapter == null || !mBtAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
public void onScanButton(){
if (mBtAdapter.isEnabled()){
scanLeDevice(true);
}
}
this is my code
BluetoothManager btManager; //field 'btManager' is never used
private BluetoothAdapter btAdapter = null;
BluetoothLeScanner btScanner;
Button startScanningButton;
Button stopScanningButton;
TextView peripheralTextView;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
peripheralTextView = (TextView) findViewById(R.id.peripheralTextView);
peripheralTextView.setMovementMethod(new ScrollingMovementMethod());
startScanningButton = (Button) findViewById(R.id.StartScanButton);
startScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startScanning();
}
});
stopScanningButton = (Button) findViewById(R.id.StopScanButton);
stopScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
stopScanning();
}
});
stopScanningButton.setVisibility(View.INVISIBLE);
final BluetoothManager btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
btScanner = btAdapter.getBluetoothLeScanner();
if (btAdapter != null && !btAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
}
// Make sure we have access coarse location enabled, if not, prompt the user to enable it
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
// Device scan callback.
private ScanCallback leScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
peripheralTextView.append("MAC address: " + result.getDevice().getAddress() + " rssi: " + result.getRssi() + "TxPower:" + result.getTxPower() + "\n");
// auto scroll for text view
final int scrollAmount = peripheralTextView.getLayout().getLineTop(peripheralTextView.getLineCount()) - peripheralTextView.getHeight();
// if there is no need to scroll, scrollAmount will be <=0
if (scrollAmount > 0)
peripheralTextView.scrollTo(0, scrollAmount);
}
};
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
}
}
}
public void startScanning() {
System.out.println("start scanning");
peripheralTextView.setText("");
startScanningButton.setVisibility(View.INVISIBLE);
stopScanningButton.setVisibility(View.VISIBLE);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
}
public void stopScanning() {
System.out.println("stopping scanning");
peripheralTextView.append("Stopped Scanning");
startScanningButton.setVisibility(View.VISIBLE);
stopScanningButton.setVisibility(View.INVISIBLE);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.stopScan(leScanCallback);
}
});
}
}
The logcat shows
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeScanner.startScan(android.bluetooth.le.ScanCallback)' on a null object reference
at com.example.myapplication.MainActivity$6.run(MainActivity.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Before i click the Scan button,a prompt will be display asking to turn
on the bluetooth.So bluetooth will be turned on
You are wrong about that part. You ask the user to enable it, but it might not have happened yet. At least you need to get the Scanner later on.
Currently you set the Scanner reference before the permission requesting has been initiated.
This also explains why it works after your App has crashed for the first time, because the 2nd time you come here the Permission has been enabled.
From the Javadoc of BluetoothAdapter#getBluetoothLeScanner():
Will return null if Bluetooth is turned off or if Bluetooth LE
Advertising is not supported on this device.
You can change your code to:
public void startScanning() {
btScanner = btAdapter.getBluetoothLeScanner();
if (btScanner == null) {
// not enabled yet or not supported
return;
}
System.out.println("start scanning");
peripheralTextView.setText("");
startScanningButton.setVisibility(View.INVISIBLE);
stopScanningButton.setVisibility(View.VISIBLE);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
}
I have 6 boolean variables which I have initialized as false. There are 6 different imageviews which are associated with these 6 boolean false variables. When the user clicks any of these image, there respective boolean variable is switched to true and when the user again clicks the same image, it will turn to false like on and off. After being satisfied with the selected options, the user can click the done button and the data will be save in the firebase accordingly to whether which options are true and which are false.
My problem is that whenever the application is restarted, all boolean variables are again initialized to false, I understand the fact that, the application restarts for OnCreate class due to which the variables are again false. How can I write a certain code which can save the state of these variables even after application restarts?
Below is my Code:
boolean checkcar = false, checkPickUp = false, checkTruck = false, checkCycle = false, checkBike = false, checkMen = false;
private FirebaseAuth firebaseAuth;
private String currentUserID;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myTransport = inflater.inflate(R.layout.fragment_transport, container, false);
firebaseAuth = FirebaseAuth.getInstance();
currentUserID = firebaseAuth.getCurrentUser().getUid();
carImage = myTransport.findViewById(R.id.carTransport);
pickUpImage = myTransport.findViewById(R.id.pickUpTransport);
truckImage = myTransport.findViewById(R.id.truckTransport);
cycleImage = myTransport.findViewById(R.id.cyclerTransport);
bikeImage = myTransport.findViewById(R.id.bikeTransport);
menImage = myTransport.findViewById(R.id.menTransport);
done = myTransport.findViewById(R.id.selectUserTransportBtn);
transport = FirebaseDatabase.getInstance().getReference().child("UserProfileDetails").child(currentUserID).child("Transport");
MarkUserRegisteredTransport();
carImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkcar) {
carImage.setColorFilter(carImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkcar = true;
} else {
carImage.setColorFilter(carImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkcar = false;
}
}
});
pickUpImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkPickUp) {
pickUpImage.setColorFilter(pickUpImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkPickUp = true;
} else {
pickUpImage.setColorFilter(pickUpImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkPickUp = false;
}
}
});
truckImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkTruck) {
truckImage.setColorFilter(truckImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkTruck = true;
} else {
truckImage.setColorFilter(truckImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkTruck = false;
}
}
});
cycleImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkCycle) {
cycleImage.setColorFilter(cycleImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkCycle = true;
} else {
cycleImage.setColorFilter(cycleImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkCycle = false;
}
}
});
bikeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
menImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkMen) {
menImage.setColorFilter(menImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkMen = true;
} else {
menImage.setColorFilter(menImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkMen = false;
}
}
});
here is when user can click done and the information is updated in the firebase with true or false with their res
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
HashMap userTransport = new HashMap();
userTransport.put("check Car", checkcar);
userTransport.put("check PickUp", checkPickUp);
userTransport.put("check Truck", checkTruck);
userTransport.put("check Cycle", checkCycle);
userTransport.put("check bike", checkBike);
userTransport.put("check Men", checkMen);
transport.updateChildren(userTransport).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
Toast.makeText(getContext(), "Transportation information updated", Toast.LENGTH_LONG).show();
} else {
String message = task.getException().getMessage();
Toast.makeText(getContext(), "Error Occured: " + message, Toast.LENGTH_SHORT).show();
}
}
});
}
});
return myTransport;
}
According to your comment:
well i needed the data to be stored even after the user deletes the application just like instagram and facebook
I would like to tell you that either SharedPreferences nor Bundle won't help in this case. Both tehniques when used, do not persist across application uninstalls. If you reinstall the app, your SharedPreferences or your Bundle will be empty and you will not be able to use any data at all.
To solve this, I recommend you add that data to database and everytime the user wants to update his preferences, change the data in database accordingly. So create six new properties of type boolean under your transport object and set/update them accordingly with user's choice.
You can use onSaveInstanceState to save the boolean values, and fetch the values in onCreate or onRestoreInstanceState.
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("boolean1", booleanValue1);
outState.putString("boolean2", booleanValue2); //and so on
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(savedInstanceState!=null){
if(getString("boolean1") != null){
booleanValue1 = savedInstanceState.getString("boolean1");
}
}
}
Use SharedPreferences, if the application is killed the values saved will not be deleted or reset.
PreferenceManager mManager = PreferenceManager.getDefaultSharedPreferences(context);
//example methods
public static boolean getBool(String resName, boolean defValue) {
return mManager.getBoolean(resName, defValue);
}
public static void setBool(String resName, boolean value) {
mManager.edit()
.putBoolean(resName, value)
.apply();
}
PS: Well, if you uninstall the app or delete the app data (in "Settings", for example) datas will be destroyed
I'm making flashlight application with handling Activity Life Cycle. The application is running fine but the problem occurs when i call onStop(); while flashlight is on ,when I return from the onStop();, the application should turn on flash light but it doesn't.
I have tried all the methods but the flashOn(); is not enabling the flashlight. I had checked from debugging that the application do nothing if the flashlight was on after returning from onStop();
public class MainActivity extends AppCompatActivity {
private ImageButton imagebtn;
ImageView img;
private Camera camera;
private boolean isFlashOn;
private boolean hasFlash = false;
private Camera.Parameters params;
private boolean flag= false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imagebtn = (ImageButton) findViewById(R.id.button);
img = findViewById(R.id.torchimage);
isFlashOn = false;
hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (!hasFlash) {
// If device doesn't support flash
// Show alert message and close the application
AlertDialog alert = new AlertDialog.Builder(MainActivity.this)
.create();
alert.setTitle("Error");
alert.setMessage("Sorry, your device doesn't support flash light!");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();//Close application
}
});
alert.show();
}
imagebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isFlashOn) {
flashOff();
} else {
flashOn();
}
}
});
}
protected void checkCamera() {
if (camera == null) {
try {
camera = Camera.open();
params = camera.getParameters();
} catch (RuntimeException e) {
Toast.makeText(getApplicationContext(), "Camera not found", Toast.LENGTH_SHORT).show();
}
}
}
**protected void flashOn() {
if (!isFlashOn) {
{
if (camera == null || params == null) {
return;
}
/*if (flag==true) {
flag=false;
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
*/}
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
isFlashOn = true;
toggleImages();
btnSound();
}
}**
protected void flashOff() {
if (isFlashOn)
{
if (camera == null || params == null) {
return;
}
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
camera.stopPreview();
isFlashOn = false;
toggleImages();
btnSound();
}
}
protected void btnSound() {
final MediaPlayer mp = MediaPlayer.create(this, R.raw.button_sound);
mp.start();
}
public void toggleImages() {
if (isFlashOn) {
imagebtn.setImageResource(R.drawable.button_on);
img.setImageResource(R.drawable.torch_on);
} else {
imagebtn.setImageResource(R.drawable.button_off);
img.setImageResource(R.drawable.torch_off);
}
}
#Override
protected void onDestroy() {
// Toast.makeText(this,"OnDestroy",Toast.LENGTH_SHORT).show();
super.onDestroy();
}
#Override
protected void onPause() {
super.onPause();
if (isFlashOn)
flashOn();
else
flashOff();
}
#Override
protected void onRestart(){ super.onRestart();
if (isFlashOn==true)
flashOn();
else
flashOff();
}
#Override
protected void onResume() {
super.onResume();
if (isFlashOn == true)
flashOn();
else
flashOff();
}
#Override
protected void onStart() {
super.onStart();
// Toast.makeText(this,"OnStart",Toast.LENGTH_SHORT).show();
// if (hasFlash)
checkCamera();
}
#Override
protected void onStop() {
// Toast.makeText(this, "OnStop", Toast.LENGTH_SHORT).show();
super.onStop();
if (camera != null) {
camera.release();
camera = null;
flag= true;
}
}
Please look again at the Android lifecycle https://developer.android.com/guide/components/activities/activity-lifecycle.html
It goes onStop -> onRestart -> onStart -> onResume
You have an awful lot of crap spread all over the place making what should be easy to see, rather difficult.
So... the flash is on ie isFlashOn = true;
Remove the boolean == true from the if while you're at it. Just if (boolean) works and is much better.
onStop... camera = null; flag= true;
But isFlashOn is still true
Returned to Activity...
onRestart... if (isFlashOn==true) flashOn(); <--- It is, so going to flashOn()
flashOn() {
if (!isFlashOn) { <------------- No the boolean is still true so this isn't run... camera is null anyway.
onStart... checkCamera() {
if (camera == null) { <------ Yes, OK
onResume... if (isFlashOn == true) <----- Again same problem, so camera never starts.
Set isFlashOn = false in onStop
Also remove code from resume or restart... its just duplicated and going through the same thing twice.
Hopefully this teaches you how to debug better. Learn from it.
I want the user to confirm closing my app. I use the following code for that in my MainActivity:
#Override
public void onBackPressed() {
if (this.lastBackPressTime < System.currentTimeMillis() - 4000) {
toast = Toast.makeText(this, "Press back again to close this app", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
this.lastBackPressTime = System.currentTimeMillis();
} else {
if (toast != null) {
toast.cancel();
}
super.onBackPressed();
}
}
In other classes I use this:
#Override public void onBackPressed() {
if (!mWebView.onBackPressed()) { return; }
// ...
super.onBackPressed(); }
Now I get the confirm event in EVERY class, but I only want it in my MainActivity. How can I do that?
Note: I have to extent my MainActivity in other classes. That should be the main problem to solve, but I still dont know how exactly?
#Vala, If your adding fragments to the Activty, then you can make use BackSackEntryCount of FragmentManager like below.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackCount == 1) {
Toast.makeText(this, "Press back again to close this app", Toast.LENGTH_LONG).show();
}
if backstackcount is one, it means, on pressing the back button again, remaining frgament will be popped from back stack and app will be quit.
Try using this
in your main activity
private boolean exit = false;
#Override
public void onBackPressed()
{
if (exit) {
finish(); // finish activity
} else {
Toast.makeText(this, "Press Back again to Exit.",
Toast.LENGTH_SHORT).show();
exit = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
exit = false;
}
}, 3 * 1000);
}
}
Try like this
Activity activity = this;
if (activity instanceof MainActivity) {
if (this.lastBackPressTime < System.currentTimeMillis() - 4000) {
Toast toast = Toast.makeText(this, "Press back again to close this app", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
this.lastBackPressTime = System.currentTimeMillis();
} else {
if (toast != null) {
toast.cancel();
}
super.onBackPressed();
}
} else {
super.onBackPressed();
}
change other class to
#Override
public void onBackPressed() {
if (mWebView.canGoBack()) { return; }
// ...
super.onBackPressed();
}
I want to update the changes when I uncheck and check the checkbox in the preference activity but when I press the back button it doesn't work. It only works when I close the activity and then open it
Main activity
public class MainActivity extends ActionBarActivity {
private ToggleButton togle;
private Camera camera;
private boolean isFlashOn;
private boolean hasFlash;
Parameters params;
private ShakeListener mShaker;
MediaPlayer mp;
ImageView anime;
int p=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
anime = (ImageView) findViewById(R.id.Animation);
hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (!hasFlash) {
// device doesn't support flash
// Show alert message and close the application
AlertDialog alert = new AlertDialog.Builder(MainActivity.this)
.create();
alert.setTitle("Error");
alert.setMessage("Sorry, your device doesn't support flash light!");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// closing the application
finish(); }
});
alert.show();
return;}
getCamera();
togle = (ToggleButton) findViewById(R.id.ToggleButton01);
togle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
boolean checked = ((ToggleButton) v).isChecked();
if (checked){
turnOffFlash();
}
else{
getCamera();
turnOnFlash();
}
}
});
SharedPreferences getprefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean stopshake = getprefs.getBoolean("checkbox", true);
if (stopshake == true ){
mShaker = new ShakeListener(this);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
public void onShake()
{ if (!isFlashOn) {
Toast.makeText(MainActivity.this, "On" , Toast.LENGTH_SHORT).show();
getCamera();
turnOnFlash();
}
else{
turnOffFlash();
Toast.makeText(MainActivity.this, "Off" , Toast.LENGTH_SHORT).show();
} }
});
}
}
private void getCamera() {
// TODO Auto-generated method stub
if (camera == null) {
try {
camera = Camera.open();
params = camera.getParameters();
} catch (RuntimeException e) {
Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
}
} }
private void turnOnFlash() {
if (!isFlashOn) {
if (camera == null || params == null) {
return;
}
// play sound
getCamera();
playSound();
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
isFlashOn = true;
anime.setImageResource(R.drawable.anim);
anime.post(new Runnable() {
#Override
public void run() {
AnimationDrawable frameAnimation =
(AnimationDrawable) anime.getDrawable();
frameAnimation.start();
}
});
// changing button/switch image
}
}
private void turnOffFlash() {
if (isFlashOn) {
if (camera == null || params == null) {
return;
}
// play sound
playSound();
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
isFlashOn = false;
anime.setImageResource(R.drawable.off);
// changing button/switch image
}
}
private void playSound() {
// TODO Auto-generated method stub
if(isFlashOn){
mp = MediaPlayer.create(MainActivity.this, R.raw.off1);
}else{
mp = MediaPlayer.create(MainActivity.this, R.raw.on1);
}
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
mp.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent intent = new Intent(MainActivity.this, Prefsetting.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Preference activity
public class Prefsetting extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefset);
}
}
You access SharedPreferences in the onCreate() of your MainActivity, which is only called when that activity is created from scratch (i.e. when you first start your app). As you (presumably) navigate to and from your Prefsetting Activity fairly quickly, MainActivity is likely only in a paused or stopped state when it is resumed. Take a look at the diagram here to see what happens to Activity classes as they move into and out of the foreground.
You have a couple of options. Either place this:
#Override
public void onResume() {
super.onResume();
SharedPreferences getprefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean stopshake = getprefs.getBoolean("checkbox", true);
if (stopshake) {
mShaker = new ShakeListener(this);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
public void onShake() {
if (!isFlashOn) {
Toast.makeText(MainActivity.this, "On" , Toast.LENGTH_SHORT).show();
getCamera();
turnOnFlash();
} else {
turnOffFlash();
Toast.makeText(MainActivity.this, "Off" , Toast.LENGTH_SHORT).show();
}
}
});
} else {
if (mShaker != null) {
mShaker.setOnShakeListener(null);
mShaker = null;
}
}
}
Into somewhere like onResume().
Or, use an EventBus like LocalBrodcastManager to update your Preferences when onPause() is called in your PreferenceActivity.
From the code snippet it appears that you never actually commit your changes to the SharedPreferences of the application. Somewhere in the code when that boolean is flipped you need to do something like this:
prefs.put("checkbox", currentBooleanState).commit();