Send Data from SQLite to appServer using POST,OKHttp - android

I have an SQLite Db which stores call logs. Each entry has a number, date, and duration. I have seen that there are many ways we can send the data to the app server. As a JSON String and send one by one from an ArrayList of model class objects.
Which is the correct way to approach this? And how can I create a JSON from these data, I have done as much as getting these data to an ArrayList of objects. since each entry has many data, I am confused about how to do this.
public ArrayList<PhNumber> getCallLogs() {
ArrayList<PhNumber> callLogList;
callLogList = new ArrayList<PhNumber>();
String selectQuery = "SELECT * FROM callInfo where syncStatus = '" + "no" + "'";
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
callLogList.add(new PhNumber(Integer.parseInt(cursor.getString(0)), cursor.getString(1),
cursor.getString(2),
cursor.getString(3),
cursor.getString(4)));
Log.e("DbHelper:getCallLogs", callLogList.toString());
} while (cursor.moveToNext());
}
return callLogList;
}

Which is the correct way to approach this?
There is not any one solution . It depends on your use case scenario.
For making JSON , you can do this after getting your data in ArrayList<PhNumber> callLogList
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < callLogList.length(); i++) {
JSONObject jsonobject= new JSONObject();
jsonobject.put("data1",callLogList.get(i).get); //I dont know the field name of your PhNumber so fill accordingly
jsonobject.put("data2",callLogList.get(i).get);
jsonArray.put(jsonobject);
}

I would suggest you to use Retrofit for this, a library that is very easy to use, saves lot of time and code. Serialization and HTTP requests are handled seamlessly using Retrofit.
please refer to this article for simple understanding of Retrofit

Related

Storing JSON data to local database in android

Okay so, I created an app that retrieves data from my server using JSON. Now I want to store the retrieved data on my phone's local storage/db. How do I do it? I am new in android programming.
This is the JSON that I receive from the server
{"messages":[{"id":"44","issender":0,"content":"CAT1DOG","date":"Jan 01, 1970 07:30 AM","sender":"Administrator","receiver":"User"},{"id":"57","issender":0,"content":"ttt","date":"Jun 30, 2016 03:43 PM","sender":"Administrator","receiver":"User"},{"id":"58","issender":0,"content":"s","date":"Jun 30, 2016 03:43 PM","sender":"Administrator","receiver":"User"},{"id":"82","issender":0,"content":"yeuwu","date":"Jun 30, 2016 04:59 PM","sender":"Administrator","receiver":"User"}],"success":1}
and this is my code to parse JSON
for(int i = 0; i < messages.length(); i++){
JSONObject o = messages.getJSONObject(i);
String msgid = o.getString("id");
String message = o.getString("content");
String date = o.getString("date");
String sender = o.getString("sender");
String receiver = o.getString("receiver");
String issender = o.getString("issender");
// TEMP HASHMAP FOR USER
HashMap<String, String> msgList = new HashMap<String, String>();
// ADDING EACH CHILD NOTE TO HASHMAP => VALUE
msgList.put("id", uid);
msgList.put("message", message);
msgList.put("date", date);
msgList.put("name", sender);
msgList.put("receivername", receiver);
// ADDING USER TO MSGLIST
ListOfMsg.add(msgList);
}
Thanks in advance for those who will answers. will appreciate it.
First I need to tell you that this is not the easy way out but for sure it is the correct one.
Next create a new class named Message
public class Message{
public String issender;
}
When you receive the json :
List<Message> messages= new ArrayList<>();
Gson gson = new Gson();
Message m= gson.fromJson(json.toString(),Message.class);
messages.add(m);
Please be careful that the items in the class should have the name as the items in the json you are trying to receive
Now we are done with this part:
Let us add the library for caching:
Follow this tutorial and if you need help get back to me:
https://guides.codepath.com/android/activeandroid-guide
or you could do the caching using sql old fashioned way
You can do this in two ways:
Use the new extension for json in sqite. The information you might need is available on this page https://www.sqlite.org/json1.html . Still I would suggest to do a little bit more of research on this, as it is new and I have not used it yet.
You can convert your json to string and insert it to the database.
String jsontostring = jsonObject.toString();

Raw query to Ormlite (JOINS,GROUPBY) correct way

