I would like to store my server response as a string in Shared Preferences so that I can use this response later without fetching from server. But when I saved the data in Shared Preferences and later I use I miss the whole response. I have no security issue and any other cause like uninstall app etc. My question is whether the response will be lost in Shared Preferences so that the response contain multiple JSONObject and JSONArray.
private void productListApi(String url){
final ProgressDialog pDialog = new ProgressDialog(mContext);
pDialog.setMessage(mContext.getResources().getString(R.string.loading_message));
pDialog.show();
System.out.println("product list urlllllllllllllllllllll:" + url);
RequestQueue mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println("response of product list data is:"
+ response);
apiResponse = response ;
pDialog.dismiss();
try {
JSONObject json = new JSONObject(response);
if (json.has("code")) {
if (code.equalsIgnoreCase("200")) {
//set response to shared preference
SharedPreference.setStringValue(mContext, SharedPreference.PRODUCT_LIST_RESPONSE, response);
parseData(SharedPreference.getStringValue(mContext,SharedPreference.PRODUCT_LIST_RESPONSE));
}else {
UserDialog
.showUserAlert(mContext,
mContext.getResources().getString(R.string.product_list_failed));
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
pDialog.dismiss();
UserDialog.showUserAlert(mContext,
mContext.getResources().getString(R.string.no_response));
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
// the POST parameters:
params.put("user_id", SharedPreference.getStringValue(getActivity(), SharedPreference.USER_ID));
params.put("temp_user_id", SharedPreference.getStringValue(getActivity(), SharedPreference.TEMP_USER_ID));
params.put("version", Utilities.getVersionCode(mContext));
params.put("device_token", SharedPreference.getStringValue(getActivity(), SharedPreference.DEVICE_TOKEN));
return params;
}
};
int socketTimeout = Constant.socketTimeout
;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
//RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
postRequest.setRetryPolicy(policy);
mRequestQueue.add(postRequest);
}
public class SharedPreference {
SharedPreferences preferences;
SharedPreferences.Editor editor;
private static final String PREFS_NAME = "nevada_food";
public static final String PRODUCT_LIST_RESPONSE = "product_list" ;
public SharedPreference() {
super();
// TODO Auto-generated constructor stub
}
public static String getStringValue(final Context context, String key) {
return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
.getString(key, "");
}
public static void setStringValue(final Context context, String key,
String value) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFS_NAME, Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = prefs.edit();
editor.putString(key, value);
editor.commit();
}
}
this is my server response. I saved it in Shared Preferences and parse data in UI from Shared Preferences. This method
parseData(SharedPreference.getStringValue(mContext,SharedPreference.PRODUCT_LIST_RESPONSE));
works properly first time when directly from server but when we use this method in another it does not work.
Data stored in SharedPreference does not loss until unless:
You clear it by manually or programmatically.
Any cache clearing application won't clear application cache.
You uninstall your application.
Depending on scenario you can opt from following approach to save/cache your json data/response:
SharedPreference more convenient to use.
Writing it text file as private or public in external/internal storage. Data stored in external store won't loss even if you uninstall application.
If json is big and there is trade off associated with calling server every time you can go creating Sqlite database or can choose ORM tools like ORMLite, GreeDao etc.
Caching library can be used to cache server response.
My question is whether the response will be lost in Shared Preferences
Shared preferences won't be removed/lost, unless:
you remove them
user clears app data
So, you are safe to store there necessary data.
You are using a wrong way to save into SharedPreference.
Your Code:
//set response to shared preference
SharedPreference.setStringValue(mContext, SharedPreference.PRODUCT_LIST_RESPONSE, response);
parseData(SharedPreference.getStringValue(mContext,SharedPreference.PRODUCT_LIST_RESPONSE));
I don't have any clue what you written here. Try my solution below.
You should have to follow the simple SharedPreference format followed by its Editor.
Just save your data like below:
SharedPreferences.Editor editor = getSharedPreferences("PREFS_NAME", 0).edit();
editor.putString("PRODUCT_LIST_RESPONSE", response);
editor.commit();
And get it by the KEY (PRODUCT_LIST_RESPONSE here)
SharedPreferences prefs = getSharedPreferences("PREFS_NAME", 0);
String response = prefs.getString("PRODUCT_LIST_RESPONSE", any_default_Value);
Related
I am trying to implement server side using php Joomla API for my application. User sends login info and server processes and creates session successfully. However, i am unable to catch this session data in android. I am using volley to perform the post, however multiple post seems to create new logins which should not be the case as user is already logged in. I am guessing their is a problem with headers being sent by volley. Anyone with a solution for this i will appreciate.
Note server side is working 100%. Problem is only with android.
protected void doLogin(){
final String username = editTextUsername.getText().toString().trim();
final String password = editTextPassword.getText().toString().trim();
final CookieManager cookieManager = new CookieManager(new PersistentCookieStore(getApplicationContext()), CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager);
RequestQueue queue = Volley.newRequestQueue(this);
String loginUrl ="http://loginurl/sesslogin/";
final StringRequest stringRequest = new StringRequest(Request.Method.POST, loginUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//COOKIE_JAR = cookieManager.getCookieStore().getCookies().toString();
//PersistentCookieStore.getCookies();
// Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG).show();
//stringRequest.getHeaders().values()
Toast.makeText(getApplicationContext(), response , Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "That didn't work!", Toast.LENGTH_LONG).show();
}
}
){
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put(KEY_USERNAME,username);
params.put(KEY_PASSWORD,password);
return params;
}
};
queue.add(stringRequest);
}
I also got an implementation of shared preference and cookie manager that i found on Github and is part of my code. But i dont see any impact of this code.
public class PersistentCookieStore implements CookieStore {
/**
* The default preferences string.
*/
private final static String PREF_DEFAULT_STRING = "";
/**
* The preferences name.
*/
private final static String PREFS_NAME = PersistentCookieStore.class.getName();
/**
* The preferences session cookie key.
*/
private final static String PREF_SESSION_COOKIE = "Set-Cookie";
private CookieStore mStore;
private Context mContext;
/**
* #param context The application context
*/
public PersistentCookieStore(Context context) {
// prevent context leaking by getting the application context
mContext = context.getApplicationContext();
// get the default in memory store and if there is a cookie stored in shared preferences,
// we added it to the cookie store
mStore = new CookieManager().getCookieStore();
String jsonSessionCookie = getJsonSessionCookieString();
if (!jsonSessionCookie.equals(PREF_DEFAULT_STRING)) {
Gson gson = new Gson();
HttpCookie cookie = gson.fromJson(jsonSessionCookie, HttpCookie.class);
mStore.add(URI.create(cookie.getDomain()), cookie);
}
}
#Override
public void add(URI uri, HttpCookie cookie) {
if (cookie.getName().equals("sessionid")) {
// if the cookie that the cookie store attempt to add is a session cookie,
// we remove the older cookie and save the new one in shared preferences
remove(URI.create(cookie.getDomain()), cookie);
saveSessionCookie(cookie);
}
mStore.add(URI.create(cookie.getDomain()), cookie);
}
#Override
public List<HttpCookie> get(URI uri) {
return mStore.get(uri);
}
#Override
public List<HttpCookie> getCookies() {
return mStore.getCookies();
}
#Override
public List<URI> getURIs() {
return mStore.getURIs();
}
#Override
public boolean remove(URI uri, HttpCookie cookie) {
return mStore.remove(uri, cookie);
}
#Override
public boolean removeAll() {
return mStore.removeAll();
}
private String getJsonSessionCookieString() {
return getPrefs().getString(PREF_SESSION_COOKIE, PREF_DEFAULT_STRING);
}
/**
* Saves the HttpCookie to SharedPreferences as a json string.
*
* #param cookie The cookie to save in SharedPreferences.
*/
private void saveSessionCookie(HttpCookie cookie) {
Gson gson = new Gson();
String jsonSessionCookieString = gson.toJson(cookie);
SharedPreferences.Editor editor = getPrefs().edit();
editor.putString(PREF_SESSION_COOKIE, jsonSessionCookieString);
editor.apply();
}
private SharedPreferences getPrefs() {
return mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
}
I have identified the issue. So i will answer this for anyone encountering the same problem. The problem was here;
final CookieManager cookieManager = new CookieManager(new PersistentCookieStore(getApplicationContext()), CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager);
This CookieManager for some reason should be instatiated during the onCreate method. Also the type final is unnecesary here. My final code is as follows;
#Override
protected void onCreate(Bundle savedInstanceState) {
//INSTANTIATE COOKIE MANAGER
CookieManager cookieManager = new CookieManager(new PersistentCookieStore(this.getApplicationContext()), CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager);
doLogin();
}
For example: I have a String value "A". and I have activities : activity_a, activity_b, activity_C.
Can I use value "A" across all activities? If yes how to achieve this?
And not through Intent or send data to another activity.
I am sorry that I am not fluent in English.
I moved a token value in login activity to main activity.
I used Intent and move token login activity. this is my login activity code.
StringRequest stringRequest = new StringRequest(Request.Method.POST, serverURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try{
JSONArray jsonArray = new JSONArray(response);
JSONObject json_code = jsonArray.getJSONObject(0);
JSONObject json_token = jsonArray.getJSONObject(1);
String code = json_code.getString("code");
String token = json_token.getString("token");
Intent myIntent = new Intent(loginActivity.this, mainActivity.class);
myIntent.putExtra("token", token);
startActivity(myIntent);
finish();
overridePendingTransition(R.xml.madefadein, R.xml.splashfadeout);
}catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
switch(error.networkResponse.statusCode)
{
case 409:
Toast.makeText(loginActivity.this, error.networkResponse.toString(), Toast.LENGTH_SHORT).show();
break;
}
}
but in main Activity, I tried to declare static like this.
Intent i = new Intent(getIntent());
public static final String token = i.getStringExtra("token");
but it doesn't work.
1.just declare your String as public static String strTmp="A"; in your activity than you can use any where in your project
like this
String strTmp = yourActivity.str;
2. create a new class like this
public class ServiceClass {
public static String strTmp="Data";
}
now you can access this string anywhere in your project like this
String mystr= ServiceClass.strTmp;
3.if you want use hard String than store your string in res/values/string.xml like this
<resources>
<string name="app_name">PatternView</string>
</resources>
than you can use like this
String str = getResources().getString(R.string.app_name);
4. save it in SharedPreferences like this
code for save data in SharedPreferences like this
SharedPreferences myPref;
SharedPreferences.Editor prefEditor;
myPref = getSharedPreferences("TOKENNAME", MODE_PRIVATE);
prefEditor = myPref.edit();
prefEditor.putString("TOKEN", "your token");
prefEditor.apply();
code for retrieve data from SharedPreferences
SharedPreferences myPref;
myPref = getSharedPreferences("TOKENNAME",
MODE_PRIVATE);
String name = myPref.getString("TOKEN", "");
Is there a way to save the JSON data at the phone so that you can see the data if your phone is offline?
And what would be the best option to cache data ? SharedPreferences or SQLite database
Here is my code, which i am using to Parse JSON:
if (InternetConnection.checkConnection(getApplicationContext()))
new GetDataTask().execute();
class GetDataTask extends AsyncTask<Void, Void, Void> {
private static final String KEY_ICONURL ="http://droid.hol.es/images/"; ;
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(Exit_View_Activity.this);
dialog.show();
}
#Nullable
#Override
protected Void doInBackground(Void... params) {
jsonObject = JSONParser.getDataFromWeb();
try {
if (jsonObject != null) {
if(jsonObject.length() > 0) {
JSONArray array = jsonObject.getJSONArray(Keys.KEY_INFO);
int lenArray = array.length();
if(lenArray > 0) {
for(int jIndex = 0; jIndex < lenArray; jIndex++) {
MyDataModel model = new MyDataModel();
JSONObject innerObject = array.getJSONObject(jIndex);
String name = innerObject.getString(Keys.KEY_NAME);
String viewtype = innerObject.getString(Keys.KEY_VIEWTYPE);
String image = innerObject.getString(Keys.KEY_ICON);
String Constantfilter = cat_id.replaceAll("[^0-9,]","");
Log.i("CONSTANT :",Constantfilter);
String[] numbers = Constantfilter.split(",");
for (int i=0;i<numbers.length;i++) {
Log.i("Number: ", numbers[i]);
if(numbers[i].equals(Keys.CONSTANT_CAT)) {
if (innerObject.getString(Keys.KEY_VIEWTYPE).equals("exit") || innerObject.getString(Keys.KEY_VIEWTYPE).equals("grid,exit")) {
model.setName(name);
model.setView_type(viewtype);
model.setId(id);
model.setImage(KEY_ICONURL + image);
model.setCat_id(cat_id);
model.setGrid_order_id(grid_order_id);
list.add(model);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
dialog.dismiss();
if (list.size() > 0) {
try {
adapter.notifyDataSetChanged();
dataPath = objectToFile(list);
editor.putString("key_name5",dataPath); // Saving string
// Save the changes in SharedPreferences
editor.commit(); // commit changes
// pref.getString("key_name5", null);
// list = (ArrayList<MyDataModel>)objectFromFile(dataPath);
Snackbar.make(findViewById(R.id.parentLayout), pref.getString("key_name5", null), Snackbar.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
If your data is structured and you want to access it in parts, you should better use SQLite.
If you just want to cache this data and you will use it completely in future better use SharedPref as you won't create schema for it hence SQLite will be a waste of resource and time both.
Hi You can create a class with any name for example I have created "LocalSharedPrefrences"
public class LocalSharedPrefrences {
private static final String strSharedPrefName = "AppPrefrence";
private static final String homePageJosn = "homePageJosn";
public static void saveHomePageJosnData(Context context, String JsonData) {
SharedPreferences pref = context.getSharedPreferences(strSharedPrefName, context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(homePageJosn, JsonData);
editor.commit();
}
public static String getHomePageJosnData(Context context) {
SharedPreferences pref = context.getSharedPreferences(strSharedPrefName, context.MODE_PRIVATE);
String JsonData = pref.getString(homePageJosn, "");
return JsonData;
}
}
And then you can use these functions to save and get json data as below:
LocalSharedPrefrences.saveHomePageJosnData(Context,JsonDataToSave);
String getJsonData = LocalSharedPrefrences.getHomePageJosnData(Context)
Yes, You can save your json data and and you can use it in offline by using SharedPreferences in android.
First you need to java class i.e. pojo class using Json, Convert that json into above class object.
To save that json -->
private SharedPreferences preferences;
preferences = context.getSharedPreferences("Name", Context.MODE_PRIVATE);
editor = preferences.edit();
editor.putString("your Key String", gson.toJson(here will be your json class object));
editor.commit();
To retrieve That Json-->
gson.fromJson(preferences.getString("your same Key String", null), your json class.class);
In this you will get object of that pojo class i.e. converted json class object.
After the login I get this response from the webserver..
{"success":" Bem vindo lu#lu.com"}{"nomeusuario":"Lu Zimermann"}{"enderecousuario":"Rua Pedro Alves 270. Centro. Casa."}{"telefoneusuario":"(42) 3623-8052"}
Ok. Now My android code.
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
request = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if(jsonObject.names().get(0).equals("success")){
Toast.makeText(getApplicationContext(),jsonObject.getString("success"),Toast.LENGTH_SHORT).show();
//startActivity(new Intent(getApplicationContext(),Restaurantes.class));
}else {
Toast.makeText(getApplicationContext(), jsonObject.getString("error"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
This code Toast the following message. "Bem vindo lu#lu.com"
What I want is:
How can I get the other infos and pass it to a String.
Email = "lu#lu.com"
Endereco = "Rua Pedro..."
Name = "Lu Zimermann"
Soo I can use it later on the app.
Thanks.
Now the response is the right way you can do this to save data..
first wirte a custion class for Preferennce
SharedPreferenceCustom
public class SharedPreferenceCustom {
private Context mContext;
private String defValue = "";
public SharedPreferenceCustom(Context context) {
this.mContext = context;
}
public void setSharedPref(String inputKey, Object inputValue) {
final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(inputKey, String.valueOf(inputValue));
editor.apply();
}
public String getSharedPref(String inputKey) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
return sharedPreferences.getString(inputKey, defValue);
}
}
Now for saving the data, in the activity
try {
JSONObject response = new JSONObject(new String(response_from_server))
SharedPreferenceCustom sp = new SharedPreferenceCustom(Activity.this);
sp.setSharedPref("key_1", response.getString("nomeusuario")); // use key as per needed
sp.setSharedPref("key_2", response.getString("enderecousuario"));
sp.setSharedPref("key_3", response.getString("telefoneusuario"));
sp.setSharedPref("key_4", response.getString("success"));
} catch (JSONException e) {
e.printStackTrace();
}
And for getting the data call sp.getSharedPref("key"); pass the key for getting the corresponding data
EDIT: you can also write individual function in SharedPreferenceCustion to store different data type, or you can use just this, But it might create some conflicts for certain data types,
Hope this helps :) :)
To get access to the other keys, you can use the get(key) on the jsonObject object. Here are the code changes you need to make:
try {
JSONObject jsonObject = new JSONObject(response);
if(jsonObject.names().get(0).equals("success")){
Toast.makeText(getApplicationContext(),jsonObject.getString("success"),Toast.LENGTH_SHORT).show();
{"success":" Bem vindo lu#lu.com"}{"nomeusuario":"Lu Zimermann"}{"enderecousuario":"Rua Pedro Alves 270. Centro. Casa."}{"telefoneusuario":"(42) 3623-8052"}
//here I am just getting the other properties/keys
String nomeusuario = jsonObject.getString("nomeusuario");
String enderecousuario = jsonObject.getString("enderecousuario");
String telefoneusuario = jsonObject.getString("telefoneusuario");
//here you could do whatever you like - I am just making a Toast as an example:
Toast.makeText(getApplicationContext(), nomeusuario+ ", "+enderecousuario+ ", "+telefoneusuario ,Toast.LENGTH_LONG).show();
}else {
Toast.makeText(getApplicationContext(), jsonObject.getString("error"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
I hope this helps you - give it a try and let me know.
By the way, I am assuming the JSON that you are getting is proper.
There are several ways you can do that.
First of all you need to store them into variable/s.
You can choose to keep it as JSON var, as HashMap or each variable separate as String.
The second action is to access it from any place. This depends on how long to you want the information alive.
If you want them live for just as long as the app is live then the I suggest to create a Global Java class with set/get of your variable.
You could also store it in SharedPreferences or sqlite database for permanent.
Try following
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
request = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
if(jsonObject.names().get(0).equals("success")){
//Toast.makeText(getApplicationContext(),jsonObject.getString("success"),Toast.LENGTH_SHORT).show();
JSONObject jsonObject = new JSONObject(response);
Iterator<String> keys = jsonObject.keys();
String values = "";
while(keys.hasNext()){
String keyName = keys.next();
values = jsonObject.getString(keyName) + "\n";
}
Toast.makeText(getApplicationContext(),values,Toast.LENGTH_SHORT).show();
//startActivity(new Intent(getApplicationContext(),Restaurantes.class));
}else {
Toast.makeText(getApplicationContext(), jsonObject.getString("error"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
I'm quite new to android, and I am having a problem with save and load data.
I am trying to make an app with a save and a load button, these buttons should save 2 ArrayLists with x- and y-coordinates.
I've tried doing it with SharedPreferences and it works until the apps restarts or the screen rotates.
When i take look in the app files the ArrayLists files are in the SharedPreferences folder, but my app will not load those if I press the load button.
Could anyone help we why this does not work when the app is restarted?
this is my load and save code:
public void saveArrayList(ArrayList aList, String s) {
SharedPreferences sharedPrefs = getSharedPreferences(prefs, MODE_PRIVATE);
editor = sharedPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(aList);
editor.putString(s, json);
editor.commit();
}
public void loadFloatList(ArrayList aList, String s) {
SharedPreferences sharedPrefs = getSharedPreferences(prefs, MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPrefs.getString(s, null);
Type type = new TypeToken<ArrayList<Float>>() {
}.getType();
aList = gson.fromJson(json, type);
}
Possible error; you are re-initializing gson and sharedPrefs which then takes a new state with the same key value. you should do this in onCreate.
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPrefs = getSharedPreferences(PREFS, MODE_PRIVATE);
json = sharedPrefs.getString(JSON_KEY, "");
gson = new Gson();
}
it is best to use apply() because this save the value(s) of your sharedprefs as instance but commit() do this when the app closes.
public void saveArrayList(ArrayList aList) {
String json = gson.toJson(aList);
editor = sharedPrefs.edit();
editor.putString(JSON_KEY, json);
editor.apply();
}
public void loadFloatList(ArrayList aList, String s) {
json = sharedPrefs.getString(JSON_KEY, "");
Type type = new TypeToken<ArrayList<Float>>() {
}.getType();
aList = gson.fromJson(json, type);
}
note also the PREFS and JSON_KEY are final key values
private final String PREFS = "prefs";
private final String JSON_KEY = "json";
private SharedPreferences sharedPrefs;
private SharedPreferences.Editor editor;
private String json;
private Gson gson;