How to Cache Json data to be available offline? - java

I have parsed the JSON Data in a listview and now I want to make it available offline.
Is there a way to save the JSON data at the phone so that you can see the data if your phone is offline?
Does someone knows an example?
EDIT works now:
public class MainActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new TheTask().execute();
}
class TheTask extends AsyncTask<Void, Void, JSONArray> {
InputStream is = null;
String result = "";
JSONArray jArray = null;
ProgressDialog pd;
#Override
protected void onPostExecute(JSONArray result) {
super.onPostExecute(result);
pd.dismiss();
ArrayList<String> list= new ArrayList<String>();
try {
for(int i=0;i<result.length();i++) {
JSONObject jb = result.getJSONObject(i) ;
String name = jb.getString("name")+" "+jb.getString("Art");
list.add(name);
}
} catch(Exception e) {
e.printStackTrace();
}
setListAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, list));
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = ProgressDialog.show(MainActivity.this, "State",
"Loading...", true);
}
#Override
protected JSONArray doInBackground(Void... arg0) {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("***");
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// Convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
writeToFile(result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
try {
jArray = new JSONArray(result);
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
try {
jArray = new JSONArray(readFromFile());
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
return jArray;
}
}
private void writeToFile(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
private String readFromFile() {
String ret = "";
try {
InputStream inputStream = openFileInput("config.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
inputStream.close();
ret = stringBuilder.toString();
}
} catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
}

You have two ways. Either you create a database and save all of the data there and retrieve it back when you want to. Or if the data you have is not that much and you don't want to deal with databases, then you write the json string to a text file in the memory card and read it later when you are offline.
And for the second case, every time you go online, you can retrieve the same json from your web service and over write it to the old one. This way you can be sure that you have the latest json saved to the device.

this class will help you cache strings in files with a key to retrieve later on. the string can be a json string and key can be the url you requested and also an identifier for the url if you are using post method.
public class CacheHelper {
static int cacheLifeHour = 7 * 24;
public static String getCacheDirectory(Context context){
return context.getCacheDir().getPath();
}
public static void save(Context context, String key, String value) {
try {
key = URLEncoder.encode(key, "UTF-8");
File cache = new File(getCacheDirectory(context) + "/" + key + ".srl");
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(cache));
out.writeUTF(value);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void save(Context context, String key, String value, String identifier) {
save(context, key + identifier, value);
}
public static String retrieve(Context context, String key, String identifier) {
return retrieve(context, key + identifier);
}
public static String retrieve(Context context, String key) {
try {
key = URLEncoder.encode(key, "UTF-8");
File cache = new File(getCacheDirectory(context) + "/" + key + ".srl");
if (cache.exists()) {
Date lastModDate = new Date(cache.lastModified());
Date now = new Date();
long diffInMillisec = now.getTime() - lastModDate.getTime();
long diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffInMillisec);
diffInSec /= 60;
diffInSec /= 60;
long hours = diffInSec % 24;
if (hours > cacheLifeHour) {
cache.delete();
return "";
}
ObjectInputStream in = new ObjectInputStream(new FileInputStream(cache));
String value = in.readUTF();
in.close();
return value;
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
how to use it :
String string = "cache me!";
String key = "cache1";
CacheHelper.save(context, key, string);
String getCache = CacheHelper.retrieve(context, key); // will return 'cache me!'

Once you download the data you could persist the data on the mobile, using a database or a system of your preference.
You can check the different options here: data-storage

using SharedPreferences should be prepared to sqlite (unless of course you have a database structure). For caching and storing data pulled from the internet, I recommend robospice: https://github.com/octo-online/robospice. It's a very well done library, easy to use, and should be used any time you download data from the internet or have a long-running task.

You can use those two methods two store you JSON file as a string in your SharedPreferences and retrieve it back:
public String getStringProperty(String key) {
sharedPreferences = context.getSharedPreferences("preferences", Activity.MODE_PRIVATE);
String res = null;
if (sharedPreferences != null) {
res = sharedPreferences.getString(key, null);
}
return res;
}
public void setStringProperty(String key, String value) {
sharedPreferences = context.getSharedPreferences("preferences", Activity.MODE_PRIVATE);
if (sharedPreferences != null) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
CupsLog.i(TAG, "Set " + key + " property = " + value);
}
}
Just use setStringProperty("json", "yourJsonString") to save and getStringProperty("json") to retrieve.

How to Cache Json data to be available offline?
You can use gson to parse JSON data more easily.
In your build.gradle file add this dependency.
compile 'com.google.code.gson:gson:2.8.0'
Then create a POJO class to parse JSON data.
Example POJO class:
public class AppGeneralSettings {
#SerializedName("key1")
String data;
public String getData() {
return data;
}
}
To parse a json string from internet use this snippet
AppGeneralSettings data=new Gson().fromJson(jsonString, AppGeneralSettings.class);
Then add a helper class to store and retrieve JSON data to and from preferences.
Example: Helper class to store data
public class AppPreference {
private static final String FILE_NAME = BuildConfig.APPLICATION_ID + ".apppreference";
private static final String APP_GENERAL_SETTINGS = "app_general_settings";
private final SharedPreferences preferences;
public AppPreference(Context context) {
preferences = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
}
public SharedPreferences.Editor setGeneralSettings(AppGeneralSettings appGeneralSettings) {
return preferences.edit().putString(APP_GENERAL_SETTINGS, new Gson().toJson(appGeneralSettings));
}
public AppGeneralSettings getGeneralSettings() {
return new Gson().fromJson(preferences.getString(APP_GENERAL_SETTINGS, "{}"), AppGeneralSettings.class);
}
}
To save data
new AppPreference().setGeneralSettings(appGeneralSettings).commit();
To retrieve data
AppGeneralSettings appGeneralSettings = new AppPreference().getGeneralSettings();

You can cache your Retrofit responses, so when you make the same request second time, Retrofit will take it from it's cache:
https://medium.com/#coreflodev/understand-offline-first-and-offline-last-in-android-71191e92b426, https://futurestud.io/tutorials/retrofit-2-activate-response-caching-etag-last-modified. After that you'l need to parse that json again

Related

How implements the Google Distance/Matrix Api at Android Studio?

I'm programming an app that calculates, in route, two locations. I've implemented the google places API to get the lat/lon based on name or address but I can't implement the Distance API. The classes/methods don't appear when I try to import. Below is an example of what I'm trying to do.
private static final String API_KEY = "YOUR_API_KEY";
private static final GeoApiContext context = new
GeoApiContext().setApiKey(API_KEY);
public DistanceMatrix estimateRouteTime(DateTime time, Boolean isForCalculateArrivalTime, DirectionsApi.RouteRestriction routeRestriction, LatLng departure, LatLng... arrivals) {
try {
DistanceMatrixApiRequest req = DistanceMatrixApi.newRequest(context);
if (isForCalculateArrivalTime) {
req.departureTime(time);
} else {
req.arrivalTime(time);
}
if (routeRestriction == null) {
routeRestriction = DirectionsApi.RouteRestriction.TOLLS;
}
DistanceMatrix trix = req.origins(departure)
.destinations(arrivals)
.mode(TravelMode.DRIVING)
.avoid(routeRestriction)
.language("fr-FR")
.await();
return trix;
} catch (ApiException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
The GeoApiContext and DistanceMatrix don't appear at import.
Tks for help.
Answering my question...
public class GetJson extends AsyncTask<Void, Void, DeliveryData> {
#Override
protected void onPreExecute() {
// progressDialog
}
#Override
protected DeliveryData doInBackground(Void... params) {
Utils util = new Utils();
DeliveryData json = util.getInfo("https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins="+latLngCompany.latitude+","+latLngCompany.longitude+
"&destinations="+latPlace+","+lonPlace+"&key=" + APISERVERKEY);
deliveryData.saveDeliveryData();
return json;
}
#Override
protected void onPostExecute(DeliveryData deliveryData) {
//progressDialog.dismiss
}
}
Created a AsyncTask to get json from url with the especifics parameters.
public class Utils {
public DeliveryData getInfo(String end){
String json;
DeliveryData output;
json = NetworkUtils.getJSONFromAPI(end);
output = parseJson(json);
return output;
}
private DeliveryData parseJson(String json){
try {
DeliveryData deliveryData = new DeliveryData();
JSONObject distanceJson = new JSONObject(json)
.getJSONArray("rows")
.getJSONObject(0)
.getJSONArray("elements")
.getJSONObject(0)
.getJSONObject("distance");
Double distanceDouble = null ;
String distance = distanceJson.get("text").toString();
if (distance.contains("km")){
distanceDouble = Double.parseDouble(distance.replace("km", ""));
}else {
distanceDouble = Double.parseDouble("0." + distance.replace("m", ""));
}
deliveryData.setDistance(distanceDouble);
return deliveryData;
}catch (JSONException e){
e.printStackTrace();
return null;
}
}
}
At getInfo, the data from url is passed to string. Then, parseJson is call to transform the string to JsonObject.
My Json there is only one position. So, the object is selected at array and the String is parse to Double, excluding the chars. In the end, the distance is saved at object.
public class NetworkUtils {
public static String getJSONFromAPI (String url){
String output = "";
try {
URL apiEnd = new URL(url);
int responseCode;
HttpURLConnection connection;
InputStream is;
connection = (HttpURLConnection) apiEnd.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(15000);
connection.setConnectTimeout(15000);
connection.connect();
responseCode = connection.getResponseCode();
if(responseCode < HttpURLConnection.HTTP_BAD_REQUEST){
is = connection.getInputStream();
}else {
is = connection.getErrorStream();
}
output = convertISToString(is);
is.close();
connection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return output;
}
private static String convertISToString(InputStream is){
StringBuffer buffer = new StringBuffer();
try {
BufferedReader br;
String row;
br = new BufferedReader(new InputStreamReader(is));
while ((row = br.readLine())!= null){
buffer.append(row);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
}
This class is resposible for connecting to server and get the data from url.

Parsin JSON information - Android studio

i am currently trying to parse a simple JSON information but can't figure out the JSON object and array part... I'm trying to extract from this JSON(below) the app_time and postcode + address. Can anyone give me a solution about my "extractFeatureFromJson()", sorry about the formatting it's my first post here.
{
"data": [
{
"id": 24256,
"app_time": 1904280242,
"addresses": [
{
"id": 1,
"postcode": "9000",
"address": "Street:Street, City: City, Country: Country"
}
],
"comments": [
{
"id": 1,
"comment": "Comment",
"created_at": 234234234
}
]
}
]
}
public static final String LOG_TAG = MainActivity.class.getSimpleName();
private static final String _URL = "https://.......com/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ScheduleAsyncTask task = new ScheduleAsyncTask();
task.execute();
}
private void updateUi(Event job) {
TextView titleTextView = (TextView) findViewById(R.id.time);
titleTextView.setText(getDateString(job.time));
TextView dateTextView = (TextView) findViewById(R.id.address);
dateTextView.setText(job.address);
}
private String getDateString(long timeInMilliseconds) {
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
return formatter.format(timeInMilliseconds);
}
private class ScheduleAsyncTask extends AsyncTask<URL, Void, Event> {
#Override
protected Event doInBackground(URL... urls) {
// Create URL object
URL url = createUrl(_URL);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = "";
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
Event jobs = extractFeatureFromJson(jsonResponse);
return jobs;
}
#Override
protected void onPostExecute(Event job) {
if (job == null) {
return;
}
updateUi(job);
}
/**
* Returns new URL object from the given string URL.
*/
private URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("X-Application", ".....");
urlConnection.connect();
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} catch (IOException e) {
// TODO: Handle the exception
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
private Event extractFeatureFromJson(String scheduleJSON) {
try {
JSONObject baseJsonResponse = new JSONObject(scheduleJSON);
JSONArray featureArray = baseJsonResponse.getJSONArray("comments");
// If there are results in the features array
// Extract out the first feature
JSONObject firstFeature = featureArray.getJSONObject(0);
JSONObject properties = firstFeature.getJSONObject("comment");
// Extract out the time address values
String address = properties.getString("address");
long time = properties.getLong("app_time");
// Create a new {#link Event} object
return new Event(address, time);
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the JSON results", e);
}
return null;
}
}
}
As per your json structure, data is json array and so is addresses and comments, so you have to work your way down to those json arrays and finally json objects.
One way to understand json structure (objects and array is to format it and view it. Use online json formatters like https://jsonformatter.org/ or install plugins in notepad++ to format json.
NOTE: I am not giving you full solution as it is for your own benefit so here is what you should do and add debugger points and system.out.println (Log.d in android) for understanding json object and array you traverse and learn yourself.
JSONObject obj = new JSONObject(str);
JSONObject appTime = obj.getJSONArray("data").getJSONObject(0).getJSONObject(“app_time”);
JSONObject postal_code = obj.getJSONArray("data").getJSONObject(0).getJSONArray(“addresses”).getJSONObject(0).getJSONObject(“postcode”);
You have to add appropriate null checks at each step to avoid NPE.
You can also use JSONObject’s methods to retrieve specific data type (getString, getLong, etc.)
https://developer.android.com/reference/org/json/JSONObject.html
if (scheduleJSON!= null) {
try {
JSONObject jsonObj = new JSONObject(scheduleJSON);
// Getting JSON Array node
JSONArray data= jsonObj.getJSONArray("data");
// looping through All data
for (int i = 0; i < data.length(); i++) {
JSONObject id = data.getJSONObject(id);
JSONObject app_time=data.getJSONObject(app_time);
String id = c.getString("id");
// Getting JSON Array node
JSONArray addresses=new JSONArray(data.getJSONObject(i).getString("addresses"));
JSONArray comments= new JSONArray(data.getJSONObject(i).getString("comments"));
}
}catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}

Need to change String into JSON and return it. The code runs fine except I get the error: java.lang.String cannot be converted to JSONObject

Everything seems to be fine except for the JSON exception error.
Here it is specifically: org.json.JSONException:
Value username of type `java.lang.String` cannot be converted to `JSONObject`.
There are a number of other flags that I can check in logcat and everything seems pretty good except that. I think the problem is that I need to convert the String encodedStr into a JSON object and return it to ASYNC TASK.
private class AsyncDataClass extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//Use HashMap, it works similar to NameValuePair
Map<String, String> dataToSend = new HashMap<>();
dataToSend.put("username", params[1]);
dataToSend.put("password", params[2]);
//Server Communication part - it's relatively long but uses standard methods
//Encoded String - we will have to encode string by our custom method (Very easy)
String encodedStr = getEncodedData(dataToSend);
//Will be used if we want to read some data from server
BufferedReader reader = null;
//Connection Handling
try {
//Converting address String to URL
URL url = new URL(serverUrl);
//Opening the connection (Not setting or using CONNECTION_TIMEOUT)
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//Post Method
con.setRequestMethod("POST");
//To enable inputting values using POST method
//(Basically, after this we can write the dataToSend to the body of POST method)
con.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
//Writing dataToSend to outputstreamwriter
writer.write(encodedStr);
//Sending the data to the server - This much is enough to send data to server
//But to read the response of the server, you will have to implement the procedure below
writer.flush();
//Data Read Procedure - Basically reading the data comming line by line
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = reader.readLine()) != null) { //Read till there is something available
sb.append(line + "\n"); //Reading and saving line by line - not all at once
}
line = sb.toString();//Saving complete data received in string, you can do it differently
//Just check to the values received in Logcat
Log.i("custom_check", "The values received in the store part are as follows:");
Log.i("custom_check", line);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Same return null, but if you want to return the read string (stored in line)
//then change the parameters of AsyncTask and return that type, by converting
//the string - to say JSON or user in your case
**strong text**return encodedStr;**strong text**
**strong text**HERE IS THE PROBLEM I BELIEVE.
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
System.out.println("Resulted Value: " + result);
if (result.equals("") || result == null) {
Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_LONG).show();
return;
}
int jsonResult = returnParsedJsonObject(result);
if (jsonResult == 0) {
Toast.makeText(MainActivity.this, "Invalid username or password", Toast.LENGTH_LONG).show();
return;
}
if (jsonResult == 1) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("USERNAME", enteredUsername);
intent.putExtra("MESSAGE", "You have been successfully login");
startActivity(intent);
}
}
private int returnParsedJsonObject(String result) {
JSONObject resultObject = null;
int returnedResult = 0;
try {
resultObject = new JSONObject(result);
returnedResult = resultObject.getInt("success");
} catch (JSONException e) {
e.printStackTrace();
}
return returnedResult;
}
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = br.readLine()) != null) {
answer.append(rLine);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return answer;
}
//************getEncodedData*****************//
private String getEncodedData(Map<String,String> data) {
StringBuilder sb = new StringBuilder();
for(String key : data.keySet()) {
String value = null;
try {
value = URLEncoder.encode(data.get(key), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if(sb.length()>0)
sb.append("&");
sb.append(key + "=" + value);
}
return sb.toString();
}`enter code here`

Using Intent to pass variable from Activity

I want to send a value("sessionId") from one activity to another. I have used intent for that but I don't know how to access that variable so that I can use it in Intent.
This is my java file:-
public class Login extends Activity {
//URL to get JSON Array
private static String url = "http://*************/webservice.php?operation=getchallenge&username=admin";
//JSON Node Names
private static final String TAG_RESULT = "result";
private static final String TAG_TOKEN = "token";
// contacts JSONArray
JSONArray contacts = null;
String token = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
new AsyncTask<Void, Void, Void>() {
#SuppressWarnings("unused")
JSONObject result;
#Override
protected Void doInBackground(Void... params) {
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting JSON Array
result = json.getJSONObject(TAG_RESULT);
JSONObject json_result = json.getJSONObject(TAG_RESULT);
// Storing JSON item in a Variable
token = json_result.getString(TAG_TOKEN);
//Importing TextView
} catch (JSONException e) {
e.printStackTrace();
}
String username="admin";
String accesskeyvalue = "**************";
String accessKey=md5(token + accesskeyvalue);
String data = null;
try {
data = URLEncoder.encode("username", "UTF-8")
+ "=" + URLEncoder.encode(username, "UTF-8");
data += "&" + URLEncoder.encode("accessKey", "UTF-8") + "="
+ URLEncoder.encode(accessKey, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String text = "";
BufferedReader reader=null;
System.out.println(data);
// Send data
try
{
// Defined URL where to send data
URL url = new URL("http://***************/webservice.php?operation=login");
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + "\n");
}
text = sb.toString();
}
catch(Exception ex)
{
}
finally
{
try
{
reader.close();
}
catch(Exception ex) {}
}
// Show response
System.out.println(text);
String sessionid = text.substring(41, 62);
System.out.println(sessionid);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}.execute();
}
public String md5(String s)
{
MessageDigest digest;
try
{
digest = MessageDigest.getInstance("MD5");
digest.update(s.getBytes(),0,s.length());
String hash = new BigInteger(1, digest.digest()).toString(16);
return hash;
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return "";
}
public void sendMessage(View view)
{
Intent intent = new Intent(Login.this, Quote1.class);
intent.putExtra("sessionId", sessionId);
startActivity(intent);
}
}
Here in sendMessage() I am not able to use sessionId as it is declared in doInBackground() which is protected.
I am bit weak in OOP.
Please help.
To access variables within a class between different methods simply make the variable a class variable.
To send data between activities refer to this article.
Basic example of Activity1 sending message to Activity2:
Activity1:
//Static String to identify the send parameter, without this this you have to set the exact same string twice.
public final static String SESSION_ID = "com.example.your.long.appname.SESSION_ID";
//sendMessage method is called for some reason in your class that you define (e.g user onClick)
public void sendMessage(View view) {
//Create an Intent
Intent intent = new Intent(this, Activity2.class);
//put the sessionID as extra intent.
intent.putExtra(SESSION_ID, sessionID);
//Start Activity2 with the intent.
startActivity(intent);
}
And to get the variable sent, use getStringExtra(String) for example in Activity2:
//Get the intent
Intent intent = getIntent();
//Get the message
String message = intent.getStringExtra(Activity1.SESSION_ID);
you can put your sessionId variable as a class variable in Login class as you did for TAG_RESULT, TAG_TOKEN etc...
Then, because your asyncTask is declared inline this Login class, you cann access it (and change its value) from it (the AsyncTask) and also access it's value in sendMessage method of the Login class.
I would also recommand (for better readability) to put you AsyncTask as another class (inner class of LoginClass). Code will be more readable.

How to download JSON data in android

I am developing an android application in which first I am sending request to Web service and getting the response status in 0 or 1 format if I get the response as 1 then complete JSON file is loaded.
My question is I want to make an offline app for which I want to download the JSON data from one activity and read that data in different activity with listview displaying title of every downloaded JSON file. After clicking the listview item, JSON data is displayed. And some of the JSON data items contains URL of images I also want to download them and display them in another activity.
I also want to encrypt the downloaded JSON data. Please Help me.
For reference I have attached the JSON file format.
{"test_time":7200,"time_taken":"0","time_left":"7200","score":null,"easy_score":null,"medium_score":null,"hard_score":null,"status":"n","sections":[{"section_id":"196498","section_name":"Reasoning Aptitude","section_no":1,"total_questions":"40","total_minutes":"24","questions":[{"question_id":"61562","question":{"1":{"text":"In a certain code GRANT is written as UOBSH and PRIDE is written as FEJSQ. How is SOLD written in that code?","image":"","imgHeight":"","imgWidth":""}},"correct_ans":{"1":{"text":"EMPT","image":"","imgHeight":"","imgWidth":""}},"rightOption":[],"rightOptionID":"246408","rightOptionNo":"2","anwer_explaination":{"1":{"text":"","image":"http://abc.com/testengine/images/questions/bankpower/image1.Jpeg","imgHeight":304,"imgWidth":212},"2":{"text":" ","image":"","imgHeight":"","imgWidth":""}},"question_time_taken":"10","marked":"0","skipped":"0","answer_id":"1395795","option_choose":"246407","question_status":1,"options":[{"OptionId":"246406","OptionDesc":{"1":{"text":"EPMT","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246407","OptionDesc":{"1":{"text":"TPME","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246408","OptionDesc":{"1":{"text":"EMPT","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246409","OptionDesc":{"1":{"text":"CKNR","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246410","OptionDesc":{"1":{"text":"ETPM","image":"","imgHeight":"","imgWidth":""}}}]},{"question_id":"61563","question":{"1":{"text":"Four of the following five are alike in a certain way and so form a group. Which is the one that does not belong to that group?","image":"","imgHeight":"","imgWidth":""}},"correct_ans":{"1":{"text":"27","image":"","imgHeight":"","imgWidth":""}},"rightOption":[],"rightOptionID":"246414","rightOptionNo":"3","anwer_explaination":{"1":{"text":"Mouse is odd rest are use for storage.","image":"","imgHeight":"","imgWidth":""}},"question_time_taken":"0","marked":"0","skipped":"1","answer_id":"","option_choose":"","question_status":3,"options":[{"OptionId":"246411","OptionDesc":{"1":{"text":"19","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246412","OptionDesc":{"1":{"text":"17","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246413","OptionDesc":{"1":{"text":"13","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246414","OptionDesc":{"1":{"text":"27","image":"","imgHeight":"","imgWidth":""}}},{"OptionId":"246415","OptionDesc":{"1":{"text":"37","image":"","imgHeight":"","imgWidth":""}}}]}
parse all the data using the parser detailed in that link
http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
then Write all the data into a file using the method below , this way ur data is downloaded and saved as a file
public void appendData(String text)
{
File myFile = new File("sdcard/myfile.file");
if (!myFile.exists())
{
try
{
myFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(myFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You need to do something like this:
private class PrepareMapTask extends AsyncTask<String, Integer, Boolean>
{
// Initialize with invalid value
private int mPrepareResult = -1;
private String mJsonString = null;
protected Boolean doInBackground(String... urls)
{
mJsonString = downloadFileFromInternet(urls[0]);
if(mJsonString == null /*|| mJsonString.isEmpty()*/)
return false;
JSONObject jObject = null;
try {
jObject = new JSONObject(mJsonString);
JSONArray jsonImageArray = jObject.getJSONArray("imageTarget");
JSONArray jsonUrlArray = jObject.getJSONArray("videoUrls");
JSONArray jsonVideoOrUrlArray = jObject.getJSONArray("videoOrUrl");
if (jsonImageArray == null || jsonUrlArray == null)
return false;
for (int i = 0; i<jsonImageArray.length(); i++){
mapTargetUrl.put(jsonImageArray.get(i).toString(), jsonUrlArray.get(i).toString());
mVideoOrUrl.add(jsonVideoOrUrlArray.get(i).toString());
}
} catch (JSONException e) {
e.printStackTrace();
return false;
}
return true;
}
protected void onPostExecute(Boolean result)
{
}
private String downloadFileFromInternet(String url)
{
if(url == null /*|| url.isEmpty() == true*/)
new IllegalArgumentException("url is empty/null");
StringBuilder sb = new StringBuilder();
InputStream inStream = null;
try
{
url = urlEncode(url);
URL link = new URL(url);
inStream = link.openStream();
int i;
int total = 0;
byte[] buffer = new byte[8 * 1024];
while((i=inStream.read(buffer)) != -1)
{
if(total >= (1024 * 1024))
{
return "";
}
total += i;
sb.append(new String(buffer,0,i));
}
}catch(Exception e )
{
e.printStackTrace();
return null;
}catch(OutOfMemoryError e)
{
e.printStackTrace();
return null;
}
return sb.toString();
}
private String urlEncode(String url)
{
if(url == null /*|| url.isEmpty() == true*/)
return null;
url = url.replace("[","");
url = url.replace("]","");
url = url.replaceAll(" ","%20");
return url;
}
}
Take the data structures as per your json and modify the code.
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
// Set HTTP parameters
/*StringEntity se;
se = new StringEntity(jsonObjSend.toString());*/
jsonObjSend.length();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(jsonObjSend.length());
nameValuePairs.add(new BasicNameValuePair("data", jsonObjSend.toString()));
// Log.i("jsonObjSend.toString()","jsonObjSend.toString()"+jsonObjSend.toString());
Log.i("HTTPPOST","URL: "+URL);
Log.i("HTTPPOST","Request: "+jsonObjSend.toString());
UrlEncodedFormEntity en=new UrlEncodedFormEntity(nameValuePairs);
en.getContent();
httpPostRequest.getParams().setParameter("http.socket.timeout", new Integer(600000));
httpPostRequest.setEntity(en);
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
Log.i(TAG, httpPostRequest.getRequestLine().getProtocolVersion().toString());
responses = convertEntityToString(response.getEntity(), "UTF-8");
Log.i("HTTPPOST","Responce: "+responses);
Log.i("HTTPPOST","******************");
//Log.i("Encoding",response.getEntity().getContentEncoding().getName());
if (response.equalsIgnoreCase("")) {
webresponse = 1;
} else {
webresponse = 0;
}
} catch (IOException e) {
h.post(new Runnable() {
#Override
public void run() {
pd.dismiss();
AlertNullWebserviceResponce();
}
});
e.printStackTrace();
}

Categories