i am using ormlite version 4.46 I am able to get the desired result when i run a raw query but somehow the result is null when i am trying it in ormlite can someone please explain where i am making a mistake.
Snippet:
String query=
"SELECT Products.* FROM "+DBConst.TABLE_PRODUCTS
+" INNER JOIN "+DBConst.TABLE_OFFERS_MAPPING
+" ON Products."+DBConst.PROD_ID+" = OffersMapping."+DBConst.OFFERS_PRODUCT_ID
+" WHERE "+DBConst.OFFERS_OFFER_ID+ " = "+offerId+
" GROUP BY "+DBConst.PROD_PARENT_PRODVAR_ID;
GenericRawResults<Product> rawResults = productDao.queryRaw(query, productDao.getRawRowMapper());
//produces this query:SELECT Products.* FROM Products INNER JOIN OffersMapping ON Products._id = OffersMapping.product_id WHERE offer_id = 141 GROUP BY variant_id
List<Product> prodList = rawResults.getResults();
rawResults.close();
Gives me desired result....
Now to ormlite
Dao<Product, String> productDao = helper.getProductDao();
Dao<OfferMapping, String> offerMappingDao = helper.getOfferMappingDao();
try {
QueryBuilder<Product, String> productQb = productDao.queryBuilder();
QueryBuilder<OfferMapping, String> offerQb = offerMappingDao.queryBuilder();
//to sort the offer id accordingly
offerQb.where().eq(DBConst.OFFERS_OFFER_ID, offerId);
productQb.where().eq(DBConst.PROD_ID, new ColumnArg(DBConst.OFFERS_PRODUCT_ID));
productQb.join(offerQb);
productQb.groupBy(DBConst.PROD_PARENT_PRODVAR_ID);
Constants.showLog("Query", "Query is "+productQb.query());//gets null here
List<Product> prodList = productQb.query();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
Dont know where i am making a mistake...
i am using ormlite version 4.46 I am able to get the desired result when i run a raw query but somehow the result is null when i am trying it in ormlite can someone please explain where i am making a mistake.
Sorry for the late response. I would log the generated query from the ORMLite query-builder and then compare it with your hand generated query. You can log the results of productQb.prepareStatementString() before the query is performed. For more information see the logging documentation.
Let me know if ORMLite is doing something wrong.

Sql lite gets all data sent to webservice JSon format in android?

I am creating local database I want to send all data sent to web service.
For example product name one column. Lots of product name is there. I want to send it.
& Product name = briyani,egg,rice
I got all details from database below i have mention code:
public String fetchMyRowid(String column_name)
{
String query = "select "+column_name+" From " + TABLErestaurant;
mCursor =db.rawQuery(query, null);
StringBuffer buf = new StringBuffer();
if (mCursor.moveToNext()) {
buf.append(mCursor.getString(0));
String str = buf.toString();
System.out.println("**************"+str);
}
return buf.toString();
}
}
return buf.toString();
}
In class :
HashMap<String, String> paramsvalue = new HashMap<String, String>(); paramsvalue.put("product_name", dataBase.fetchMyRowid(DatabaseHelper.columnproductname));
But I have some issue. I got only one product name. I need all product name. Can any one suggest solution for this.
wel come to stackoveflow,
Please check below link in that i have first select all table's recode then i have created one another method for get all columns value by row. after that i have marge all data in to JSON. this is idea you have to do similar way...
https://stackoverflow.com/a/10600440/1168654

What is the fastest way to parse a JSON string into an SQLite table?

