Android storing data locally for offline access - android

In my project, there is a scenario where i am getting Json data as response when the device is in online. I need the same data when the device is offline.
I have tried saving the data into Default SharedPreference file using
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("contactobject", result.toString()).apply();
And retrieving the data from SharedPreference file like using
String result = PreferenceManager.getDefaultSharedPreferences(context).getString("contactobject", "");
The thing is, by using SharedPreference, the usage of memory is high.
Question : Is there any other better way to save the data in Cache memory as like WebView for better performance.

Just write the JSON to your cache dir. Read it from your cache file if you're offline and update your cache when you're online. You don't need a database for simple JSON. Seriously.

The Sharedpreferences use key values.That might be create a problem some time. So store the data in database and retrieve it when user is offline.
UPDATE
you can use database for retrieving records like this
aQuery.progress(progressDialog).ajax(url, JSONObject.class, new AjaxCallback<JSONObject>() {
#Override
public void callback(String url, JSONObject object, AjaxStatus status) {
if (object != null) {
//delete old records
db.execSQL("delete from entrys");
String quotos = object.optString("quote_data");
String msg = object.optString("msg");
// Toast.makeText(getApplicationContext(),msg+" and "+quotos,Toast.LENGTH_LONG).show();
try {
JSONArray jsonArray = new JSONArray(quotos);
al = new ArrayList<String>();
for (int i = 0; i < jsonArray.length(); i++) {
jsonObject = jsonArray.getJSONObject(i);
String str = jsonObject.getString("quote");
al.add(str);
//add the data in database
ContentValues cv = new ContentValues();
cv.put("name",str);
db.insert("entrys",null,cv);
Log.d("STR,","Created"+str);
}
ArrayAdapter<String> adpt = new ArrayAdapter<String>(Wishes.this, R.layout.single_row, R.id.tv_wishdata, al);
lv.setAdapter(adpt);
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Server is busy Reciving data..", Toast.LENGTH_LONG).show();
}
} else {
//show the data when user is offline
SimpleCursorAdapter sd = new SimpleCursorAdapter(getApplicationContext(), R.layout.single_row,c, new String[]{"name"}, new int[]{R.id.tv_wishdata});
lv.setAdapter(sd);
Toast.makeText(getApplicationContext(), "Please Check Internet connection", Toast.LENGTH_LONG).show();
}
}
});
Option 2 You can also use cache files for retrieve data.
First of all create a function for save data in cachefile.
public void saveMyData()
{
try {
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(getFilesDir(),"")+"cachefile.txt"));
out.writeObject(al.toString());
Toast.makeText(getApplicationContext(), "Data Saved..",Toast.LENGTH_LONG).show();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Then after retrieve data whenever you what to show data from file.
private String retriveMyData()
{
String fileContent = "";
try {
String currentLine;
BufferedReader bufferedReader;
FileInputStream fileInputStream = new FileInputStream(getFilesDir()+"cachefile.txt");
bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream,"UTF-8"));
while ((currentLine = bufferedReader.readLine()) != null) {
fileContent += currentLine + '\n';
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
Log.d("FAILED","THOS IS NULL");
fileContent = null;
}
Log.d("SUCESS","SUCESS BUDDYY"+fileContent);
Toast.makeText(getApplicationContext(),fileContent+"",Toast.LENGTH_SHORT).show();
return fileContent;
}

Related

Store & retrieve a list of HashMap/Map objects to Local Storage

