Roboelectric assertion fails with shared preferences android - android

Referring this SO question, I tried to save shared preferences, but my assertion fails.
This is my test class
#Test
public void testSharedPreferences(){
activity=actController.create().get();
loginButton=(Button)activity.findViewById(R.id.loginButton);
userName=(EditText)activity.findViewById(R.id.userName);
userPassword=(EditText)activity.findViewById(R.id.userPassword);
sharedPrefs = ShadowPreferenceManager.getDefaultSharedPreferences(Robolectric.application.getApplicationContext());
sharedPrefs.edit().putString("userName", "user1").commit();
assertThat(userName.getText().toString(),equalTo("user1"));
}
This is the code in the class under test-
public class LoginActivity extends Activity {
private EditText userName,userPassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
SharedPreferences sharedPreferences =PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor=sharedPreferences.edit();
String name = sharedPreferences.getString("userName", "");
if (!"".equalsIgnoreCase(name)) {
userName.setText(name);
}
}
Assertion fails and it says expected "user1" but found "".

Your test is creating the activity first (and triggering onCreate() too early), so your changes to the SharedPrefs have no effect. Try this instead:
#Test
public void testSharedPreferences() {
// First set up the shared prefs
sharedPrefs = ShadowPreferenceManager.getDefaultSharedPreferences(Robolectric.application.getApplicationContext());
sharedPrefs.edit().putString("userName", "user1").commit();
// Create the activity - this will call onCreate()
activity=actController.create().get();
loginButton=(Button)activity.findViewById(R.id.loginButton);
userName=(EditText)activity.findViewById(R.id.userName);
userPassword=(EditText)activity.findViewById(R.id.userPassword);
// Verify text
assertThat(userName.getText().toString(),equalTo("user1"));
}

Related

What is a proper way to store key:value returned by registerForActivityResult()?

I am trying to catch and store the file path selected by user using registerForActivityResult. It returns the path, I can print the path but I am not able to store it using SharedPreferences class as it requires an app context which I cannot get using getApplicationContext() in static SettingsFragment.
public class SettingsActivity extends AppCompatActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
protected void onCreate(Bundle savedInstanceState) {...}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {...}
public class SettingsFragment extends PreferenceFragmentCompat {
ActivityResultLauncher<String> mGetContent = registerForActivityResult(
new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
#Override
public void onActivityResult(Uri uri) {
Log.i("MYAPP", "File selected:" + uri.toString());
// the added code is right below.
sharedPreferences = getSharedPreferences( BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE );
editor = sharedPreferences.edit();
editor.putString("audio_filename", uri.toString());
editor.apply();
}
});
#Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
if (key.equals("audio_filename")) {
mGetContent.launch("*/*");
return true;
}
return super.onPreferenceTreeClick(preference);
}
}
}
The code I used from documentation but it seems missing integration between SharedPreferences and registerForActivityResult.
UPDATE1 (Clarification): This is a podcast player, actually I try to play audio using MediaPlayer class. The app has MainActivity and SettingActivity. The idea is the SettingActivity is to select an audio file and save its file path (SharedPreferences) then on the next app start (MainActivity retrieves last file path from SharedPreferences) I do not need to select it again but continue listening selected file instead.
UPDATE2: When I define SharePreferences it asks me to remove static from SettingsFragment definition. But when I run the app an error thrown:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.audiotranscriptd/com.example.audiotranscriptd.SettingsActivity}: java.lang.IllegalStateException: Fragment com.example.audiotranscriptd.SettingsActivity.SettingsFragment must be a public static class to be properly recreated from instance state.
Found solution here . It appears in Fragment the getSharedPreferences should be called with getActivity(), like this
sharedPreferences = getActivity().getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
Works for me!

Call another class and getText

public class ustawienia extends MainActivity {
EditText kryptonim;
public String test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ustawienia);
kryptonim = (EditText) findViewById(R.id.edit_kryptonim);
test = kryptonim.getText().toString();
}
public String call_back(){
return test;
}
}
When call call_back() from another class I've got error: Unable to start activity ComponentInfo. What's wrong with that?
When you close an activity all data from it is lost, so unless both activities are runing at the same time you can't retrieve data. You could use shared prefrences instead.
// IN ORDER TO WRITE TO A FILE
SharedPreferences.Editor prefs = getSharedPreferences("PrefsName", MODE_PRIVATE).edit();
prefs.putString("test", kryptonim.getText().toString());
prefs.apply(); // use prefs.commit(); if this doesn't work
In order to read data
SharedPreferences prefsR = getSharedPreferences("PrefsName", MODE_PRIVATE); // you could also write 0 instead MODE_PRIVATE
String restoredText = prefsR.getString("test", null);
Ofcourse you need to import SharedPrefs , and put this in oncreate or wherever you want... let me now if it works :)

