How to Initialize Array inside while loop - android

I have been struggling for hours trying to use an array inside a while loop. The problem is that im very new to android development so i have no idea how to do this. I have seen similar questions but most/all of them does not suite for my scenario. The code below does work but im calling a new instance of articlesData for each row in the while statement, this causes it to just return the value of the last row.. Is there any way to use an array like ArticlesData[] and get all my data in it? Please help :) Here is my code:
public ArticlesData[] getArticleData(int no) {
Log.e("DB STAT", "getArticleData Called");
SQLiteDatabase db = helper.getWritableDatabase();
String[] columns = { ArticlesHelper.ID, ArticlesHelper.TITLE, ArticlesHelper.IMAGEURL };
Cursor cursor = db.query(ArticlesHelper.TABLE_NAME,
columns,
ArticlesHelper.DATENUMBER+" < '"+Integer.toString(no)+"'", null, null, null, ArticlesHelper.DATENUMBER+" DESC", "20");
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
Log.e("DB STAT", "Article Id = "+Integer.toString(id));
String title = cursor.getString(1);
Log.e("DB STAT", "Article Title = "+title);
String url = cursor.getString(2);
articlesData = new ArticlesData[] {
new ArticlesData(title, Integer.toString(id), url)
};
}
return articlesData;
}

You most probably want to use a Collection such as List:
public List<ArticlesData> getArticleData(int no) {
Log.e("DB STAT", "getArticleData Called");
SQLiteDatabase db = helper.getWritableDatabase();
String[] columns = { ArticlesHelper.ID, ArticlesHelper.TITLE, ArticlesHelper.IMAGEURL };
Cursor cursor = db.query(ArticlesHelper.TABLE_NAME,
columns,
ArticlesHelper.DATENUMBER+" < '"+Integer.toString(no)+"'", null, null, null, ArticlesHelper.DATENUMBER+" DESC", "20");
List<ArticlesData> list = new ArrayList<ArticlesData>();
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
Log.e("DB STAT", "Article Id = "+Integer.toString(id));
String title = cursor.getString(1);
Log.e("DB STAT", "Article Title = "+title);
String url = cursor.getString(2);
list.add(new ArticlesData(title, Integer.toString(id), url));
}
return list;
}
You should not try to use a raw array here because it has a fixed size. You could use it if you limited the number of rows in the query so you'd know exactly how much elements you need, but even then it would still be much easier to just use a Collection elsewhere in the code.
As you seem new to Android development and Java I suggest you first get acquainted with the basic data structures such as Maps, Lists, and Sets, and then later you might want to use an ORM to save you the pain of writing boilerplate code for interacting with a database.

Related

Fetching and saving Contacts to SQLite database blocking the UI for long time