I'm writing an Android application which will occasionally need to download a json string of around 1MB and containing around 1000 elements, and parse each of these into an SQLite database, which I use to populate a ListActivity.
Even though the downloading and parsing isn't something that needs to be done on every interaction with the app (only on first run or when the user chooses to refresh the data), I'm still concerned that the parsing part is taking too long, at around two to three minutes - it seems like an eternity in phone app terms!
I'm currently using Gson to parse each json object into a custom object that I've defined, and then using an SQLiteOpenHelper to enter it into the database.
My question is - is there a faster way of implementing this? Would it be noticeably faster to interact with the json directly, without using Gson? Or am I doing something stupid in the code below that's slowing things down?
Here's the method I'm using in my AsyncTask to parse the json to SQLite:
protected Boolean doInBackground(Integer... bType) {
InputStream source = getJsonInputStream(bTypeString);
VegDataHandler db = new VegDataHandler(mainActivity, bTypeString);
Gson gson = new Gson();
Reader reader = new InputStreamReader(source);
JsonParser jParser = new JsonParser();
JsonArray jArray = jParser.parse(reader).getAsJsonArray();
aLength = jArray.size();
mCurrProgress = 1;
publishProgress(mCurrProgress, 0, aLength);
/* Each array element is of the form { company: {...} } */
int i = 0;
mCurrProgress = 2;
for (JsonElement obj : jArray) {
Company c = gson.fromJson(obj.getAsJsonObject().getAsJsonObject("company"), Company.class);
db.addCompany(c);
i++;
publishProgress(mCurrProgress, i);
}
}
This is the addCompany method from my VegDataHandler class, which extends SQLiteOpenHelper:
public void addCompany(Company c) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_ID, c.getCompanyId());
values.put(KEY_NAME, c.getCompanyName());
values.put(KEY_RYG, c.getCompanyRedYellowGreen());
values.put(KEY_COUNTRY, c.getCompanyCountry());
values.put(KEY_URL, c.getCompanyUrl());
values.put(KEY_NOTES, c.getCompanyNotes());
values.put(KEY_EMAIL, c.getCompanyEmail());
db.insertWithOnConflict(TABLE_COMPANY, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
This is the class that holds each json element before adding to the SQLite (I've omitted the getters and setters for brevity).
public class Company {
public Company() {
}
#SerializedName("id")
public int companyId;
#SerializedName("company_name")
public String companyName;
#SerializedName("red_yellow_green")
public String companyRedYellowGreen;
#SerializedName("country")
public String companyCountry;
#SerializedName("url")
public String companyUrl;
#SerializedName("notes")
public String companyNotes;
#SerializedName("email")
public String companyEmail;
}
Thanks in advance for any replies.
First you need to determine the portion(s) of the process that are eating up the most time. From your comment above it sounds like the JSON parsing is the culprit.
If JSON parsing is the issue:
Research and consider a faster JSON parser. Perhaps something like json-smart.
If SQLite/DB bulk inserts are the issue:
See my answer here
General tips:
Recycle objects as much as possible (keep new to a minimum)
Always use transactions in DB bulk inserts at the very least
Don't open/close the database. Do this once at the start/finish of your processing
Use pre-compiled statements!

Android Http Post streaming json

I ran into trouble trying to send SQLite data to a web server using json (gson).
Everything was fine until the table came round 6000 rows.
I ran into Out of Memory errors.
In my datahelper I have:
public String DonneesToJson (SQLiteDatabase db, int chantier, int chantier_serveur )
{
Cursor c = db.rawQuery("select * from "+P_TABLE+" where "+P_CHANTIER+"="+chantier+ " order by "+P_TIME+" desc ", null);
List<Donnees> donnees = new ArrayList<Donnees>();
c.moveToFirst();
while (c.moveToNext())
{
Donnees d = new Donnees (
c.getInt(c.getColumnIndex(Datahelper.P_ID)),
chantier_serveur,
offset,
c.getInt(c.getColumnIndex(Datahelper.P_PLAN)),
c.getString(c.getColumnIndex(Datahelper.P_TIME)),
c.getInt(c.getColumnIndex(Datahelper.P_PRESSION)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR_TOTALE)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_X)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_Y)),
c.getString(c.getColumnIndex(Datahelper.P_PIEU)),
c.getInt(c.getColumnIndex(Datahelper.P_NO_RALLONGE)),
c.getString(c.getColumnIndex(Datahelper.P_RALLONGE)),
c.getInt(c.getColumnIndex(Datahelper.P_MOTEUR)),
c.getString(c.getColumnIndex(Datahelper.P_SERIE)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_A)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_B))
);
donnees.add(d);
}
c.close();
Gson gson = new Gson();
return gson.toJson(donnees);
}
Basically I call this like that:
String resultat = dbHelper.DonneesToJson(db,i, chantier_serveur);
HttpPost post2 = new HttpPost("http://www.zzzzzzz.com/test.php");
StringEntity se = new StringEntity(resultat);
se.setContentEncoding( new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post2.setEntity(se);
response = client.execute(post2);
On the server side, it's quite basic php to store data in a big sql DB and then do analysis.
ie:
$decoded = json_decode($HTTP_RAW_POST_DATA,true);
foreach ( $decoded as $key => $value)
{
$query = ...
While doing OOM erros, it's slow. I mean getting sql data to json is slow.
I tried to go the jackson route, faster, no out of memory error, but... it can only write to a file or a stream.
I'd try to avoid writing to a file then send the file trough http post.
So I decided to open an http stream to send json data and I'm stuck.
I did not find any example on how to open an output stream to the web server using apache.
Any help appreciated.
Despite the answer from dmon to split the data into batches, you should work on other glitches. Try this code:
public String DonneesToJson (SQLiteDatabase db, int chantier, int chantier_serveur ) {
Cursor c = db.rawQuery("select * from "+P_TABLE+" where "+P_CHANTIER+"="+chantier+ " order by "+P_TIME+" desc ", null);
List<Donnees> donnees = new ArrayList<Donnees>();
if (c != null) { // nullcheck as rawQuery can return null!
Donnees d; // reuse variables for loops
while (c.moveToNext()) { // was buggy before, read comment below code
d = new Donnees (
c.getInt(c.getColumnIndex(Datahelper.P_ID)),
chantier_serveur,
offset,
c.getInt(c.getColumnIndex(Datahelper.P_PLAN)),
c.getString(c.getColumnIndex(Datahelper.P_TIME)),
c.getInt(c.getColumnIndex(Datahelper.P_PRESSION)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR)),
c.getInt(c.getColumnIndex(Datahelper.P_PROFONDEUR_TOTALE)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_X)),
c.getInt(c.getColumnIndex(Datahelper.P_ANGLE_Y)),
c.getString(c.getColumnIndex(Datahelper.P_PIEU)),
c.getInt(c.getColumnIndex(Datahelper.P_NO_RALLONGE)),
c.getString(c.getColumnIndex(Datahelper.P_RALLONGE)),
c.getInt(c.getColumnIndex(Datahelper.P_MOTEUR)),
c.getString(c.getColumnIndex(Datahelper.P_SERIE)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_A)),
c.getDouble(c.getColumnIndex(Datahelper.P_COEFF_B)));
donnees.add(d);
}
c.close();
}
return new Gson().toJson(donnees);
}
Your current implementation is buggy and you will never get the first entry. The reason for that is your call to moveToFirst() which moves you to the first. The while loop will move the internal pointer to the second entry with moveToNext() which will result in starting with the second element and completely ignoring the first one. Always and forever...

Categories

Resources