Android - Deleting Key Element from SharedPreferences

I'm using the following method to delete a key element on the SharedPreferences of my app. I'm calling it from within a fragment. The problem is that the element is never deleted from SharedPreferences and I get no LogCat output. Is there something wrong with this method? Context perhaps? The deleteFromSharedPreferences is located in a class called Utils and the triggering method is located on a fragment called PagerFragment. Any feedback would be greatly appreciated.
public class PagerFragment extends Fragment {
private void deleteCity() {
deleteFromSharedPref(mCityId, getContext());
}
}
public class Utils {
public static void deleteFromSharedPref(String key, Context context) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(key);
editor.apply();
}
}

Checking if Shared Preferences Exist

Trying to check if if Shared Preferences exist or not. What I need is to allow the user to arrive on a page if they have been here before (i.e. shared preferences exist and are not equal to "") or put them to the welcome page if it is their first time on the app (i.e. shared preferences are blank as user hasn't entered any data).
public class PersonalDetails extends Activity {
private SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_personal_details);
if (sharedPreferences.contains("")) {
Intent intent = new Intent(PersonalDetails.this, Welcome.class);
startActivity(intent);
}
I think getPreferences needs two inputs as below.
public abstract SharedPreferences getSharedPreferences(String name,
int mode);
// Example
getSharedPreferences("your_app_name", MODE_PRIVATE);

how to pass extra intent to two activities

i have an app that on the first activity asks the persons name on the second page it displays the name in a sentence i want to use the name in the third fourth or 9th activity how do i properly declare it (public?) and call it when and where ever i need it? this is my code sending it
Main
public class MainActivity extends Activity {
Button ok;
EditText name;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name=(EditText)findViewById(R.id.editText);
Typeface font_a = Typeface.createFromAsset(getAssets(),"fonts/MarkerFelt.ttf");
name.setTypeface(font_a);
ok=(Button)findViewById(R.id.button);
Typefacefont_b=Typeface.createFromAsset(getAssets(),
"fonts/SignPaintersGothicShaded.ttf");
ok.setTypeface(font_b);
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String nameStr = name.getText().toString();
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
intent.putExtra("NAMEDATA",nameStr);
startActivity(intent);
}
});
}
and this is activity 2 receiving it
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
t = (TextView)findViewById(R.id.textView3);
Typeface font_b = Typeface.createFromAsset(getAssets(),"fonts/MarkerFelt.ttf");
t.setTypeface(font_b);
String n = this.getIntent().getStringExtra("NAMEDATA");
t.setText(n);
so please how would i reuse this?
Use SharedPreferences to save the name or whatever variable you need, then read whenever you need it. First, create global in MainActivity which will be used as preference file name:
public static final String PREFS_NAME = "MyPrefsFile";
Then, to save:
SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("name", name);
editor.commit();
to load:
SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
String name = settings.getString("name", "John");
Once saved, the prefs are accessible for every activity.
So in your case, save the name when ok button is pressed:
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String nameStr = name.getText().toString();
SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("name", nameStr);
editor.commit();
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent);
}
});
Then read it:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
t = (TextView)findViewById(R.id.textView3);
Typeface font_b = Typeface.createFromAsset(getAssets(),"fonts/MarkerFelt.ttf");
t.setTypeface(font_b);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
String n = settings.getString("name", "defaultName");
t.setText(n);
You can do similarly in every activity you need it. See docs here.
You have a number of different approaches to share data between activities. I would say which one you use depends on the ultimate source and destination of the data.
Pass through intents - This is the method you are currently using. To proceed, just keep passing the name to the next intent.
Save to SharedPreference - This method you save the information to the "preference" file of the application. This is useful if the the user is setting up a profile or other semi-fixed information.
Write it to a DB - Here you would create a a new SQLite table for user information and write new rows to it for the name, password, and other info. This has way more overhead and is really only useful if you have multiple users in the same application
Save to a singleton - In this case you create a static class with public properties that can be set. This would be least favorable all the information is lost on application close, but could be useful for temporary creation and retention across many activities. Be warned: bad programming can make singletons a nightmare
Create class extending from Application class.
Implement setter and getter inside that class like,
public class GlobalClass extends Application {
//create setters and getters here
public void setUserInfo(String userInfo) {
}
public void getUserInfo() {
return userInfo;
}
}
then you can use this from any activity like,
GlobalClass app = (GlobalClass ) getApplication();
app.getUserInfo();

Categories

Resources