I am using below code to get all Contacts and saving in Local database.
Getting contacts:
ArrayList<ContactHolder> contactList = new ArrayList<ContactHolder>();
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor managedCursor = mContext.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, order);
int _number = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int _name = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int _id = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
while (managedCursor.moveToNext()) {
ContactHolder holder = new ContactHolder();
//String mData = Utility.filterLocaleWithAppropreateFlagsTest(mContext, managedCursor.getString(_number));
holder.setNumber(managedCursor.getString(_number).replaceAll("\\s+",""));
holder.setName(managedCursor.getString(_name));
holder.setImageUrl(managedCursor.getString(_name));
contactList.add(holder);
}
Saving in SQLite DB:
public List<Contact> insertContactDetails() {
ArrayList<ContactHolder> arr = Utility.getContactDetails(context);
List<Contact> serverArr = new ArrayList<Contact>();
List<ContentValues> list = new ArrayList<ContentValues>();
for (int i = 0; i < arr.size(); i++) {
String mLocaleNo = "";
ContactHolder mObject = arr.get(i);
String mData = Utility.filterLocaleWithAppropreateFlagsTest(context, mObject.getNumber().replaceAll("\\s+",""));
if (mData != null) {
Contact mContact = new Contact();
ContentValues values = new ContentValues();
values.put(CONTACT_NAME, mObject.getName());
mContact.setName(mObject.getName());
values.put(CONTACT_MOBILE_NUMBER, mObject.getNumber().replaceAll("\\s+",""));
values.put(CONTACT_IMAGE, mObject.getImageUrl());
ArrayList<String> extra = new ArrayList<String>();
StringTokenizer token = new StringTokenizer(mData);
while (token.hasMoreElements()) {
extra.add(String.valueOf(token.nextElement()));
}
mLocaleNo = extra.get(0);
int mLocaleFlag = Integer.parseInt(extra.get(1));
values.put(LOCALE_NUMBER, mLocaleNo);
mContact.setPhNo(mLocaleNo);
values.put(LOCALE_FLAG, mLocaleFlag);
values.put(REG_STATUS, "0");
list.add(values);
serverArr.add(mContact);
}
/*
arr.get(i).setContactStatus("0");
arr.get(i).setLocaleNumber(mLocaleNo);*/
}
ourDatabase.beginTransaction();
for (ContentValues entry : list) {
try{
long id = ourDatabase.insertOrThrow(CONTACT_TABLE, null, entry);
}catch(Exception e){
e.printStackTrace();
}
}
ourDatabase.setTransactionSuccessful();
ourDatabase.endTransaction();
return serverArr;
}
Everything is working as expected but if the contact size is huge then the actual problem comes to the picture which makes the screen white for a long.
I still not found any proper solution to handle this.
I can recommend to use only ContentValues as an model to handle contacts from source to dest.
If you will dig little, you can able to find out the actual issue. You are using contactHolder to store and again retrive and again store in ContentValues which is not necessary I think. Just change the code as below and see the improvements.
I simply added your code in a method and add some changes in it.
Fetch contacts:
public static ArrayList<ContentValues> getContactDetails(final Context mContext){
ArrayList<ContentValues> contactList = new ArrayList<ContentValues>();
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor managedCursor = mContext.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, order);
int _number = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int _name = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int _id = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
while (managedCursor.moveToNext()) {
ContentValues values = new ContentValues();
Contact mContact = new Contact();
values.put(ContactClass.CONTACT_NAME, managedCursor.getString(_name));
values.put(ContactClass.CONTACT_MOBILE_NUMBER, managedCursor.getString(_number).replaceAll("\\s+",""));
mContact.setPhNo(managedCursor.getString(_number).replaceAll("\\s+",""));
mContact.setName(managedCursor.getString(_name));
contactList.add(values);
serverContactList.add(mContact);
}
}
return contactList;
}
Here I simply use same ContentValues class as a model to hold contacts inside collection and simply adding the same data for your Contacts (server stuffs) class which are saving in a static collection (serverContactList) which you can direct access from anywhere.
NB: ContactClass.CONTACT_MOBILE_NUMBER is your column name.
Insert Contacts to DB:
public List<Contact> insertContactDetails() {
List<ContentValues> list = Utility.getContactDetails(context);
ourDatabase.beginTransaction();
for (ContentValues entry : list) {
try{
long id = ourDatabase.insertOrThrow(CONTACT_TABLE, null, entry);
}catch(Exception e){
e.printStackTrace();
}
}
ourDatabase.setTransactionSuccessful();
ourDatabase.endTransaction();
return Utility.serverContactList;
}
It will make your performance more better if you will do all these stuffs in a background thread as others suggested here.
You should use CursorLoader for save/retrieve if data is huge.
There are three key benefits of using a CursorLoader:
The query is handled on a background thread for you (courtesy of being built on AsyncTaskLoader) so that large data queries do not block the UI. This is something the docs recommended for you to do when you’re using a plain Cursor, but now it's done under the hood.
CursorLoader is auto-updating. In addition to performing the initial query, CursorLoader also registers a ContentObserver with the dataset you requested and calls forceLoad() on itself when the data set changes.
This results in getting async callbacks anytime the data changes in order to update the view.
For more read this Cursor Loader.

Accessing contact data Android

If I'm assigning a value to a field of a contact, such as nickname;
.withValue(Nickname.NAME, "Mr. Incredible")
it is stored in the DATA1 column according to http://developer.android.com/reference/android/provider/ContactsContract.CommonDataKinds.Nickname.html
Yet, if I add a SIP Address with SipAddress.SIP_ADDRESS() it's value is also assigned to column DATA1. How do I differentiate between these two? I'm a bit confused on how to access a contacts specific fields and I can't find an explanation in the Android Reference.
I'm specifically using
SimpleCursorAdapter(getActivity(),
R.layout.contact_list, null, new String[] {
SipAddress.DISPLAY_NAME, SipAddress.SIP_ADDRESS, Nickname.NAME},
new int[] {
R.id.text1, R.id.text2, R.id.text3}, 0);
Please try,
try {
Cursor cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data.DISPLAY_NAME},
ContactsContract.CommonDataKinds.Nickname.DATA1 + "=" + text, null, null);
cursor.moveToFirst();
String Nickname = cursor.getString(0);
}
catch (Exception e) {
}
Yes its saved in ContactsContract.DataColumns.DATA1 with the String SIP_ADDRESS. May this helps you ContactsContract.CommonDataKinds.SipAddress
Happy coding!

