How to display saved information from SharedPreferences? - android-studio

I want to display the username on the user profile that the user inputs on the first activity. I am using SharedPreferences, but the following code does not display the username on the other activity.
This is the code on the activity where the user inputs the username:
public class MainActivity extends AppCompatActivity {
EditText userName, password;
Button b1;
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userName=findViewById(R.id.usernameText);
password=findViewById(R.id.passwordText);
b1=findViewById(R.id.button);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(binding.usernameText.length()==0 && binding.passwordText.length()==0){
binding.fillInTheBlanks.setText("Please, fill in the blanks.");
binding.passwordConstraint.setText("");
}
else{
SharedPreferences sp = getSharedPreferences("database", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("Username", userName.getText().toString());
editor.apply();
binding.fillInTheBlanks.setText("");
binding.passwordConstraint.setText("");
startActivity(new Intent(v.getContext(), YourGenderActivity.class));
}
}
});
}
}
And this is the code where I want to read and display saved information from SharedPreferences:
public class MyProfileActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_profile_activity);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String userstring = sp.getString("Username",null);
TextView username = findViewById(R.id.userName);
username.setText(userstring); //this does not do anything on the activity
}
public void homeActivity(View v){
Intent intent = new Intent(v.getContext(), HomeActivity.class);
startActivity(intent);
}
}
If there is another way to achieve this, any help is welcome.

If you just want an implementation of SharedPreferences, you can do it like that:
To write to the SharedPreferences:
SharedPreferences sp = context.getSharedPreferences("database", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("Username", username);
editor.apply();
To retrieve information:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
String userstring = sp.getString("Username",null);
Another problem is the implementation of context is new Intent(v.getContext()) it could be as simple as
startActivity(this, YourGenderActivity.class));
This code snippet just uses this for the context then it is similar with next profile context this
NOTES:
Both writing and reading operations have to have the same Context.
SharedPreferences should write to inside a singleton to make it easy to set and get value

You are using 2 different SharedPreferences objects. You need to get the same one using getSharedPreferences("database", Context.MODE_PRIVATE) in both activities. By using PreferenceManager.getDefaultSharedPreferences(context), you're using a SharedPreferences object that is associated to your package name (nothing wrong with using that, but I prefer to be explicit).

You have specified a name for your shared preference named 'database'
In your second activity you must exactly get that name again so
use this in your second activity:
SharedPreferences sp = getSharedPreferences("database", MODE_PRIVATE);
String userstring = sp.getString("Username",null);
In SharedPreference you can have multiple names to arrange your data for example you can specify a name for all data related to theme,database and...
to get android default name for sharedPreference use :
SharedPreferences sp =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

Related

How to reference "getSharedPreferences" from a static context that is not an Activity

I'm in
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewholder>
When trying
SharedPreferences mySharedPrefData = getSharedPreferences("mySharedPrefData",MODE_PRIVATE);
I get as an error:
Non-static method 'getSharedPreferences(java.lang.String, int)' cannot be referenced from a static context
I tried as alternatives
Context.getSharedPreferences("mySharedPrefData",MODE_PRIVATE)
and
this.getSharedPreferences("mySharedPrefData",MODE_PRIVATE)
and declaring mySharedPrefData as static
static SharedPreference mySharedPrefData
but all throw errors.
Question: How can I get data from mySharedPrefData into the class MyAdapter?
to use the sharedPreferences you need to have the activity, so there's a lot of options here:
if you're using fragments then you need activity to get applicationContext,
you can get an activity by calling requireActivity() on your fragment object.
then get a SharedPreferences reference to your data through this line of code.
Context context = requireActivity().getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
"mySharedPrefData", Context.MODE_PRIVATE);
then you can send this sharedPref reference through the adapter constructor when you initialize it.
so your adapter constructor code should look like this :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewholder> {
SharedPreferences myShared ;
public MyAdapter (SharedPreferences shared){
myShared = shared ;
}
}
which from now on you can use the myShared variable to access your shared preferences inside your adapter.
N.B : if you're not using fragments and initializing your adapter inside your main activity directly, then you can skip the requireActivity part and your shared preferences code will look like this instead
Context context = getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
"mySharedPrefData", Context.MODE_PRIVATE);
Update
since there's some confusion let me clarify that you should use the getApplicationContext() call inside your activity, assuming you initialize your adapter in onCreate method inside activity, then your MainActivity code might look like this :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
Context context = getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
"mySharedPrefData", Context.MODE_PRIVATE);
MyAdapter myAdapter = new myAdapter(sharedPref);
...
}
}
N.B : three dots (...) means that I don't care about your code written here.
Update
if you don't have the permission to edit the adapter constructor parameters then what about making a setter to it.
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewholder> {
SharedPreferences myShared ;
public MyAdapter (SomeOtherParameter){...}
public void setMyShared(SharedPreferences shared){
myShared = shared ;
}
}
then after initializing your adapter, you set the shared Preferences to it
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
Context context = getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
"mySharedPrefData", Context.MODE_PRIVATE);
MyAdapter myAdapter = new myAdapter(SomeOtherParameter);
myAdapter.setMyShared(sharedPref);
...
}
}
N.B : if you used the code above then don't use the myShared object in any case in the adapter constructor to avoid NullPointerException

