I want to send these data from current activity to more "BusInformationsCard" activity.
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, final int position) {
viewHolder.busLineName.setText(tickets.get(position).getBusLine());
viewHolder.seatsNumbers.setText(String.valueOf(tickets.get(position).getSeatNum()));
viewHolder.leavingTime.setText(tickets.get(position).getLeavingTime());
viewHolder.companyName.setText(tickets.get(position).getLeavingTime());
viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// here passing data to BusInformationCard
Intent ticketInfo = new Intent(mContext, BusInformationsCard.class);
ticketInfo.putExtra("busLine", tickets.get(position).getBusLine());
ticketInfo.putExtra("companyName", tickets.get(position).getCompany());
ticketInfo.putExtra("driverName", tickets.get(position).getName());
ticketInfo.putExtra("driverPhone", tickets.get(position).getDriverPhone());
ticketInfo.putExtra("seatNum", tickets.get(position).getSeatNum());
ticketInfo.putExtra("leavingTime", tickets.get(position).getLeavingTime());
ticketInfo.putExtra("latitude", tickets.get(position).getLatitude());
ticketInfo.putExtra("longitude", tickets.get(position).getLongitude());
mContext.startActivity(ticketInfo);
}
});
}
you can use shared preference to use your data in all over project. You just need to create an App Preference class like this:-
public class AppPrefrences {
private static SharedPreferences mPrefs;
private static SharedPreferences.Editor mPrefsEditor;
public static boolean isUserLoggedOut(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return mPrefs.getBoolean("id_logged_in", true);
}
public static void setUserLoggedOut(Context ctx, Boolean value) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
mPrefsEditor.putBoolean("id_logged_in", value);
mPrefsEditor.commit();
}
public static String getUserName(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return mPrefs.getString("userName", "");
}
public static void setUserName(Context ctx, String value) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
mPrefsEditor.putString("userName", value);
mPrefsEditor.commit();
}
public static void clearAllPreferences(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
mPrefsEditor.clear();
mPrefsEditor.commit();
}
}
and now just call these methods for save data and get saved data.
create a your own methods for save data and get saved data
You can get your data from one activity to another using Intent's getExtra method
Here is example ::
Example
String name;
name = getIntent().getStringExtra("driverName");
If you wish to pass the complete ticket object, you can use Serializable or Parcelable class in Java.
These classes help you to convert your object in a form which can be transferred between activities.
All you need to do in case of Serializable is to extend your ticket class
public class Ticket extends Serializable {}
In case of Parcelable, you need to add a little bit more code (in case of Java).
public class Ticket extends Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(busLine);
// Similarly for all the other parameters.
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Ticket createFromParcel(Parcel in) {
return new Ticket(in);
}
public Ticket[] newArray(int size) {
return new Ticket[size];
}
};
}
In both these cases, now you can directly pass your complete ticket object in the intent just like intent.putExtra("ticket", ticket); and can receive it in the other activity like, Ticket ticket = getIntent().getSerializableExtra("ticket") */ getParcelable */ if you have extended Parcelable.
The main difference between Parcelable and Serializable is the speed difference, Parcelable is faster than Serializable. Also, parcelable is customisable, and hence developers have the independence to play with their data.
Also Serializable used Java Reflection API, and hence ends up with a lot of garbage object during the conversion.
Related
I have been searching for the correct answer everywhere, but couldn't find it anywhere. That is why I am posting this question, this may look very similar to other questions but I didn't find the answer to this yet. I have to retrieve the user data that was saved during the login on Android device and I want to use the same data in a fragment, I tried using several answers found on StackOverflow, none of them worked for me. Look at the code below, how can I get the user values into strings?
SharedPreferences preferences = getActivity().getSharedPreferences("mysharedpref",Context.MODE_PRIVATE);
String user_name = preferences.getString("user_id",null);
String password = preferences.getString("role", null);
I have to pass these string values to a URL, but it doesn't work. I also checked passing values manually, it's working. For example, if I take assign values to the above strings like
String user_name="admin";
String password="administrator";
Best way to use your SharedPrefernce is by using your appContext that is accessible to the whole App(Common SharedPrefernce and accessible Everywhere).
Define your SharedPrefernce instance in your Application class with get and set methods as below : (If you have not created the Application class then create one as below, This class is called at the start of your app)
public class Application extends android.app.Application {
private static Application _instance;
private static SharedPreferences _preferences;
#Override
public void onCreate() {
super.onCreate();
_instance = this;
}
public static Application get() {
return _instance;
}
/**
* Gets shared preferences.
*
* #return the shared preferences
*/
public static SharedPreferences getSharedPreferences() {
if (_preferences == null)
_preferences = PreferenceManager.getDefaultSharedPreferences(_instance);
return _preferences;
}
//set methods
public static void setPreferences(String key, String value) {
getSharedPreferences().edit().putString(key, value).commit();
}
public static void setPreferences(String key, long value) {
getSharedPreferences().edit().putLong(key, value).commit();
}
public static void setPreferences(String key, int value) {
getSharedPreferences().edit().putInt(key, value).commit();
}
public static void setPreferencesBoolean(String key, boolean value) {
getSharedPreferences().edit().putBoolean(key, value).commit();
}
//get methods
public static String getPrefranceData(String key) {
return getSharedPreferences().getString(key, "");
}
public static int getPrefranceDataInt(String key) {
return getSharedPreferences().getInt(key, 0);
}
public static boolean getPrefranceDataBoolean(String key) {
return getSharedPreferences().getBoolean(key, false);
}
public static long getPrefranceDataLong(String interval) {
return getSharedPreferences().getLong(interval, 0);
}
}
Declare the Application class in AndroidManifest.xml file with line android:name=".Application" as shown in below snippet:
<application
android:name=".Application"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="#style/AppTheme">
Now, How to store key-value:
Application.setPreferences("Key","String_Value");
How to fetch key-value:
String value_string=Application.getPrefranceData("Key");
You can now set-SharedPrefernce key-value and get-SharedPrefernce value from anywhere in the app using public Application class and the static get and set methods
Firstly create a SharedPreference.java Class.
public class SharedPreference {
Context context;
SharedPreferences sharedPreferences;
String user_name;
String password;
public SharedPreference(Context co) {
context = co;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
}
public String getPassword() {
password = getStringInput("password");
return password;
}
public void setPassword(String password) {
this.password = password;
stringInput("password", password);
}
public String getUser_name() {
user_name = getStringInput("Username");
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
stringInput("Username", user_name);
}
public void stringInput(String key, String value) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
public String getStringInput(String key) {
return sharedPreferences.getString(key, "0");
}
}
Now go into activity or Fragment
example: I'm gone use it in MainActivity.java
public class MainActivity extends AppCompatActivity {
Prefrences prefrences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Dashboard");
prefrences = new Prefrences(MainActivity.this);
prefrences.setUser_name("Rishabh Jain");
prefrences.setUser_name("8369554235");
Log.e("Details",prefrences.getUser_name()+" "+prefrences.getPassword())
}
}
The output will be Rishabh Jain 8369554235.
Similarly, you can use this in any Activity or any Fragment
I guess you are trying to get values with different key. Get values with same key you put them with.
String user_name = preferences.getString(preferences.KEY_USERNAME,null);
String password = preferences.getString(preferences.KEY_PASSWORD, null);
----BUT----
And don't use singleton pattern for SharedPreferences it is very bad to use Context in singleton. It will crash your app. You can figure it out why.
Instead use static methods.
public class PreferenceUtil {
public static final String PASSWORD = "PASSWORD";
public static void setInt(Context context, int in, String key) {
SharedPreferences settings;
Editor editor;
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
editor = settings.edit();
editor.putInt(key, in);
editor.apply();
}
public static int getInt(Context context, String key) {
SharedPreferences settings;
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
if (settings.contains(key)) {
return settings.getInt(key, 0);
} else
return 0;
}
}
And access it like this
int password = PreferenceUtil.getInt(getActivity(), PreferenceUtil.PASSWORD);
How can I use savePreferences and loadPreferences methods
In first activity
private static final String GLOBAL_PREFERENCES = "music_status";
public static void savePreferences(#NonNull Context context, String key, int value) {
SharedPreferences sharedPreferences = context.getSharedPreferences(GLOBAL_PREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(key, value);
editor.apply();
}...
protected void onResume() {
super.onResume();
musicGroup = (RadioGroup) findViewById(R.id.radioGroupForMusic);
turnOn = (RadioButton) findViewById(R.id.radioButtonMusicOn);
turnOff = (RadioButton) findViewById(R.id.radioButtonMusicOff);
musicGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.radioButtonMusicOff:
mediaPlayer.pause();
savePreferences(MainMenuActivity.this,"music_status",0);
case R.id.radioButtonMusicOn:
mediaPlayer.start();
savePreferences(MainMenuActivity.this,"music_status",1);
}
}
});
}
In Second activity
private static final String GLOBAL_PREFERENCES = "music_status";
public static int loadPreferences(#NonNull Context context, String key, int defaultValue) {
SharedPreferences sharedPreferences = context.getSharedPreferences(GLOBAL_PREFERENCES, Context.MODE_PRIVATE);
return sharedPreferences.getInt(key, defaultValue);
}
However I do not know how to get the value from first activity
The short answer is you cannot do that. Unless your status variable is static. Which is extremely bad for this case.
You have three choices.
SharedPreferences
In contrast to my previous revision. This might be the best option for your case.
If you only want to save the state of something, you might find it better to simply not use a class to hold the status of your music. You could do as #cricket_007 suggests and implement SharedPreferences.
You could use these example functions:
private static final String GLOBAL_PREFERENCES = "a.nice.identifier.for.your.preferences.goes.here";
public static void savePreferences(#NonNull Context context, String key, int value) {
SharedPreferences sharedPreferences = context.getSharedPreferences(GLOBAL_PREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(key, value);
editor.apply();
}
public static int loadPreferences(#NonNull Context context, String key, int defaultValue) {
SharedPreferences sharedPreferences = context.getSharedPreferences(GLOBAL_PREFERENCES, Context.MODE_PRIVATE);
return sharedPreferences.getInt(key, defaultValue);
}
You can then use those functions in your code to save the status of your music. Instead of status.setStatus(0); and status.setStatus(1); your can use Utils.savePreferences(context, "music_status", 1); and instead of status.getStatus() you could use Utils.loadPreferences(context, "music_status", 0);
Parcelable
One option for you is to implement Parcelable in your musicStatus class. You can then send the object through an Intent to your second activity. You may find an example class implementing Parcelable below.
Once you have that, you can pass it through Intents like so:
musicStatus status = new musicStatus();
status.setStatus(8);
Intent intent = new Intent(this, HighScoreActivity.class);
intent.putExtra("status", status);
startActivity(intent);
Class implementation:
public class musicStatus implements Parcelable {
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status){
this.status = status;
}
private musicStatus(Parcel in) {
status = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(status);
}
public static final Parcelable.Creator<musicStatus> CREATOR = new Parcelable.Creator<musicStatus>() {
public musicStatus createFromParcel(Parcel in) {
return new musicStatus(in);
}
public musicStatus[] newArray(int size) {
return new musicStatus[size];
}
};
public int describeContents() {
return 0;
}
}
Singleton
In this case, this would really be an anti-pattern. However, it is still a possibility.
public class musicStatus {
private static musicStatus mInstance = null;
private int status;
#NonNull
public static musicStatus getInstance() {
if (mInstance == null) {
synchronized(mInstance) {
if (mInstance == null) {
mInstance = new musicStatus();
}
}
}
}
public int getStatus(){
return status;
}
public void setStatus(int status){
this.status = status;
}
}
For the easiest way, your musicStatus class need implement Serializable.
Bundle bundle = new Bundle();
bundle.putSerializable("musicStatus", status);
intent.putExtras(bundle);
in other activity:
Intent intent = this.getIntent();
Bundle bundle = intent.getExtras();
musicStatus status=
(musicStatus)bundle.getSerializable("musicStatus");
extend Serviceable in you POJO class.
After while starting Activity 2.
intetn.putExtra("obj",pojoObj);
and get it in you second activity using.
PojoCls obj = (PojoCls)getIntent().getSerializableExtra("obj");
Thats it.
I'm trying to implement MVP without Dagger (for learning purposes). But I got to the problem - I use Repository patter to get raw data either from cache (Shared Preferences) or network:
Shared Prefs|
|<->Repository<->Model<->Presenter<->View
Network|
But to put my hands on Shared Preferences I have to put somewhere line like
presenter = new Presenter(getApplicationContext());
I use onRetainCustomNonConfigurationInstance/getLastCustomNonConfigurationInstance pair to keep Presenter "retained".
public class MyActivity extends AppCompatActivity implements MvpView {
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
presenter = (MvpPresenter) getLastCustomNonConfigurationInstance();
if(null == presenter){
presenter = new Presenter(getApplicationContext());
}
presenter.attachView(this);
}
#Override
public Object onRetainCustomNonConfigurationInstance() {
return presenter;
}
//...
}
So how to use Shared Preferences in MVP without Dagger and not causing Presenter to be Context dependent?
Your Presenter should not be Context dependent in the first place. If your presenter needs SharedPreferences you should pass them in the constructor.
If your presenter needs a Repository, again, put that in the constructor. I highly suggest watching Google clean code talks since they do a really good job explaining why you should use a proper API.
This is proper dependency management, which will help you write clean, maintainable, and testable code.
And whether you use dagger, some other DI tool, or supply the objects yourself is irrelevant.
public class MyActivity extends AppCompatActivity implements MvpView {
#Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences preferences = // get your preferences
ApiClient apiClient = // get your network handling object
Repository repository = new Repository(apiClient, preferences);
presenter = new Presenter(repository);
}
}
This object creation can be simplified by using a factory pattern, or some DI framework like dagger, but as you can see above neither Repository nor your presenter depends on a Context. If you want to supply your actual SharedPreferences only their creation of them will depend on the context.
Your repository depends on some API client and SharedPreferences, your presenter depends on the Repository. Both classes can easily be tested by just supplying mocked objects to them.
Without any static code. Without any side effects.
This is how I do it. I have a singleton "SharedPreferencesManager" class that will handle all the read write operations to shared prefs like below
public final class SharedPreferencesManager {
private static final String MY_APP_PREFERENCES = "ca7eed88-2409-4de7-b529-52598af76734";
private static final String PREF_USER_LEARNED_DRAWER = "963dfbb5-5f25-4fa9-9a9e-6766bfebfda8";
... // other shared preference keys
private SharedPreferences sharedPrefs;
private static SharedPreferencesManager instance;
private SharedPreferencesManager(Context context){
//using application context just to make sure we don't leak any activities
sharedPrefs = context.getApplicationContext().getSharedPreferences(MY_APP_PREFERENCES, Context.MODE_PRIVATE);
}
public static synchronized SharedPreferencesManager getInstance(Context context){
if(instance == null)
instance = new SharedPreferencesManager(context);
return instance;
}
public boolean isNavigationDrawerLearned(){
return sharedPrefs.getBoolean(PREF_USER_LEARNED_DRAWER, false);
}
public void setNavigationDrawerLearned(boolean value){
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putBoolean(PREF_USER_LEARNED_DRAWER, value);
editor.apply();
}
... // other shared preference accessors
}
Then whenever access to shared preference is needed I pass the SharedPreferencesManager object in the relevant Presenter's constructor. For example :
if(null == presenter){
presenter = new Presenter(SharedPreferencesManager.getInstance(getApplicationContext()));
}
Hope this helps!
Another approach can also be found in the Android Architecture libraries:
As the Shared Preferences depends on a context, it solely should know about it. To have things in one place, I choose a Singleton to manage this. It consists of two classes: the Manager (i.e. the SharePreferenceManager or ServiceManager or whatever), and an initializer which injects the Context.
class ServiceManager {
private static final ServiceManager instance = new ServiceManager();
// Avoid mem leak when referencing context within singletons
private WeakReference<Context> context
private ServiceManager() {}
public static ServiceManager getInstance() { return instance; }
static void attach(Context context) { instance.context = new WeakReference(context); }
... your code...
}
The initializer is basically an empty Provider (https://developer.android.com/guide/topics/providers/content-providers.html), which is registered in the AndroidManifest.xml and loaded when the app starts:
public class ServiceManagerInitializer extends ContentProvider {
#Override
public boolean onCreate() {
ServiceManager.init(getContext());
return false;
}
#Nullable
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, #Nullable String selection, #Nullable String[] selectionArgs, #Nullable String sortOrder) {
return null;
}
#Nullable
#Override
public String getType(#NonNull Uri uri) {
return null;
}
#Nullable
#Override
public Uri insert(#NonNull Uri uri, #Nullable ContentValues values) {
return null;
}
#Override
public int delete(#NonNull Uri uri, #Nullable String selection, #Nullable String[] selectionArgs) {
return 0;
}
#Override
public int update(#NonNull Uri uri, #Nullable ContentValues values, #Nullable String selection, #Nullable String[] selectionArgs) {
return 0;
}
}
All function are default implementations except the onCreate, which injects the required context into our manager.
Last step to get this working is to register the provider in the manifest:
<provider
android:authorities="com.example.service-trojan"
android:name=".interactor.impl.ServiceManagerInitializer"
android:exported="false" />
This way, your service manager is decoupled from any external context initialization. It now can be completely replaced with another implementation which is context-independent.
This is how I implement it. You can design it with an interface where you have different implementation for your app and test. I have used interface PersistentStorage which I provide depdencdy from UI/tests. This is just an idea, feel free to modify it.
From your Activity/Fragment
public static final String PREF_NAME = "app_info_cache";
#Inject
DataManager dataManager;
void injectDepedendency(){
DaggerAppcompnent.inject(this);//Normal DI withDagger
dataManager.setPersistentStorage(new PersistentStorageImp(getSharedPreferences()));
}
//In case you need to pass from Fragment then you need to resolve getSharedPreferences with Context
SharedPreferences getSharedPreferences() {
return getSharedPreferences(PREF_NAME,
Context.MODE_MULTI_PROCESS | Context.MODE_MULTI_PROCESS);
}
//This is how you can use in Testing
#Inject
DataManager dataManager;
#Before
public void injectDepedendency(){
DaggerTestAppcompnent.inject(this);
dataManager.setPersistentStorage(new MockPersistentStorageImp());
}
#Test
public void testSomeFeature_ShouldStoreInfo(){
}
/**
YOUR DATAMANAGER
*/
public interface UserDataManager {
void setPersistentStorage(PersistentStorage persistentStorage);
}
public class UserDataManagerImp implements UserDataManager{
PersistentStorage persistentStorage;
public void setPersistentStorage(PersistentStorage persistentStorage){
this.persistentStorage = persistentStorage;
}
}
public interface PersistentStorage {
/**
Here you can define all the methods you need to store data in preferences.
*/
boolean getBoolean(String arg, boolean defaultval);
void putBoolean(String arg, boolean value);
String getString(String arg, String defaultval);
void putString(String arg, String value);
}
/**
PersistentStorage Implementation for Real App
*/
public class PersistentStorageImp implements PersistentStorage {
SharedPreferences preferences;
public PersistentStorageImp(SharedPreferences preferences){
this.preferences = preferences;
}
private SharedPreferences getSharedPreferences(){
return preferences;
}
public String getString(String arg, String defaultval) {
SharedPreferences pref = getSharedPreferences();
return pref.getString(arg, defaultval);
}
public boolean getBoolean(String arg, boolean defaultval) {
SharedPreferences pref = getSharedPreferences();
return pref.getBoolean(arg, defaultval);
}
public void putBoolean(String arg, boolean value) {
SharedPreferences pref = getSharedPreferences();
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean(arg, value);
editor.commit();
}
public void putString(String arg, String value) {
SharedPreferences pref = getSharedPreferences();
SharedPreferences.Editor editor = pref.edit();
editor.putString(arg, value);
editor.commit();
}
}
/**
PersistentStorage Implementation for testing
*/
public class MockPersistentStorageImp implements PersistentStorage {
private Map<String,Object> map = new HashMap<>();
#Override
public boolean getBoolean(String key, boolean defaultval) {
if(map.containsKey(key)){
return (Boolean) map.get(key);
}
return defaultval;
}
#Override
public void putBoolean(String key, boolean value) {
map.put(key,value);
}
#Override
public String getString(String key, String defaultval) {
if(map.containsKey(key)){
return (String) map.get(key);
}
return defaultval;
}
#Override
public void putString(String key, String value) {
map.put(key,value);
}
}
I want to get a string from my shared preference file and use for more classes, but I don't know why not work.
My reader class is:
import android.app.Activity;
import android.content.SharedPreferences;
public class A {
public static String url2;
public void execute() {
String URLPref = "URL";
SharedPreferences prefs = getSharedPreferences("com.exam.search_preferences",Activity.MODE_PRIVATE);
url2 = prefs.getString(URLPref , "");
}
private SharedPreferences getSharedPreferences(String string,
int modePrivate) {
return null;
}
}
And the second class that uses the string
public class SearchHome extends Activity {
static String url2;
A cls2= new A();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_activity);
cls2.execute();
url2 = A.url2;
Toast.makeText(getApplicationContext(),"URL:" + url2 ,
Toast.LENGTH_LONG).show();
...
Sorry for my bad english, I never learned.But I'm trying!
You need to pass the Context to your class A, because you can get the SharedPreferences from a Context object. NOTE, an Activity is a Context to some extend
public class A {
public static String url2;
/** #param context used to get the SharedPreferences */
public void execute(Context context) {
String URLPref = "URL";
SharedPreferences prefs = context.getSharedPreferences("com.exam.search_preferences",Activity.MODE_PRIVATE);
url2 = prefs.getString(URLPref , "");
}
}
And then pass the Context to your execute method
public class SearchHome extends Activity {
static String url2;
A cls2= new A();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_activity);
// pass context 'this' to the execute function
// This works, because SearchHome extends Activity
cls2.execute(this);
url2 = A.url2;
...
if your data is not confidential it would be a lot easier if you can make a class specially for shared preference and have other activities access it. you will save a lot of time and code will be a lot simpler to follow up
public class HelperShared {
public static final String score = "Score";
public static final String tag_User_Machine = "tag_User_Machine",
tag_Machine_Machine = "tag_Machine_Machine",
tag_Draw_Machine = "tag_Draw_Machine",
tag_Total_Machine = "tag_Total_Machine";
public static SharedPreferences preferences;
public static Editor editor;
public HelperShared(Context context) {
this.preferences = context.getSharedPreferences(score,
Activity.MODE_PRIVATE);
this.editor = preferences.edit();
}
/*
* Getter and Setter methods for Machine
*/
public void setUserMachine(int UserMachine) {
editor.putInt(tag_User_Machine, UserMachine);
editor.commit();
}
public void setMachineMachine(int MachineMachine) {
editor.putInt(tag_Machine_Machine, MachineMachine);
editor.commit();
}
public void setDrawMachine(int DrawMachine) {
editor.putInt(tag_Draw_Machine, DrawMachine);
editor.commit();
}
public void setTotalMachine(int TotalMachine) {
editor.putInt(tag_Total_Machine, TotalMachine);
editor.commit();
}
public int getUserMachine() {
return preferences.getInt(tag_User_Machine, 0);
}
public int getMachineMachine() {
return preferences.getInt(tag_Machine_Machine, 0);
}
public int getDrawMachine() {
return preferences.getInt(tag_Draw_Machine, 0);
}
public int getTotalMachine() {
return preferences.getInt(tag_Total_Machine, 0);
}
}
private SharedPreferences getSharedPreferences(String string,
int modePrivate) {
return null;
}
problem is here.
return null;
you have to return valid SharedPreferences object. otherwise you will always get NullPointerException.
Call this when you want to put a pref:
putPref("myKey", "mystring", getApplicationContext());
Call this when you want to get a pref:
getPref("myKey", getApplicationContext());
You can use SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings. This data will persist across user sessions (even if your application is killed).
Different Modes:
1 MODE_APPEND
This will append the new preferences with the already exisiting preferences
2 MODE_ENABLE_WRITE_AHEAD_LOGGING
Database open flag. When it is set , it would enable write ahead logging by default
3 MODE_MULTI_PROCESS
This method will check for modification of preferences even if the sharedpreference instance has already been loaded
4 MODE_PRIVATE
By setting this mode , the file can only be accessed using calling application
5 MODE_WORLD_READABLE
This mode allow other application to read the preferences
6 MODE_WORLD_WRITEABLE
This mode allow other application to write the preferences
Read More
You just need to make shared prefrences object in class where you want to have data
SharedPreferences prefrences = getSharedPreferences("my prefs",MODE_PRIVATE)
Editor editor = prefrences.edit();
String s = edit.getString("your key",value);
hope it helps !
I am having a class EmployeeInfo as the following:
public class EmployeeInfo {
private int id; // Employee ID
private String name; // Employee Name
private int age;// Employee Age
public int getEmployeeID() {
return id;
}
public void setEmployeeID(int id) {
this.id = id;
}
public String getEmployeeName() {
return name;
}
public void setEmployeeName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age= age;
}
}
ArrayList<EmployeeInfo> employeeInfo object contains the emplyoyee info data for multiple employees.
I want to transfer the data( ArrayList employeeInfo ) from Activity1 to Activity2.
Is using Parcelable the only way to transfer the data from Activity1 to Activity2?
If not , what are the alternatives.
If yes ,kindly provide the prototype code of Parcelable along with the sample code on how to transfer the object data from Activity1 to Activity2.
Here is my implementation of Parceleble:
public class ProfileData implements Parcelable {
private int gender;
private String name;
private String birthDate;
public ProfileData(Parcel source) {
gender = source.readInt();
name = source.readString();
birthDate = source.readString();
}
public ProfileData(int dataGender, String dataName, String dataBDate) {
gender = dataGender;
name = dataName;
birthDate = dataBDate;
}
// Getters and Setters are here
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(gender);
out.writeString(name);
out.writeString(birthDate);
}
public static final Parcelable.Creator<ProfileData> CREATOR
= new Parcelable.Creator<ProfileData>() {
public ProfileData createFromParcel(Parcel in) {
return new ProfileData(in);
}
public ProfileData[] newArray(int size) {
return new ProfileData[size];
}
};
}
and how I transfer data:
Intent parcelIntent = new Intent().setClass(ActivityA.this, ActivityB.class);
ProfileData data = new ProfileData(profile.gender, profile.getFullName(), profile.birthDate);
parcelIntent.putExtra("profile_details", data);
startActivity(parcelIntent);
and take data:
Bundle data = getIntent().getExtras();
ProfileData profile = data.getParcelable("profile_details");
You can simply let your EmployeeInfo class implement Serializable. Or you can send data like this
intent.putExtra("id", employInfo.getEmployeeID());
intent.putExtra("name", employInfo.getEmployeeName());
intent.putExtra("age", employInfo.getAge());
If you need to transfer a list of your custom classes, i'd use the first approach. So you would be able to put entire list as Serializable.
However they said that everyone should use Parcelable instead because it's "way faster". Tbh, I'd never used it, because it needs more effort and I doubt somebody can realize the difference in speed in a regular application w/o a load of data sending via intent
Good question. Looking at the docs and doing armchair coding:
It may be possible to pass an object between Activities by calling putExtras(Bundle) and myBundle.putSerializable. The object and the entire object tree would need to implement serializable.
JAL
EDIT: The answer is yes:
It is possible to pass an immutable object between Activities by calling putExtras(Bundle) and myBundle.putSerializable. The object and the entire object tree would need to implement serializable. This is a basic tenet of Object Oriented Programming, passing of stateful messages.
First we create the immutable object by declaring a new class:
package jalcomputing.confusetext;
import java.io.Serializable;
/*
* Immutable messaging object to pass state from Activity Main to Activity ManageKeys
* No error checking
*/
public final class MainManageKeysMessage implements Serializable {
private static final long serialVersionUID = 1L;
public final int lengthPassword;
public final long timeExpire;
public final boolean isValidKey;
public final int timeoutType;
public MainManageKeysMessage(int lengthPassword, long timeExpire, boolean isValidKey, int timeoutType){
this.lengthPassword= lengthPassword;
this.timeExpire= timeExpire;
this.isValidKey= isValidKey;
this.timeoutType= timeoutType;
}
}
Then we create an immutable stateful instance of the class, a message, in the parent activity, and send it in an intent as in:
private void LaunchManageKeys() {
Intent i= new Intent(this, ManageKeys.class); // no param constructor
// push data (4)
MainManageKeysMessage message= new MainManageKeysMessage(lengthPassword,timeExpire,isValidKey,timeoutType);
Bundle b= new Bundle();
b.putSerializable("jalcomputing.confusetext.MainManageKeysMessage", message);
i.putExtras(b);
startActivityForResult(i,REQUEST_MANAGE_KEYS); // used for callback
}
Finally, we retrieve the object in the child activity.
try {
inMessage= (MainManageKeysMessage) getIntent().getSerializableExtra("jalcomputing.confusetext.MainManageKeysMessage");
lengthPassword= inMessage.lengthPassword;
timeoutType= inMessage.timeoutType;
isValidKey= inMessage.isValidKey;
timeExpire= inMessage.timeExpire;
} catch(Exception e){
lengthPassword= -1;
timeoutType= TIMEOUT_NEVER;
isValidKey= true;
timeExpire= LONG_YEAR_MILLIS;
}
Well there is another way to transfer an object.We can use application to transfer object and this is way is far better way in my opinion.
First of all create your custom application in your main package.
public class TestApplication extends Application {
private Object transferObj;
#Override
public void onCreate() {
super.onCreate();
// ACRA.init(this);
}
public Object getTransferObj() {
return transferObj;
}
public void setTransferObj(Object transferObj) {
this.transferObj = transferObj;
}
}
Now use setTransfer and get transfer methods to move abjects from one activity to other like:
To Transfer:
((TestApplication) activity.getApplication()).setTransferObj(Yous object);
ToRecieve:
Object obj=((TestApplication) activity.getApplication()).getTransferObj();
NOTE
Always remember to make entry of this application in manifest application tag:
<application
android:name=".TestApplication">
</application>
You can convert your object to jsonstring using Gson or Jakson and pass using intent as string and read the json in another activity.