I am really new to coding and mobile development. I am writting a mobile app for to do list
For each to-do-item, I stored it as a Map, and put them into an Arraylist myItems.
Now I want to save/retrieve myItems, to a local storage, so every time I reopen the file the previous data are still retained. Someone told me can save to a JSON file,
How can I achieve that? Thanks in advance.
Below are methods for my MainActivity FYI.
public class MainActivity extends AppCompatActivity {
//define variables
ListView listview;
ArrayList<Map<String,Object>> myItems=new ArrayList<Map<String,Object>>();
SimpleAdapter adapter;
EditText addItemEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//use "activity_main.xml" as the layout
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
//Create an adapter for the list view using Android's built-in item layout
adapter = new SimpleAdapter(this,myItems,android.R.layout.simple_list_item_2,
new String[]{"Name","Time"},new int[]{android.R.id.text1,android.R.id.text2});
//connect the listview and the adapter
listview.setAdapter(adapter);
//Below two examples of how the item look like
Map<String,Object> item1 = new HashMap<String,Object>();
item1.put("Name","Item1");
item1.put("Time","Time1");
myItems.add(item1);
Map<String,Object> item2 = new HashMap<String,Object>();
item2.put("Name","Item2");
item2.put("Time",null);
myItems.add(item2);
//set up a list view listener
setupListViewListener();
}
public void CreatNewActivity(View view) {
...
}
...
First, you need to serialize your ArrayList to JSON. You could do that using the GSON library.
ArrayList<String> yourArrayList = new ArrayList<String>();
String jsonStr = new Gson().toJson(yourArrayList);
Now that you have a JSON string, you can save it to internal storage:
FileOutputStream outputStream;
String fileName = "jsonStorage.txt";
try {
outputStream = openFileOutput(fileName , Context.MODE_PRIVATE);
outputStream.write(jsonStr.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
In order to read the JSON and deserialize it, here are the steps:
Read the file:
InputStream inputStream = context.openFileInput(fileName);
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String jsonString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (stringBuilder = bufferedReader.readLine()) != null ) {
stringBuilder.append(stringBuilder );
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (Exception e) {
Log.e(TAG, "File read error: " + e.toString());
}
For deserializing the JSON string to an ArrayList, you can use several libraries, such as the org JSON library or GSON. Then parsing the string becomes easy:
JSONObject jsonObj = new JSONObject(stringBuilder.toString());

Update Chat Every second

I am making an chat application while implementing it i need to update the messages automatically for this i am using asyntacks. For this i am having doubt that every time we cant able to refresh through asyntaks option. So, is there any way or any other method to refresh the chat activity for every second.
Chat.java
public class chatclass extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String receiverid = getIntent().getStringExtra("Rid");
try {
URL url = new URL("" + Constant.cht);
Map<String, Object> paramm = new LinkedHashMap<>();
paramm.put("sid", "" + Session.getUserID(getApplicationContext()));
paramm.put("rid", "" + receiverid);
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : paramm.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
String urlParameters = postData.toString();
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String result = "";
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
result += line;
}
writer.close();
reader.close();
JSONObject response = new JSONObject(result);
JSONArray array = response.getJSONArray("data");
chatslistdata.clear();
for (int i = 0; i < array.length(); i++) {
JSONObject chatobj = array.getJSONObject(i);
ChatBeanData chatBeanData = new ChatBeanData();
chatBeanData.setChat_id(chatobj.getString("chat_id"));
chatBeanData.setRid(chatobj.getString("rid"));
chatBeanData.setReciever_name(chatobj.getString("reciever_name"));
chatBeanData.setReciever_image(chatobj.getString("reciever_image"));
chatBeanData.setSid(chatobj.getString("sid"));
chatBeanData.setSender_name(chatobj.getString("sender_name"));
chatBeanData.setSender_image(chatobj.getString("sender_image"));
chatBeanData.setMessage(chatobj.getString("message"));
chatBeanData.setSeen_status(chatobj.getInt("seen_status"));
chatBeanData.setTime(chatobj.getString("time"));
chatslistdata.add(chatBeanData);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
chatadapter = new ChatAdapter(ChatsPage.this, chatslistdata);
LinearLayoutManager mychatmanager = new LinearLayoutManager(ChatsPage.this, LinearLayoutManager.VERTICAL, false);
mychatmanager.setStackFromEnd(true);
chatlist.setLayoutManager(mychatmanager);
chatlist.setAdapter(chatadapter);
chatclass chatclass = new chatclass();
chatclass.execute();
}
}
It's really bad idea to refresh your chat every seconds because you lose a lot of server efficiency. You should do It like this:
Download all messages from server,
Download all messages with greater ID than last one message has (for example with long-polling or polling),
If there is any message, update list.
Or use Soket.io for example, or weboskect.
Then:
Create connection with server,
Download all messages,
Then server should send information if you will have new message,
If you receive this information, download messages with greater ID than last one message has.
I thing, it is good idea for chat. Here you have demo of chat on socket.io
Have fun
It is not really good approach to refresh your chat every second to retrieve messages.
This might overload your server with excessive requests which can be avoided.
To achieve real-time chat your server should send information if you have received any new messages.
On client-side you need to set a listener for that purpose. Once the listener is triggered, you can download the new messages.
Check ConnectyCube Android implementation as an example:
IncomingMessagesManager incomingMessagesManager = chatService.getIncomingMessagesManager();
incomingMessagesManager.addDialogMessageListener(new ChatDialogMessageListener() {
#Override
public void processMessage(String dialogId, ConnectycubeChatMessage message, Integer senderId) {
}
#Override
public void processError(String dialogId, ChatException exception, ConnectycubeChatMessage message, Integer senderId) {
}
});

Android JsonArray into ListView

Im trying to parse json array data into listview!I searched the whole internet and always was on one point! Json aray must have header something like this
"emp_info":[{"employee name":"Adam","employee no":"101700"},{"employee name":"John","employee no":"101701"},{"employee name":"Paul","employee no":"101702"},{"employee name":"Mark","employee no":"101703"},{"employee name":"Donald","employee no":"101704"},{"employee name":"Brain","employee no":"101705"},{"employee name":"Kevin","employee no":"101706"}]}
Where by my understanding the "emp_info" is the header file by which i must search for rest data inside it in android!My College pretending that i can accept and parse the same data into listview without that header name,but every bit of code where i searched to parse json in android was a single line like this!
JSONObject obj = new JSONObject(jsonString);
JSONArray stations = obj.getJSONArray("emp_inf");
where i just have to put the jsonarray header file as you can see in this piece of code!So please help me is that possible to accept json array without this code?because if i try to remove this code i get nullpointer in my code!Will be very happy if you could at least say yes or no!
Posting Full Codes!
Here is the android class which gets the Json and loads it into List View
private class JsonReadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://54.148.41.171/server/index/dompy");
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(
response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
// e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error..." + e.toString(), Toast.LENGTH_LONG).show();
}
return answer;
}
#Override
protected void onPostExecute(String result) {
ListDrwaer();
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
// passes values for the urls string array
task.execute(new String[] { url });
}
// build hash set for list view
public void ListDrwaer() {
List<Map<String, String>> employeeList = new ArrayList<Map<String, String>>();
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("emp_info");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("empployee no");
String number = jsonChildNode.optString("etc.");
String outPut = name + "-" + number;
employeeList.add(createEmployee("data", outPut));
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error" + e.toString(),
Toast.LENGTH_SHORT).show();
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, employeeList,
android.R.layout.simple_list_item_1,
new String[] { "employee no" }, new int[] { android.R.id.text1 });
listView.setAdapter(simpleAdapter);
}
private HashMap<String, String> createEmployee(String name, String number) {
HashMap<String, String> employeeNameNo = new HashMap<String, String>();
employeeNameNo.put(name, number);
return employeeNameNo;
}
}
And by this json array im successfully able to fetch the json which type is the next!
{"emp_info":[{"employee name":"Adam","employee no":"101700"},{"employee name":"John","employee no":"101701"},{"employee name":"Paul","employee no":"101702"},{"employee name":"Mark","employee no":"101703"},{"employee name":"Donald","employee no":"101704"},{"employee name":"Brain","employee no":"101705"},{"employee name":"Kevin","employee no":"101706"}]}
And here is the json array which my college pretends that i must accept!
{"data":"123"}
And im Saying that its not possible to load this json into list view just because it dont have header file like mine the emp_info,but hes saying its not matter i just MUST accept!We just on same project and i just cant understand is it even possible to do what he says?
String name = jsonChildNode.optString("empployee no");
String number = jsonChildNode.optString("etc.");
How can you get the data by "etc." tag I could not understand it firstly. It should return "" instead of employee number.