How to create when i click 1st item in arrayList1 will open page with 1st item in arrayList2

When I click first or second item from 1st array list I get first item from array list two, but I need if i click second item on array list 1 I get shown second item from list two
public class SecondActivity extends AppCompatActivity {
ListView listView;
ArrayList<String> 1stArrayList;
ArrayList<String> 2ndArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
listView = (ListView) findViewById(R.id.listView);
1stArrayList = new ArrayList<>();
1stArrayList .add("A");
1stArrayList .add("B");
1stArrayList .add("C");
2ndArrayList = new ArrayList<>();
2ndArrayList.add("1");
2ndArrayList.add("2");
2ndArrayList.add("3");
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.item, 1stArrayList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
String 2ndArrayList= listView.getItemAtPosition(position).toString();
SharedPreferences settings = getSharedPreferences("PREFS", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("2ndArrayList ", 2ndArrayList );
editor.apply();
Intent intent = new Intent(getApplicationContext(), ThirdActivity.class);
startActivity(intent);
}
});
}
}
A possible solution would be getting the value directly from the array using the position of the view clicked. Like the following:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
String secListItem = secArrayList.get(position);
SharedPreferences settings = getSharedPreferences("PREFS", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("2ndArrayList", secListItem );
editor.apply();
Intent intent = new Intent(getApplicationContext(), ThirdActivity.class);
startActivity(intent);
}
});
But you have to be sure that both the arrays will have the same size or you may have an IndexOutOfBoundsException.
Another solution would be using some Map with the values from arraylist1 and arraylist2, implementing a custom adapter that extends BaseAdapter, populating the views with the values from the first array with getView() and using getItem() to return the values from the second list, but that's harder to do.
Also if you don't mean to persist the item and only transfer them between activities, you can use the Intent to do it. In this way:
Intent intent = new Intent(getApplicationContext(), ThirdActivity.class);
Intent.putExtra("2ndArrayList", secListItem);
startActivity(intent);
And recover in the third activity with something like:
String secArrayItem = "";
Bundle extras = getIntent().getExtras();
if (extras != null) secArrayItem = extras.getString("2ndArrayList");

"java.lang.IllegalArgumentException: view must not be null" Program Closes when navigated

