I have seven different activities and i call all data in final activity to calculate it, in all activities i placed a button with failsafe that if edit text is empty no next button is nonclickable.
Problem arises now if a user click directly the result page my application crashes, due to no data in sharedpreferences to calculate,
I want to have some method or code to check if DOUBLE of my sharedpreferences or entire file is empty user should get a toast message 'Fill the values first' and calculation page does not open. this way my app will remain alive.
Am I thinking in right direction?
Some example code:
please note seeresults is a button which is clicked to open page having calculation results (sharedpreferences values are accessed).
variable 'v' is a double
I have entered following code but its again having problems (if statement cannot be compared with double), can any one help me out
seeresults.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
abcPref = this.getSharedPreferences(FILE1, 0);
Boolean bCheck = abcPref.getBoolean("v", false);
if (v == -1) { Toast message = Toast.makeText(Timesaving.this, "No Data or Parameteres Was Entered in forms", 3000);
message.setGravity(Gravity.CENTER_VERTICAL , 0, 0);
message.show();
finish();}
else{
Intent openresult = new Intent("com.ideals.ideal.RESMAIN");
startActivity(openresult);
}
}
});
SharedPreferences sPrefs = getSharedPreferences("MyPrefs", 0);
Boolean bCheck = sPrefs.getBoolean("ButtonReceiverState", false);
When you are trying to retrieve the values from the sharedPreferences the call provides a fail-safe exactly for the possible nullpointer; you can set a default-value if there is no value found for a key.
In my case here, the boolean is set to false if there is no value to retrieve. This works for all different datatypes aswell.
A double will never be null. Java initializes it to 0 automatically. What you could do is set the default value for the preference where you use the double to Double.NaN and check against that.
Or you simple could define reasonable default values which will work for your calculations and which the user could change at will.
Related
I need to fill form and by pressing "Back" button save it , let's say, to preferences.
Or even show it to Log.
The problem is when I use onBackPressed() - Activity goes to onPause() and myEditText.getText().toString() returns result from XML and not the result that was actually in myEditText field. Same thing goes for onDestroy().
Of course, if I hang someButton.onClickListener() it saves my data well from myEditText because Activity doesn't go onPause() and doesn't take result from XML, but I need to save it exactly by pressing back button.
The code is basic:
EditText etCompetitionName;
Competition competition;
etCompetitionName=(EditText) findViewById(R.id.etCompetitionName);
Intent intent=getIntent();//I get number of object to work with
pos=intent.getIntExtra("pos", -1); // this is this number
competition=getObject(pos);// well, this is loading this object
olDetCompetitionName=competition.getName();//getting name from loaded object
etCompetitionName.setText(olDetCompetitionName);//set this text to EditText field
...
then :
protected void onDestroy() {
super.onDestroy();
//try to save
competition.setName(etCompetitionName.getText().toString());
saveObject(competition);
}
So, it saves old value, the one I set in the beggining. If I don't set it - it will be taken from layout xml. It is issue of onPause() I need to avoid it.
Your question is quite confusing but if you override onBackPressed() you can get the data.
#Override
public void onBackPressed()
{
String text = myEditText.getText().toString();
// save text
super.onBackPressed();
}
I know you said you did this but show how you are doing it if this doesn't work. This will put whatever the user has typed in the text variable then you can save it in SharedPreferences or wherever you want.
You can also do the same thing in onPause() if you want it to save if, say, something else comes in the foreground.
SecondActivity.Java -> I saved two edittext value in SharedPReference and called the MainActivity intent
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Editor editor = sharedPreferences.edit();
editor.putString("1", a.getText().toString());
editor.putString("2", b.getText().toString());
editor.commit();
Intent i = new Intent(SecondActivity.this,MainActivity.class);
SecondActivity.this.startActivity(i);
}
MainActivity.Java -> I have a button listener to show a Toast with values from the sharedpreference.
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences pref= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String a = pref.getString("1", "") ;
String b = pref.getString("2", "");
Toast.makeText(getApplicationContext(),a+" "+b, Toast.LENGTH_LONG).show();
}
});
Good morning everyone,
I'm having problems again in my proccess to create my first app. This time with the SharedPreferences file.
I have 2 activities that must use the same SharedPreferences file. The first one is the MainActivity and the second one an edit layout for the data.
In the MainActivity I have the following method where I use the data to connect to a PLC:
//initialize the SharedPreferences variables for the PLC Data and Connection
m_DataPLC = getSharedPreferences("CFTPreferences",CONTEXT_IGNORE_SECURITY);
m_DataEditorPLC = m_DataPLC.edit();
//Gets the number from the IP Address for the connection with the PLC
//As default, the system takes the value of a static string value
//This is when the SharedPreferences file is empty
m_IpAddress = getResources().getString(R.string.ip_Address);
m_NewIpAddress = m_DataPLC.getString("newIpAddress", m_NewIpAddress);
if(m_NewIpAddress == null)
{
m_DataEditorPLC.putString("newIpAddress", m_IpAddress.toString());
m_DataEditorPLC.commit();
m_OldIpAddress = m_NewIpAddress = m_IpAddress;
}
else
{
m_OldIpAddress = m_IpAddress = m_NewIpAddress;
}
//Start the connection with the PLC
m_Connection = new ModbusConnection(this,m_IpAddress);
inet = m_Connection.loginPLC();
In my second activity, I have to load the same data and be able to modify it. What I do first is the login to the SharedPreferencesFile:
dataPLC = getSharedPreferences("CFTPreferences",CONTEXT_IGNORE_SECURITY);
dataEditorPLC = dataPLC.edit();
Then I do the writing with a click action of a button:
public void setIPAddress()
{
if (!newIpAddress.equals(etIPAddress.getText().toString()))
{
dataEditorPLC.putString("oldIpAdd",ipAddress.toString());
dataEditorPLC.putString("newIpAdd",etIPAddress.getText().toString());
dataEditorPLC.commit();
}
}
I dunno if I'm doing wrong calling the same file twice or if I have to do something extra to mend this. It looks like it does the update, but it doesn't refresh the MainActivity. If someone had some sort of the same problem, I would appreciate the help on this one!!!.
Many thanks in advance!!!
I think you are accessing the value of Shared Preferences in onCreate() of first Activity. That will be your problem. Beacuse when you come back from second activity to first activity, your onCreate() is not called, instead onResume() is called. So the better thing to do is move the code where you access SharedPreferences value to a seperate function and call this function in both onCreate() and onResume().
for e.g.
public void getSharedPrefernces() {
m_DataPLC = getSharedPreferences("CFTPreferences",CONTEXT_IGNORE_SECURITY);
m_NewIpAddress = m_DataPLC.getString("newIpAddress", m_NewIpAddress);
}
Hope this Helps..!! Cheers...
I have 2 views in my app. A form input and a screen to review the form data and confirm. The user inputs the data on the form submission screen in edittext fields. When the user clicks submit, they are presented with the data they input and a 'back' and 'confirm' button. I want it so that if the user presses back, they are returned to the form input screen and the data they input should still be in the editText fields.
At the moment, I am using an onClickListener to point to the form submission screen but the forms are all blank. How do I keep the data in them?
This is the onClickListener:
bBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(FormConfirm.this, FormCreate.class);
startActivity(j);
}
});
i don't know how to write code on android apps, but i think, why you not to store them into variable flag and call them on edit text field?
for example, if you already fill the form and click submit, you can make a function for store data first on variable flag and show the data in form submission, so when you click back button, you can call the value that you store on variable flag into edittext.
i hope my answer can give you some inspiration
As stated you should save the values somehow, for example by using SharedPreferences.
As an example, when you go from the Input-form Activity to the Submit-form Activity:
bSubmit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent j = new Intent(FormCreate.this, FormSubmit.class);
saveInput();
startActivity(j);
}
});
Where the method saveInput() could look something like:
private void saveInput() {
EditText input = (EditText) findViewById(R.id.someId);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.edit().putString("input",input.getText().toString()).commit();
}
And then, when you press back, the back action could simply be something like:
bBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
FormConfirm.this.finish();
}
});
That will cause the current activity to exit and your previous activity will be visible. If you want to display the last saved input when the Input-form Activity starts, you can simply do something like this:
private void loadInput(){
EditText input = (EditText) findViewById(R.id.someId);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String savedText = getString("input", "default input text");
input.setText(savedText);
}
and call that method in the onCreate-method in your Input-form Activity.
Had an inspiration and found a workaround that might not necessarily be correct but it works :) just changed the Java code for the activity to the following:
bBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
I created a MainActivity in which the user has a few app options, displayed in a grid menu, which access subsequent specific activities. However, when the application starts, I use an AlertDialog for the user to enter login details, inflated just after the grid layout definition.
The problem is, each time I select an item in the grid menu (and, consequently, a new activity), the AlertDialog pops-up again. How can I avoid this?
Moreover, I have an uploading service which should start with the beginning of the MainActivity (or after the login, perhaps), but should not be restarted each time a new activity is called. I assume this problem is related to the previous one, although I have managed to temporarily solve it by using a startService button via an OptionsMenu. This is no permanent solution.
Thank you in advance.
EDIT: I tried to use getSharedPreferences as follows:
private SharedPreferences prefs;
private String prefName = "MyPref";
int hasLoggedIn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mm_gridmenu);
SharedPreferences prefs = getSharedPreferences(prefName, MODE_PRIVATE);
hasLoggedIn = prefs.getInt("hasLoggedIn", 0);
if (hasLoggedIn == 0) {
showDialog(SHOW_DIALOG);
prefs = getSharedPreferences(prefName , MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("hasLoggedIn", 1);
editor.commit();
}
However, this way the hasLoggedIn value is saved as 1 and the dialog never pops-up again. I tried setting the back button to fix that, but this seems to prevent the app from being minimized. Is there a way to add that action to the button? (Which I would duplicate on the Home button as well)
#Override
public void onBackPressed() {
prefs = getSharedPreferences(prefName , MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("hasLoggedIn", 0);
editor.commit();
Log.i("hasLoggedIn", hasLoggedIn + "");
return;
}
Moreover, I believe this action will affect subsequent activities (setting the alertDialog back on). Which should be a valid alternative to this?
Basically you need to keep track of your applications states, you have a few options to do this. One simple way would be to use a SharedPreferences to store a boolean variable called something like hasLoggedIn after the user logs in you set this value to true. Each time your main activity launches simply check the value of hasLoggedIn if its is set to false require the user log in again. If it is already true don't show the log in dialog
You can try this:
Add a boolean flag in your MainActivity:
private boolean dialogFlag = true;
in the onCreate/onResume method:
if(dialogFlag) {
createDialog();
dialogFlag = false;
}
If you want to pop up just once the app is installed, you can save this flag into a property file. And read it first whenever the app is getting started.
I have a PreferenceActivity with a bunch of (Sub)PreferenceScreens. Each such (Sub)PreferenceScreen represents an account and has the account-username as its title.
PreferenceScreen root = mgr.createPreferenceScreen(this);
for (MyAccountClass account : myAccounts) {
final PreferenceScreen accScreen = mgr.createPreferenceScreen(this);
accScreen.setTitle(account.getUsername());
// add Preferences to the accScreen
// (for instance a "change username"-preference)
...
root.add(accScreen);
}
As the user enters sub-PreferenceScreen, and edits the account user-name, I want the outer PreferenceScreen to update it's PreferenceScreen-title for the account in question.
I've tried to add...
usernamePref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
accScreen.setTitle(newValue.toString());
return true;
}
});
...but the accScreen.setTitle does not seem to take effect on the outer PreferenceScreen. I've note that calling onContentChanged(); actually makes it work, but I realize that this is probably not the preferred way of doing it.
I suspect I should call postInvalidate() on some view somewhere, but I really can't figure out on what view and when to do it.
PreferenceScreen android:summary update ! may be experiening the same problem as me.
Any help appreciated.
I found a solution to this. I have a hierarchy like this, each of these is a PreferenceScreen:
main settings
-> users list
-> user1 settings
-> user2 settings
...
In the users list, title of the sub-screen is dependent on the user settings. Now when I create the user list, I store the list adapter to a variable in my PreferenceActivity.
PreferenceScreen usersListScreen = ...
userScreenListAdapter = (BaseAdapter)usersListScreen.getRootAdapter();
Now when userX-settings are edited, I set the titles in the usersListScreen and after that call:
userScreenListAdapter.notifyDataSetChanged();
which updates the list UI and the changes are visible.
notifyDataSetChanged() is right solution. But I want to add recursive iterator for all PreferenceScreens, as far as I got a problem to find real parent of a Preference. For complicated structure of Preferences I recommend this killer-code:
private void updateAll_PrefereneScreens(PreferenceGroup group) {
if (group instanceof PreferenceScreen) {
BaseAdapter adapter = (BaseAdapter) ((PreferenceScreen) group).getRootAdapter();
adapter.notifyDataSetChanged();
}
for (int i=0; i<group.getPreferenceCount(); i++) {
Preference pref = group.getPreference(i);
if (pref instanceof PreferenceGroup) {
updateAll_PrefereneScreens((PreferenceGroup) pref);
}
}
}
I call it after every setSummary() to ensure it works properly:
findPreference("KEY").setSummary(str);
updateAll_PrefereneScreens(getPreferenceScreen());
this might be a late answer but still... I'm on it right now :)
The way I achieved it, is that you can hook into the PreferenceFragmentCompat's onResume() method of its lifecycle and manually update the required field by resetting their values.
Note : in this example I also keep track of the index of the edited Preference, just to avoid reset every single ones.
// let's say you need to update title of the parent screen
// when back from sub-screen(s) edition
private int edited = -1;
// this gets called everytime you get back to the parent screen
#Override
public void onResume ()
{
super.onResume();
if ( edited != -1 )
{
PreferenceScreen root = getPreferenceScreen();
Preference preference = root.getPreference( edited );
if ( preference != null )
{
String updatedValue = getPreferenceManager()
.getSharedPreferences()
.getString( "your-preference-key", "your-default-value" );
preference.setTitle( updatedValue );
}
edited = -1;
}
}
// everytime you are about to navigate to a sub-screen
#Override
public boolean onPreferenceTreeClick ( Preference preference )
{
// beware to save it first
if ( preference instanceof MySubScreenPreference )
{
edited = preference.getOrder();
}
return super.onPreferenceTreeClick( preference );
}
As specified in the docs :
onResume
Called when the fragment is visible to the user and actively running. This is generally tied to Activity.onResume of the containing Activity's lifecycle.
Which is good is that it also works of course with FragmentManager's Transactions.
Hope this helps, happy coding ! :)
Experiencing this same problem, but onContentChanged() isn't working for me. My problem is with PreferenceScreens that are more than one level deep from the root.
To follow your example, if you first created an "Accounts" PreferenceScreen, and then added each of your individual account PreferenceScreen objects under that. Like this:
Root Screen
-> "Accounts" screen
-> "foo#example.com" screen
-> edit username
-> edit password
-> etc...
-> "bar#example.com" screen
-> "baz#example.com" screen
-> etc...
If a user edited their username and clicked save, calling PreferenceActivity.onContentChanged() seems to only affect direct descendants of the root PreferenceScreen. The third-generation screens' titles and summaries do not get redrawn, still reflecting old values.
Looking through the code for onContentChanged(), it looks like it just re-bind()s the root Screen to the ListActivity's ListView, although I don't think subsequent PreferenceScreens are ever bound to a ListView (are they?), so we can't manually re-bind anything...
The only workaround I can think of would be to create the sub-menus as isolated PreferenceActivitys instead of PreferenceScreens, so we can intentionally call onContentChanged() on our direct ancestor. But that's even more of a kludge than the current workaround. Any ideas?
PreferenceActivity#onContentChanged() will refresh the whole screen, occurring some flicker effect.
However you can achieve the same goal selectively on a given preference with the PreferenceActivity#onPreferenceTreeClick(...) method.
Note that this method is now deprecated : consider using fragments that seems to solve a lot of issues with custom preferences (I've not tested myself yet). There is a compatibility package for older SDK.
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
Log.v(TAG, "onSharedPreferenceChanged(...," + key + ")");
if (key.equals("myPref")) {
onPreferenceTreeClick(getPreferenceScreen(), getPreferenceManager().findPreference("myPref"));
Log.v(TAG, "Do whatever else you need...");
}
//onContentChanged(); // this could be used but occurs screen flickering
}
I'm just putting
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
right after updating the summary of my parent preference item.
Source
// Import required classes (Win: CTRL+SHIFT+O & Mac: CMD+SHIFT+O)
public class YourCustomPreference extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
// some logic goes above, when you want to reset value and update
// EditTextPreference value. For convenience, I am going to wrap two
// different task in different methods
private void resetPreferenceValue() {
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(this.getApplicationContext());
// Get preference in editor mode
SharedPreferences.Editor prefEditor = sharedPref.edit();
// set your default value here (could be empty as well)
prefEditor.putString("your_edit_text_pref_key", "DEFAULT-VALUE");
prefEditor.commit(); // finally save changes
// Now we have updated shared preference value, but in activity it
// still hold the old value
this.resetElementValue();
}
private void resetElementValue() {
// First get reference to edit-text view elements
EditTextPreference myPrefText = (EditTextPreference) super
.findPreference("your_edit_text_pref_key");
// Now, manually update it's value to default/empty
myPrefText.setText("DEFAULT-VALUE");
// Now, if you click on the item, you'll see the value you've just
// set here
}
}
This works for me, you have to grab the underlying dialog of your PreferenceScreen and set the title from there, really easy.
somePrefScreen.getDialog().setTitle("Whatever you want");