How to create JSON array from JSON data file?

Am new to android. Am creating an android project which parses the JSON data and displays it in a ListView. Am using Eclipse to create the project. I have created a file called userinput.json in the raw folder which is subfolder of res. I have given these JSON data inside the file.
[
{"name":"Company A", "hometown":"NJ"},
{"name":"Company B", "hometown":"PA"},
{"name":"Company C", "hometown":"CT"},
{"name":"Company D", "hometown":"NY"},
{"name":"Company E", "hometown":"NJ"}
]
My requirement is to convert this JSON data declared in the Raw resources into JSON array.
Since I have declared the json data in a file, I have to access it from the resources and hence I use BufferedReader to read the file.
But while trying to convert the StringBuilder object to JSON array, I am returned with null.
This is the code I have written:
BufferedReader jsonReader = new BufferedReader(new InputStreamReader(
this.getResources().openRawResource(R.raw.userinput)));
StringBuilder jsonBuilder = new StringBuilder();
try {
for (String line = null; (line = jsonReader.readLine()) != null;)
{
jsonBuilder.append(line).append("\n");
}
jTokener = new JSONTokener(jsonBuilder.toString());
jsonArray = new JSONArray(jTokener.toString());
}
catch (Exception e)
{
throw new RuntimeException(e);
}
ArrayList<User> newArrayOfUsers = User.JsonData(jsonArray);
In a seperate Java file I have the below two methods to convert my JSON Array into Java Objects:
public User(JSONObject object)
{
try
{
this.name = object.getString(name);
this.hometown = object.getString(hometown);
}
catch(JSONException e)
{
e.printStackTrace();
}
}
public static ArrayList<User> JsonData(JSONArray jsonArray)
{
ArrayList<User> users = new ArrayList<User>();
for(int i = 0; i < jsonArray.length(); i++)
{
try
{
users.add(new User(jsonArray.getJSONObject(i)));
}
catch(JSONException e)
{
e.printStackTrace();
}
}
return users;
}
I am not sure, whether am doing this in correct way, Can anyone please guide me how to get JSON array from the StringBuilder?
this works...
BufferedReader jsonReader = new BufferedReader(new InputStreamReader(
this.getResources().openRawResource(R.raw.userinput)));
StringBuilder jsonBuilder = new StringBuilder();
try {
for (String line = null; (line = jsonReader.readLine()) != null;) {
jsonBuilder.append(line).append("\n");
}
Toast.makeText(this, jsonBuilder.toString(), 1).show();
//JSONTokener jTokener = new JSONTokener(jsonBuilder.toString());
JSONArray jsonArray = new JSONArray(jsonBuilder.toString());
for(int i=0;i<jsonArray.length();i++)
{
JSONObject tmpjsonobject=jsonArray.getJSONObject(i);
Toast.makeText(this, tmpjsonobject.getString("name")+"\n"+tmpjsonobject.getString("hometown"), 1).show();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
and #Salvin is right ...there is no need for JsonTokener .....
You can Java's Scanner class on Android to parse a raw data file and create a JSONArray. Assuming you have a file called my_raw_json.json in your res/raw dir:
Scanner scanner = new Scanner(context.getResources().openRawResource(R.raw.my_raw_json));
String json = scanner.useDelimiter(REGEX_INPUT_BOUNDARY_BEGINNING).next();
JSONArray array = new JSONArray(json);

how to maintain array list for new added element?

Hello every one i am working on app which is similar to the facebook.In that currently i am stuck in one point like we have posts in facebook which shows on our wall in that all the post is shows in bulk like 20 20 fashion that same thing i want to apply in my app. For that thing i use listview which get value form server and create view according to that i also get all value but the problem is that when i add 1st 20 value then it work fine but when i add another 20 value it will delete the previous data in listview.
any idea how i can do this thing in my app and thanks in advance....
my function get value from the server
private void getPostnew(String start) {
String URL = start;
System.out.println("start value new :" + start);
final String usernamefor = "";
aq = new AQuery(getParent());
listitem = new ArrayList<BeanTop>();
aq.ajax(URL, JSONObject.class, 10 * 1000,
new AjaxCallback<JSONObject>() {
#Override
public void callback(String url, JSONObject json1,
AjaxStatus status) {
System.out.println("json " + json1);
if (json1 == null) {
} else {
try {
JSONArray jarray = json1
.getJSONArray("subject");
for (int j = 0; j < jarray.length(); j++) {
try {
JSONObject j1 = jarray.getJSONObject(j);
try {
listcount = j1
.getString("likecount");
} catch (Exception e) {
listcount = "0";
}
AddObject(j1.getString("text"),
j1.getString("leftpic"),
j1.getString("rightpic"),
j1.getString("rightvotecount"),
j1.getString("leftvotecount"),
j1.getString("textleft"),
j1.getString("textright"),
j1.getString("date_created"),
j1.getString("voteid"),
j1.getString("user"),
j1.getString("dom"),
j1.getString("Isvoted"),
j1.getString("Islike"),
j1.getString("profilepic"),
listcount,
j1.getString("commentcount"));
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
FriendlistAdapter ad = new FriendlistAdapter(Top.this,
listitem);
subjectlist.setAdapter(ad);
ad.notifyDataSetChanged();
}
});
}
method for save the data in bean class
private void AddObject(String string1, String string2, String string3,
String string5, String string6, String string7, String string8,
String string9, String string10, String string11,
String usernamefor, String isvoted, String isliked,
String profilepic, String likecount, String commentcount) {
BeanTop ib = new BeanTop();
Date date = null;
try {
System.out.println("date " + string9);
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(string9);
} catch (Exception e) {
e.printStackTrace();
}
ib.setText(string1);
ib.setLeftpic(string2);
ib.setRightpic(string3);
ib.setRightVote(string5);
ib.setLeftVote(string6);
ib.setLefttext(string7);
ib.setRighttext(string8);
ib.setDate(string9);
ib.setDate1(date);
ib.setVoteid(string10);
ib.setUsername(string11);
ib.setDom(usernamefor);
ib.setIsvoted(isvoted);
ib.setIsliked(isliked);
ib.setProfilepic(profilepic);
ib.setLikecount(likecount);
ib.setCommentcount(commentcount);
List<BeanTop> bookingList = new ArrayList<BeanTop>();
bookingList.addAll(listitem);
Collections.sort(bookingList, new Comparator<BeanTop>() {
public int compare(BeanTop m1, BeanTop m2) {
return m1.getDate().compareTo(m2.getDate());
}
});
Collections.reverse(bookingList);
try {
listitem.clear();
} catch (Exception e) {
e.printStackTrace();
}
listitem.addAll(bookingList);
try {
bookingList.clear();
} catch (Exception e) {
e.printStackTrace();
}
listitem.add(ib);
}
Cant say without seeing your code, but I can show you general way of doing this...
First you should maintain a list, say at class level like...
List<MyPost> posts = ArrayList<MyPost>();
Then you can create you adapter by passing 'posts' list in it.
And just call '.addAll(xxx)' to you 'posts' list everytime you get items from server like,
posts.addAll(newItems);
and right after that, call yourAdapter.notifyDatasetChanged(); so that list can redraw/update its views...
And in you code...use,
if (listitem == null) {
listitem = new ArrayList<BeanTop>();
}
in you getPostnew() instead of only listitem = new ArrayList<BeanTop>();.
Hope this helps...
You are re-initializing listitem = new ArrayList<BeanTop>(); eveytime the getPostnew methood is called. This is why your old posts are lost. Try change that line to:
if (listitem == null) {
listitem = new ArrayList<BeanTop>();
}
you should use a global variable to store the data which you get from server ,in your method
getPostnew(String start) every time you execute it ,the listitem will be recreated;so the last data will be lost.

Categories

Resources