The app closes whenever I navigate to ProfileActivity.
FATAL EXCEPTION: main Process: hfad.com.hallofmemesprototype, PID:
19092 java.lang.RuntimeException: Unable to start activity
ComponentInfo{hfad.com.hallofmemesprototype/hfad.com.hallofmemesprototype.Profile.ProfileActivity}:
java.lang.IllegalArgumentException: view must not be null
Here's the "ProfileActivity" code.
public class ProfileActivity extends AppCompatActivity {
private static final int ACTIVITY_NUM = 3;
private Context mContext = ProfileActivity.this;
private ProgressBar mProgressBar;
private ImageView profilePhoto;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
setupBottomNavigationView();
setupToolbar();
setupActivityWidgets();
setProfileImage();
}
private void setProfileImage(){
String imgURL = "www.androidzone.org/wp-content/uploads/2013/02/android-musical2.jpg";
UniversalImageLoader.setImage( imgURL, profilePhoto, mProgressBar, "https://");
}
private void setupActivityWidgets(){
mProgressBar = findViewById(R.id.profileProgressBar);
mProgressBar.setVisibility(View.GONE);
profilePhoto = findViewById(R.id.profile_photo);
}
private void setupToolbar() {
Toolbar toolbar = findViewById(R.id.profileToolBar);
setSupportActionBar(toolbar);
ImageView profileMenu = findViewById(R.id.profileMenu);
profileMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(mContext, AccountSettingsActivity.class);
startActivity(intent);
}
});
}
/**
* BottomNavigationView setup
*/
private void setupBottomNavigationView() {
BottomNavigationViewEx bottomNavigationViewEx = findViewById(R.id.bottomNavViewBar);
BottomNavigationViewHelper.bottomNavigationView(bottomNavigationViewEx);
BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx);
Menu menu = bottomNavigationViewEx.getMenu();
MenuItem menuItem = menu.getItem(ACTIVITY_NUM);
menuItem.setChecked(true);
}
}
You must check that all the views that you are getting using findViewById() really exist into the activity_profile.xml layout.
One or more views doesn´t really exist, and you have a null value gettin the reference.
findViewById(R.id.profileProgressBar);
findViewById(R.id.profile_photo);
findViewById(R.id.profileToolBar);
findViewById(R.id.profileMenu);
findViewById(R.id.bottomNavViewBar);
initially you are not getting any error tryin to find the references of this views because they are really exist but in another layout but not in activity_profile.xml that you are loading via setContentView() in your Activity.
This type of exception rise at the time of the wrong variable declaration and
initialization.
Try this
replace your weighs declare and initialize val with var.
If you have to use java
final TextView helloTextView = (TextView)findViewById(R.id.text_view_id);
For Kotlin
val helloTextView = findViewById(R.id.text_view_id) as TextView
you can refer this link for more details

Android-Xamarin: Remember EditText in sessions

I am developing an Android application on Visual Studio with his Xamarin plugin.
I need remember the user and password on a TextView in all session of this application, i.e. when the user close the application and reopen, this TextView must remember the text on fields.
Thanks you.
You will have to use ISharedPreferences. Here is a simple example supposing that you have a password and a button.:
public class MainActivity : Activity
{
private ISharedPreferences _sharedPreferences;
private EditText _editText;
private Button _saveButton;
private const string PasswordLabel = "SavedPassword";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.test);
this._editText = this.FindViewById<EditText>(Resource.Id.editText);
this._saveButton = this.FindViewById<Button>(Resource.Id.button);
this._sharedPreferences = PreferenceManager.GetDefaultSharedPreferences(this);
this._editText.Text = _sharedPreferences.GetString(PasswordLabel, "");
this._saveButton.Click += _saveButton_Click;
}
void _saveButton_Click(object sender, EventArgs e)
{
string password = this._editText.Text;
ISharedPreferencesEditor editor = this._sharedPreferences.Edit();
editor.PutString(PasswordLabel, password);
editor.Commit();
}
}

SherlockFragmentActivity with SherlockListFragment

I have 3 tabs and all of them has lists inside(different ones of course). When i click on tab I see the proper result(result which i would like to get).
I know how to get the clicked item info and make request to database about that item and get result and create new intent and put that result in it as a extra. BUT i don't know how I can display my result inside the same fragment without creating new intent. Because when i create new intent and show result in new intent my tabs obviously disappears, but i need them always to be there.
My main activity:
public class MainActivity extends SherlockFragmentActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(true);
Tab tab = actionBar.newTab()
.setText("Dictionary")
.setTabListener(new DictionaryFragment())
.setIcon(R.drawable.android);
actionBar.addTab(tab);
tab = actionBar.newTab()
.setText("Play")
.setTabListener(new PlayFragment())
.setIcon(R.drawable.apple);
actionBar.addTab(tab);
tab = actionBar.newTab()
.setText("Manage")
.setTabListener(new ManageFragment())
.setIcon(R.drawable.apple);
actionBar.addTab(tab);
}
}
One of my fragments:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
built_in_DB_setup dbOpenHelper = new built_in_DB_setup(getActivity().getBaseContext(), DB_NAME);
database = dbOpenHelper.openDataBase();
fillFreinds();
ArrayAdapter<String> adapter = new
ArrayAdapter<String>(getActivity().getBaseContext(), android.R.layout.simple_expandable_list_item_1, friends);
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
And here is the item click listener inside this class
public void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
String a=getData(((TextView) v).getText().toString());
Intent i = new Intent("com.example.fragmenttest.VIEWWORD");
i.putExtra("result", a);
startActivity(i);
}
Ones I have String a which i have got from onListItemClick how can I replace current Tab data with this string?

Resources