How to check the value already excists or not in sqlite db in android?

In my application I am saving a bill number in SQLite database. Before I add a new bill number how to check if the bill number exists in the DB.
My main class code is,
String bill_no_excist_or_not = db.billno_exist_or_not(""+et_bill_number.getText().toString());
Log.v("Bill No", ""+bill_no_excist_or_not);
My DB Code,
String billno_exist_or_not(String bill_number){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_BILL_DETAILS, new String[] { KEY_BILL_NUMBER }, KEY_BILL_NUMBER + "=?"
+ new String[] { bill_number }, null, null, null, null);
//after this i don't know how to return the values
return bill_number;
}
I don't know how to check the values which is already available or not in DB. Can any one know please help me to solve this problem.
Here is the function that helps you to find whether the value is available in database or not.
Here please replace your query with my query..
public int isUserAvailable(int userId)
{
int number = 0;
Cursor c = null;
try
{
c = db.rawQuery("select user_id from user_table where user_id = ?", new String[] {String.valueOf(userId)});
if(c.getCount() != 0)
number = c.getCount();
}
catch(Exception e) {
e.printStackTrace();
} finally {
if(c!=null) c.close();
}
return number;
}
Make your KEY_BILL_NUMBER column in your table UNIQUE and you can just insert using insertWithOnConflict with the flag SQLiteDatabase.CONFLICT_IGNORE

android database adding more than needed

private static String[] FROM = { _ID, DESCRIPTION, DATE, TITLE };
//private static String ORDER_BY = _ID + " DESC" ;
private Cursor getEvents() {
// Perform a managed query. The Activity will handle closing
// and re-querying the cursor when needed.
SQLiteDatabase db = post.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null,
null, null);
startManagingCursor(cursor);
return cursor;
}
private void showEvents(Cursor cursor) {
TextView tv = new TextView(this);
// Stuff them all into a big string
StringBuilder builder = new StringBuilder(
"Saved events:\n" );
while (cursor.moveToNext()) {
// Could use getColumnIndexOrThrow() to get indexes
long id = cursor.getLong(0);
String description = cursor.getString(1);
String date = cursor.getString(2);
String title = cursor.getString(3);
builder.append(id).append(": " );
builder.append(description).append(": " );
builder.append(date).append(": " );
builder.append(title).append("\n" );
}
// Display on the screen
tv.setText(builder);
this.setContentView(tv);
}
So the showEvents function which is supposed to display the database is displaying a larger database than I created. It is showing 19 rows, yet I only called the insertorthrow function twice so it should have two rows, so I don't know how it can have more than 19 rows. I feel the problem may lie in my getEvents() function or showEvents() function which returns the cursor. Help would be appreciated.
Using db shell go to the location and delete the database .

Android SQLite rawquery returns only first record

My SQLite query returning only one record, However, the table has multiple rows
cursor=mydb.rawQuery("Select category from items;", null);
I have even tried GROUP BY but still wont work.
I am new to SQLite, would appreciate any help. Thanks.
First of all your string query must not be terminated so instead of passing it as:
"Select category from items;"
you should try passing it as:
"Select category from items"
as mentioned on this page.
Also, are you looping over the cursor? Here is an example of how to get data out of a cursor with a while loop:
ArrayList<String> results = new ArrayList<String>()
while (cursor.moveNext()) {
results.add(cursor.getString(0)); // 0 is the first column
}
First, search:
Cursor cs = myDataBase.rawQuery("Your query", null);
if (cs.moveToFirst()) {
String a = cs.getString(cs.getColumnIndex("your_column_name"));
cs.close();
return a;
}
cs.close();
return "";
Get the information from cursor:
if (cs.moveToFirst()) {
ArrayList<String> results = new ArrayList<String>()
do {
results.add(cs.getString(cs.getColumnIndex("your_column_name")));
} while (cs.moveNext());
}
Without if, I took error in my project. But this worked for me. By the way, your query doesn't look good. If you give some information about your database, we can help much more.
Use this to select all items from the table:
Cursor cursor = db.rawQuery("SELECT * FROM Tablename ,
null);
this can help you
public ArrayList<mydata> getallContents() {
ArrayList<mydata> lst = new ArrayList<mydata>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("select * from " + GAMETABLE, null);
if (c.moveToFirst()) {
do {
lst.add(new mydata(c.getString(1),
c.getString(3),c.getString(4),c.getString(5),c.getString(6)));
} while (c.moveToNext());
}
db.close();
return lst;
}
you don't need raw query method. i think that the android way is better in this case:
db.query(items, category, null, null, null, null, null);
than use the cursor how already is written in the other comment.

Categories

Resources