One question:
I have a EditTextPreference to let the user type in a default path for the app.
How can I manage that the new value is to be seen in the preferencefragment I use?
After the user clicked ok in the preference window to complete the new settings I want to write the new path as a summary below the title.
I have tried already experiencing with the onSharedPreferenceChanged but it did not work. I do not know how to get access to the edit field from the popup window where the users text is in.
Hope to find some help
Andreas!
Edit:
Here is the source code for the whole PreferenceFragment I used and modified with the suggestions of Rustam. Unfortunately it does not work.
package com.example.wbsettings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
public class PreferenceFrag extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener{
public static final String KEYVAL = "startpath";
SharedPreferences sp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
EditTextPreference prefUrl = (EditTextPreference) findPreference(KEYVAL);
prefUrl.getEditText().setHint("default path");
//>> Here the app crashed when I debug it
------------------------------------
prefUrl.setSummary(sp.getString(KEYVAL, ""));
}//onCreate
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
Preference pref = findPreference(key);
if (pref instanceof EditTextPreference) {
EditTextPreference etp = (EditTextPreference) pref;
pref.setSummary(etp.getText());
}
}//onSharedPreferenceChanged
}
What I also do not understand in your example: Where is the preferences to register with the OnSharedPreferenceChangeListener? I mean as of now I never reach the onSharedPreferenceChanged procedure because of the crash. But when I make the statement a comment and the app is running and finished I have never been stopped at the breakpoint I set within the onSharedPreferenceChanged procedure.
Another question:
What is the best practice here to answer a comment if the answer becomes too long for another comment? I tried to open an answer to my own question. But a pop up informed me that this is not the way it should be. So what to do?
Regards Andreas!
your menu_setting.xml :
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/menu_settings"
android:icon="#android:drawable/ic_menu_preferences"/>
</menu>
your preference.xml :
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:dialogTitle="Enter path"
android:key="prefPath"
android:summary=""
android:title="Path Setting" />
</PreferenceScreen>
your PreferenceFrag should look like this :
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
public class PreferenceFrag extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener{
public static final String KEYVAL = "prefPath";
SharedPreferences sp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preference);
EditTextPreference prefPath = (EditTextPreference) findPreference(KEYVAL);
prefPath.getEditText().setHint("sdcard/path");
// Here the app crashed when I debug it
SharedPreferences sp = getPreferenceScreen().getSharedPreferences();
prefPath.setSummary(sp.getString(KEYVAL, ""));
}//onCreate
#Override
public void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
Preference pref = findPreference(key);
if (pref instanceof EditTextPreference) {
EditTextPreference etp = (EditTextPreference) pref;
pref.setSummary(etp.getText());
}
}//onSharedPreferenceChanged
}
your PreferenceActivity :
import android.app.Activity;
import android.os.Bundle;
public class PreferenceActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PreferenceFrag()).commit();
}
}
your MainActivity :
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview=(TextView)findViewById(R.id.textview);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_setting, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
Intent i = new Intent(this, PreferenceActivity.class);
startActivity(i);
break;
}
return true;
}
}
finally AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.preferencetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.preferencetest.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.preferencetest.PreferenceActivity"/>
</application>
</manifest>
Related
I am starting the activity after clicking on menu item in the action bar menu.
I have added the activity in manifest file also . I cannot find why there is ActivityNotFoundException. I have used intent to start new Activity. FragmentActivity extends Activity.
MANIFEST FILE:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.myapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.android.myapplication.FragmentActivity"
android:label="#string/app_name"></activity>
</application>
</manifest>
MAIN ACTIVITY FILE:
package com.example.android.myapplication;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatCallback;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements AppCompatCallback{
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
private EditText mEditTextName;
private EditText mEditTextEmail;
private EditText mEditTextPhone;
private Context context;
Toast mToast;
Intent mIntent;
// private String mPreferenceFileName = getString(R.string.preference_file_key);
// private String mNameKey = this.getString(R.string.name_key);
// private String mPhoneKey = this.getString(R.string.phone_key);
//private String mEmailKey = this.getString(R.string.email_key);
#Override
public void onSupportActionModeStarted(ActionMode mode) {}
#Override
public void onSupportActionModeFinished(ActionMode mode) {}
#Nullable
#Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
return null;
}
private AppCompatDelegate delegate;
#Override
protected void onCreate(Bundle savedInstanceState) {
delegate = AppCompatDelegate.create(this, this);
delegate.installViewFactory();
super.onCreate(savedInstanceState);
delegate.onCreate(savedInstanceState);
delegate.setContentView(R.layout.activity_main);
Toolbar toolbar=(Toolbar) findViewById(R.id.app_bar);
delegate.setSupportActionBar(toolbar);
mSharedPreferences = this.getSharedPreferences("myFile" , Context.MODE_PRIVATE);
mEditor = mSharedPreferences.edit();
mEditTextName = (EditText)findViewById(R.id.name);
mEditTextPhone = (EditText)findViewById(R.id.phone);
mEditTextEmail= (EditText)findViewById(R.id.email);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.save:
mEditor.putString( "mNameKey",mEditTextName.getText().toString());
mEditor.putString( "mEmailKey",mEditTextPhone.getText().toString());
mEditor.putString( "mPhoneKey",mEditTextEmail.getText().toString());
mEditor.apply();
mToast = Toast.makeText(this,"saved",Toast.LENGTH_LONG);
mToast.show();
break;
case R.id.Clear:
mEditTextName.setText("");
mEditTextEmail.setText("");
mEditTextPhone.setText("");
mToast = Toast.makeText(this,"Cleared",Toast.LENGTH_LONG);
mToast.show();
break;
case R.id.retrieve:
if(mSharedPreferences.contains("mNameKey")){
mEditTextName.setText(mSharedPreferences.getString("mNameKey",""));
}
if(mSharedPreferences.contains("mEmailKey")){
mEditTextEmail.setText(mSharedPreferences.getString("mEmailKey",""));
}
if(mSharedPreferences.contains("mPhoneKey")){
mEditTextPhone.setText(mSharedPreferences.getString("mPhoneKey",""));
}
mToast = Toast.makeText(this,"Retrieved",Toast.LENGTH_LONG);
mToast.show();
break;
case R.id.FragementActivity:
// HERE I CALL THE NEW ACTIVITY
try {
mIntent = new Intent(MainActivity.this, FragmentActivity.class);
this.startActivity(mIntent);
}catch(ActivityNotFoundException e){
e.printStackTrace();
Log.i("tag","exception");
}
}
return super.onOptionsItemSelected(item);
}
}
When i click on the FragmentActivity menu item I cannot start the new activity. Is it not possible to start new activity this way? Is there some alternative?
as #Mike M. already mentioned, you are trying to open FragmentActivity from the support package instead of your package, hence the issue
Solution :
You have to remove this import
import android.support.v4.app.FragmentActivity;
and import your activity carefully.
you can use setAction as
mIntent = new Intent();
intent.setAction("com.example.android.myapplication.FragmentActivity");
this.startActivity(mIntent);
Note : For second solution , To avoid the user to select app to complete the action, you need to add DEFAULT as category along with intent-filter for FragmentActivity
No need of changing the class name or no need of removing this :-
import android.support.v4.app.FragmentActivity;
Instead write your full qualified class ( yourPackagename.FragmentActivity )name like
(MainActivity.this,com.example.android.myapplication.FragmentActivity.class );
in the explicit intent call !!
I'm stucked with this problem.
In my app I use SharedPrefManager as a singleton class, in order to keep some "session" information. In this simple example app I just save the user's name and a boolean that indicates whether or not the user is logged in to skip the login screen if already logged, or to show it if not.
When starting the app, after the splashscreen, the LoginActivity is started.
At this point, if the user has already logged in before (without logging out later, that means the boolean value of isuseradded SharedPreferences variable is true), the user is redirected to the MainActivity, otherwise he sees the login form, where he can insert username and password and make a REST API request to a remote server.
If the login is correct, the MainActivity starts and simply shows the name of the user, taken from the response JSON obtained by the remote login REST API call.
Now, here is my problem: I want to implement a simple logout feature that deletes (or changes, as in this test app) all the information stored by SharedPreferences and takes the user back to the LoginActivity.
But when I click logout, the values for SharedPreferences are updated only in MainActivity, while in LoginActivity they remain the same as before, so when the user is redirected to LoginActivity, the isusedadded shared preference is still true, and the user is redirected back to MainActivity.
But SharedPrefManager class is a singleton, so its values should be the same in every part of the app, because only one instance of it exists, so why do I have this behavior?
You can test the app by downloading the full app code here and using these credentials for login:
Username: 52346
Password: 32fjueM1 (case sensitive)
Here follows my code.
App.java:
package mypackage.sharedprefapp;
import android.app.Application;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class App extends Application
{
private RequestQueue mRequestQueue;
private static App mInstance;
#Override
public void onCreate()
{
super.onCreate();
mInstance = this;
}
public static synchronized App getInstance()
{
return mInstance;
}
// This method returns the queue containing GET/POST requests
public RequestQueue getRequestQueue()
{
if(mRequestQueue == null)
{
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
// This method adds a GET/POST request to the queue of requests
public <T> void addToRequestQueue(Request<T> req)
{
getRequestQueue().add(req);
}
}
SplashActivity.java
package mypackage.sharedprefapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class SplashActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
}
}
LoginActivity.java
package mypackage.sharedprefapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class LoginActivity extends AppCompatActivity
{
private static final String TAG = "LoginActivity";
Button loginButton;
EditText userIDInput, passwordInput;
TextView loginErrorMsg, title;
LinearLayout bgLayout;
SharedPrefManager sharedPrefManager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sharedPrefManager = SharedPrefManager.getInstance(this);
Log.i("HERE", "LoginActivity onCreate: "+sharedPrefManager.isUserAdded());
}
#Override
protected void onResume()
{
super.onResume();
sharedPrefManager = SharedPrefManager.getInstance(this);
Log.i("HERE", "LoginActivity onResume: "+sharedPrefManager.getUserName());
// if the user is already logged in
if(sharedPrefManager.isUserAdded())
{
Log.i(TAG, "User is logged in");
// if the device is connected to the internet
if(Utils.isDeviceOnline(this))
{
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
// if the device is offline
else
{
Log.i(TAG, "Internet connection is not available");
}
}
// if the user is not logged in
else
{
Log.i(TAG, "User is NOT logged in");
setContentView(R.layout.activity_login);
title = (TextView) findViewById(R.id.title);
loginErrorMsg = (TextView) findViewById(R.id.login_errorText);
userIDInput = (EditText) findViewById(R.id.login_id_paziente);
passwordInput = (EditText) findViewById(R.id.login_password);
loginButton = (Button) findViewById(R.id.login_submitButton);
bgLayout = (LinearLayout) findViewById(R.id.login_parentLayout);
// Bind a custom click listener to the login button
loginButton.setOnClickListener(new LoginButtonClickListener(this));
// Bind a custom click listener to the background layout
// so that the soft keyboard is dismissed when clicking on the background
bgLayout.setOnClickListener(new LoginBackgroundClickListener());
}
}
}
LoginButtonClickListener.java
package mypackage.sharedprefapp;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class LoginButtonClickListener implements View.OnClickListener
{
private Context context;
private SharedPrefManager sharedPrefManager;
public LoginButtonClickListener(Context c)
{
this.context = c;
}
#Override
public void onClick(View v)
{
sharedPrefManager = SharedPrefManager.getInstance(context);
// if internet connection is available
if(Utils.isDeviceOnline(context))
{
// Verify login credentials from DB
doLogin();
}
else {}
}
// check login data with REST API
private void doLogin()
{
final String paziente_id = ((EditText)((Activity)context).findViewById(R.id.login_id_paziente)).getText().toString();
final String paziente_password = ((EditText)((Activity)context).findViewById(R.id.login_password)).getText().toString();
StringRequest stringRequest = new StringRequest
(
Request.Method.POST,
"http://www.stefanopace.net/iCAREServer/api/v1/index.php/login",
new Response.Listener<String>()
{
#Override
public void onResponse(String s)
{
try
{
JSONObject obj = new JSONObject(s);
if(!obj.getBoolean("error"))
{
String name = obj.getString("nome");
sharedPrefManager.addUser(name);
Intent intent = new Intent(context, MainActivity.class);
context.startActivity(intent);
}
else
{
Toast.makeText(context, "Error on JSON response", Toast.LENGTH_LONG).show();
}
}
catch(JSONException e)
{
e.printStackTrace();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError volleyError)
{
Toast.makeText(context, volleyError.getMessage(), Toast.LENGTH_LONG).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError
{
Map<String, String> params = new HashMap<>();
params.put("id_paziente", paziente_id);
params.put("password", paziente_password);
return params;
}
};
App.getInstance().addToRequestQueue(stringRequest);
}
}
LoginBackgroundClickListener.java
package mypackage.sharedprefapp;
import android.view.View;
public class LoginBackgroundClickListener implements View.OnClickListener
{
#Override
public void onClick(View v)
{
Utils.hideSoftKeyboard(v);
}
}
MainActivity.java
package mypackage.sharedprefapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
{
private static final String TAG = "MainActivity";
TextView personName;
SharedPrefManager sharedPrefManager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sharedPrefManager = SharedPrefManager.getInstance(this);
setContentView(R.layout.activity_main);
personName = (TextView) findViewById(R.id.person_name);
Log.i(TAG, "Value: "+sharedPrefManager.isUserAdded());
personName.setText(sharedPrefManager.getUserName());
}
#Override
protected void onResume()
{
super.onResume();
sharedPrefManager = SharedPrefManager.getInstance(this);
Log.w("MainActivity", "onResume");
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mainmenu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
// Logout button has been pressed
case R.id.logout_action:
{
Log.i("Logout pressed", "Logout button has been pressed!");
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Are you sure you want to logout?");
alertDialogBuilder.setPositiveButton
(
"Yes",
new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface arg0, int arg1)
{
boolean success = sharedPrefManager.removeDataFromSharedPreference();
// if the operation is OK
if(success)
{
// go to the login activity
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
else
{
Toast.makeText(getApplicationContext(), "Error during logout", Toast.LENGTH_LONG).show();
}
}
}
);
alertDialogBuilder.setNegativeButton
(
"No",
new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface arg0, int arg1)
{}
}
);
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
return true;
}
}
return super.onOptionsItemSelected(item);
}
}
SharedPrefManager.java
package mypackage.sharedprefapp;
import android.content.Context;
import android.content.SharedPreferences;
public final class SharedPrefManager
{
private static final String TAG = "SharedPrefManager";
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
private static SharedPrefManager mInstance;
private static final String SHARED_PREF = "sharedprefs";
private static final String KEY_IS_USER_ADDED = "isuseradded";
public static final String KEY_USER_NAME = "username";
private SharedPrefManager(Context context)
{
sharedPreferences = context.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
sharedPreferences.registerOnSharedPreferenceChangeListener(new LocalSharedPreferencesChangeListener());
}
public static SharedPrefManager getInstance(Context context)
{
if(mInstance == null)
{
mInstance = new SharedPrefManager(context);
}
return mInstance;
}
// add an user to the shared preferences
public boolean addUser(String name)
{
editor.putString(KEY_USER_NAME, name);
editor.putBoolean(KEY_IS_USER_ADDED, true);
return editor.commit();
}
public boolean removeDataFromSharedPreference()
{
editor.putString(KEY_USER_NAME, "HELLO");
editor.putBoolean(KEY_IS_USER_ADDED, false);
return editor.commit();
}
public String getUserName()
{
return sharedPreferences.getString(KEY_USER_NAME, "");
}
public boolean isUserAdded()
{
return sharedPreferences.getBoolean(KEY_IS_USER_ADDED, false);
}
}
Utils.java
package mypackage.sharedprefapp;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
public class Utils
{
public static void hideSoftKeyboard(View view)
{
InputMethodManager inputMethodManager = (InputMethodManager) view.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
// This method checks if the device is connected to the Internet
public static boolean isDeviceOnline(final Context context)
{
final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(connectivityManager != null)
{
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
boolean isOnline = (networkInfo != null && networkInfo.isConnectedOrConnecting());
if(!isOnline)
{
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setCancelable(false);
alertDialog.setTitle("Error");
alertDialog.setMessage("Internet is not available");
alertDialog.setPositiveButton("Try again", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
// Reload the Activity
Intent intent = ((Activity) context).getIntent();
((Activity) context).finish();
context.startActivity(intent);
}
});
alertDialog.show();
}
return isOnline;
}
return false;
}
}
LocalSharedPreferencesChangeListener
package mypackage.sharedprefapp;
import android.content.SharedPreferences;
import android.util.Log;
public class LocalSharedPreferencesChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener
{
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Log.i("HERE", key);
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".LoginActivity"
android:padding="0dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView"
android:layout_gravity="center_horizontal">
<LinearLayout
android:id="#+id/login_parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:clickable="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:layout_marginBottom="30dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:singleLine="false"
android:padding="5dp"
android:textSize="30sp" />
<EditText
android:id="#+id/login_id_paziente"
android:layout_width="match_parent"
android:layout_height="40dp"
android:inputType="number"
android:ems="10"
android:hint="Username"
android:textColor="#android:color/black"
android:textColorHint="#android:color/darker_gray"
android:singleLine="true"
android:minLines="1"
android:gravity="center_horizontal"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:focusableInTouchMode="true"
android:focusable="true" />
<EditText
android:id="#+id/login_password"
android:layout_width="match_parent"
android:layout_height="40dp"
android:hint="Password"
android:textColorHint="#android:color/darker_gray"
android:inputType="textPassword"
android:ems="10"
android:textColor="#android:color/black"
android:maxLines="1"
android:singleLine="true"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:focusableInTouchMode="true"
android:focusable="true" />
<TextView
android:id="#+id/login_errorText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login error"
android:textColor="#android:color/holo_red_dark"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:singleLine="false"
android:padding="5dp"
android:textSize="20sp"
android:layout_margin="10dp"
android:visibility="invisible" />
<Button
android:id="#+id/login_submitButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
android:textSize="20sp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="mypackage.sharedprefapp.MainActivity">
<TextView
android:id="#+id/person_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="25sp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
splashscreen.xml (in drawable resources folder)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/holo_green_dark"/>
<item>
<bitmap
android:gravity="center"
android:src="#mipmap/ic_launcher"/>
</item>
</layer-list>
mainmenu.xml (in res/menu resource folder)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/logout_action"
android:title="Logout"
app:showAsAction="always" />
</menu>
styles.xml
<resources>
...
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">#drawable/splashscreen</item>
</style>
</resources>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mypackage.sharedprefapp">
<!-- Needs internet to connect to Google Services -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Permission to check internet connection state -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme" />
<activity
android:name=".LoginActivity"
android:label="#string/app_name"
android:process=":other_process"
android:screenOrientation="portrait"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.LOGIN_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
build.gradle (Module: app)
dependencies {
...
compile 'com.android.volley:volley:1.0.0'
}
Thank you!
Just call editor.clear();
and editor.commit();
is enough to delete all data from shared preference.
Because onResume, you keep on instantiating a new SharedPrefManager
sharedPrefManager = new SharedPrefManager(this);
Modify your SharedPrefManager so that it only gives one instance at all times OR make sure that you are referring to the same object when you return to LoginActivity.
SharedPreferences is permanent storage, you can clear
SharedPreferences.Editor.clear().commit();
alternate solution
you want once app close clear entire values,try Application singleton class
#Ciammarica you can call this code on click of Logout button, hope this can help you..you can set in logout button boolean value false..
SessionManager.setUserLoggedIn(YourActivity.this, false); SessionManager.clearAppCredential(YourActivity.this);
I Changed my code in order to have only one instance of SharedPrefManager class.
This is my App singleton class:
public class App extends Application
{
private static App mInstance;
private SharedPrefManager sharedPrefManager;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
sharedPrefManager = new SharedPrefManager(this);
}
public SharedPrefManager getSharedPrefManager(){
return sharedPrefManager;
}
public static synchronized App getInstance(){
return mInstance;
}
}
Then from other classes I get the instance by calling
SharedPrefManager sharedPrefManager = App.getInstance().getSharedPrefManager();
Now, with this change, the onSharedPreferenceChanged() event is triggered only once, so this is better than before, but the "delayed" behavior is still there... I mean, even if I use editor.clear(); and editor.commit(); methods, the values are updated but I can see them only if I close and open the app again.
I found the problem myself... It didn't like the sharedPrefManager.removeDataFromSharedPreference(); method to be called from inside new DialogInterface.OnClickListener()
I took it in another part of the code and it worked.
I am currently working on a fahrenheit to celsius converter android app. I tried runing the app on the emulator and every time it gives "your app has stopped suddenly" error. tried many things like increasing ram of emulator, rebooting . I also added the activity to manifest.xml.
The mainactivity.java code
package com.example.yoyo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.Menu;
public class MainActivity extends Activity {
EditText input;
EditText answer;
TextView celsius;
TextView fahrenheit;
Button convert;
#Override
protected void onCreate(Bundle savedInstanceState)
{
this.findAllViewsById();
convert.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
String query = input.getText().toString();
answer.setText(query);
}
});
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#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;
}
public void findAllViewsById()
{
input = (EditText) findViewById(R.id.Input);
answer= (EditText) findViewById(R.id.Answer);
convert= (Button) findViewById(R.id.ConvertButton);
celsius= (TextView) findViewById(R.id.celsius);
fahrenheit= (TextView) findViewById(R.id.fahrenheit);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yoyo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.yoyo.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.findAllViewsById();
convert.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
String query = input.getText().toString();
answer.setText(query);
}
});
}
first of all the super.onCreate has to been your onCreate does. Second thing you can not do all related findViewById operations if you has not called setContentView
I got this code online and I am looking to make a change to it. Basically, when I click Display Shared Preferences, then click Preferences Screen, make some changes and then click Back, the displayed preferences don't update until I click the Display Shared Preferences button again. How do I get the preferences to be automatically updated...do I need a listener?
PreferenceDemoTestActivity.java
package Preference.Demo;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class PreferenceDemoTestActivity extends Activity {
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnPrefs = (Button) findViewById(R.id.btnPrefs);
Button btnGetPrefs = (Button) findViewById(R.id.btnGetPreferences);
textView = (TextView) findViewById(R.id.txtPrefs);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnPrefs:
Intent intent = new Intent(PreferenceDemoTestActivity.this,
PrefsActivity.class);
startActivity(intent);
break;
case R.id.btnGetPreferences:
displaySharedPreferences();
break;
default:
break;
}
}
};
btnPrefs.setOnClickListener(listener);
btnGetPrefs.setOnClickListener(listener);
}
private void displaySharedPreferences() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(PreferenceDemoTestActivity.this);
String username = prefs.getString("username", "Default NickName");
String passw = prefs.getString("password", "Default Password");
boolean checkBox = prefs.getBoolean("checkBox", false);
String listPrefs = prefs.getString("listpref", "Default list prefs");
StringBuilder builder = new StringBuilder();
builder.append("Username: " + username + "\n");
builder.append("Password: " + passw + "\n");
builder.append("Keep me logged in: " + String.valueOf(checkBox) + "\n");
builder.append("List preference: " + listPrefs);
textView.setText(builder.toString());
}
}
PrefsActivity.java
package Preference.Demo;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class PrefsActivity extends PreferenceActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btnPrefs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Preferences Screen" />
<Button
android:id="#+id/btnGetPreferences"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Display Shared Preferences" />
<TextView
android:id="#+id/txtPrefs"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Simple update the variables with the value from SharedPreferences in your Activity's onResume() method, and then update the UI.
Your values were not changing because even though you updated them in the Preference Screen, your Activity hand simple resumed its old instance and was using the values stored in the variables.
In your case, simple calling displaySharedPreferences() from onResume() will suffice.
You can register for changes in the onCreate() method:
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
and then use:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
SharedPreferences.Editor editor = sharedPreferences.edit();
// Update your preferences here
}
Then don't forget to unregister it in onDestroy():
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
I created a preference files for my slide show Live Wallpaper.
Most of the source are copied from several samples. I think I copied them correctly, and the eclipse shows no warnings or errors for my source.
My problem is that the "Settings" button doesn't appear when I choose the Live Wallpaper.
I checked the very close question "Can't get settings button to display for live wallpaper", but it didn't solve my problem.
I suspect something is wrong with my Manifest, or preference sources, but I couldn't find the point.
Sorry for my bad English.
My sources are follows:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="sample.slide_wallpaper"
android:versionCode="1"
android:versionName="1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="#drawable/icon"
android:label="#string/app_name">
<!-- =========================================================== -->
<!-- Launcher -->
<activity android:name=".Launcher" android:label="#string/app_name"
android:theme="#style/Theme.HalfTrans">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- ==============================================================-->
<!-- Live Wallpaper -->
<service
android:enabled="true"
android:permission="android.permission.BIND_WALLPAPER"
android:label="#string/app_name"
android:name="SlideWallpaper"
android:icon="#drawable/thumbnail">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService"></action>
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/wallpaper">
</meta-data>
</service>
<!-- ================================================================= -->
<!-- Preferences -->
<activity
android:name="sample.slide_wallpaper.Prefs"
android:label="#string/wallpaper_settings"
android:theme="#android:style/Theme.WallpaperSettings"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.PREFERENCE" />
</intent-filter>
</activity>
</application>
</manifest>
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="#string/wallpaper_settings"
>
<ListPreference
android:key="timer_key"
android:title="#string/list_title"
android:summary="#string/list_summary"
android:entries="#array/timer_pref"
android:entryValues="#array/timer_pref_values"
android:defaultValue="5000"
/>
</PreferenceScreen>
**wallpaper.xml**
<?xml version="1.0" encoding="utf-8" ?>
<wallpaper xmlns:android="http://shemas.android.com/apk/res/android"
android:thumbnail="#drawable/thumbnail"
android:description="#string/description"
android:settingsActivity="sample.slidewallpaper.Prefs"
/>
**Prefs.java**
package sample.slide_wallpaper;
import sample.slide_wallpaper.R;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.util.Log;
public class Prefs extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
Log.w("Prefs", "prefs onCreate");
addPreferencesFromResource(R.xml.settings);
}
#Override
protected void onDestroy()
{
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
}
}
SlideWallpaper.java
package sample.slide_wallpaper;
import java.util.Random;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.WindowManager;
import android.content.SharedPreferences;
import android.content.res.Resources;
//WallpaperService
public class SlideWallpaper extends WallpaperService {
// Path for Prefs
public static final String SHARED_PREFS_NAME = "sample.slide_wallpaper.Prefs";
#Override
public void onCreate() {
.....
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public WallpaperService.Engine onCreateEngine() {
return new WallpaperEngine(getResources());
}
//*********************************************************
//Wallpaper Engine
//*********************************************************
public class WallpaperEngine extends Engine
implements SharedPreferences.OnSharedPreferenceChangeListener {
private final Handler handler=new Handler();
SharedPreferences prefs;
public Bitmap img;
private Bitmap images[] = new Bitmap[5];
private Bitmap eximg;
private final Random randGen = new Random();
private static final String TAG = "WallpaperEngine";
//timer
private long timer = 5000;//interval(sec)×1000
private long startTime = 0;
private int currentAlpha;
private final Paint imagePaint;
private final Runnable drawThread=new Runnable() {
public void run() {
Log.d(TAG,"runnable");
drawFrame();
}
};
public WallpaperEngine(Resources r) {
prefs=SlideWallpaper.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
prefs.registerOnSharedPreferenceChangeListener(this);
images[0]=BitmapFactory.decodeResource(r,R.drawable.imgA);
images[1]=BitmapFactory.decodeResource(r,R.drawable.imgB);
images[2]=BitmapFactory.decodeResource(r,R.drawable.imgC);
images[3]=BitmapFactory.decodeResource(r,R.drawable.imgD);
images[4]=BitmapFactory.decodeResource(r,R.drawable.imgE);
eximg = BitmapFactory.decodeResource(r,R.drawable.bg1);
img = eximg;
imagePaint = new Paint();
imagePaint.setAlpha(255);
}
//=============================
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
Log.w(TAG, "onPreferenceChanged");//this Log doesn't show up
String listString = prefs.getString("timer_key", "5000");
int listInt = Integer.parseInt(listString);
timer = listInt;
}
//=================================
#Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
Log.d(TAG, "onCreate");
drawFrame();
}
//=====================================
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(fadeAnimate);
handler.removeCallbacks(drawThread);
}
//==================================
#Override
public void onVisibilityChanged(boolean visible) {
Log.d(TAG, "Visibility changed");
if (visible) {
if(nowTime() - startTime + 100 < timer){
if (img.isRecycled()) {
img = eximg;
}
drawBitmap(img);
handler.postDelayed(drawThread, timer - (nowTime() - startTime));
}else {
drawFrame();
}
} else {
handler.removeCallbacks(fadeAnimate);
handler.removeCallbacks(drawThread);
}
}
//===================================================
//draws bitmap
private void drawBitmap(Bitmap b) {
............
}
//=========================
#Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
//============================
#Override
public void onSurfaceChanged(SurfaceHolder holder,
int format,int width,int height) {
super.onSurfaceChanged(holder,format,width,height);
drawFrame();
}
//==============================
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
handler.removeCallbacks(fadeAnimate);
handler.removeCallbacks(drawThread);
}
//=================================
#Override
public void onOffsetsChanged(float xOffset,float yOffset,
float xStep,float yStep,int xPixels,int yPixels) {
drawBitmap(img);
}
//=================================================
//Changes image==================================
protected void drawFrame() {
.....
}
private final Runnable fadeAnimate = new Runnable() {
public void run() {
fadeTransition(img, currentAlpha);
}
};
private void fadeTransition(Bitmap b, int alpha) {
.....
}//END fadeTransition
private long nowTime() {
return System.nanoTime() / 1000000;
}
}//Engine
}//END
I really need your help!!
Also, the thumbnail image doesn't show up on the Live Wallpaper list. But this is a small problem.
Your wallpaper.xml has a minor error. The package name is incorrect. It should be:
<?xml version="1.0" encoding="utf-8" ?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="#drawable/thumbnail"
android:description="#string/description"
android:settingsActivity="sample.slide_wallpaper.Prefs"
/>
I solved the problem by myself.
Thanks for Rajesh, I rewrote the whole code of "wallpaper.xml", and it worked correctly.
Actually, I couldn't find the difference, but my revised version is this:
<?xml version="1.0" encoding="utf-8" ?>
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="#drawable/thumbnail"
android:description="#string/description"
android:settingsActivity="sample.slide_wallpaper.Prefs"
/>
By revising the source, the thumbnail error was shown up, too!