Actually I am using call logs as an input to database and then I am fetching it in a way that I can't get any duplicate values while displaying it and if i have any duplicate value in data base then it should be taken as integer value count. For example: john(6).
Here john must have entry 6 times in database. Don't get me wrong. I don't need a code.I need help. Here is code:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(android.provider.CallLog.Calls.CONTENT_URI,null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String rawContactId = cur.getString(cur.getColumnIndex(android.provider.CallLog.Calls._ID));
Cursor callLogCursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, new String[]{
android.provider.CallLog.Calls.CACHED_NAME,
android.provider.CallLog.Calls.CACHED_NUMBER_LABEL,
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.DATE,
android.provider.CallLog.Calls.DURATION,
android.provider.CallLog.Calls.TYPE
},android.provider.CallLog.Calls._ID + "=?", new String[] { rawContactId }, null);;
if (callLogCursor != null) {
while (callLogCursor.moveToNext()) {
//String id = callLogCursor.getString(0);
String name = callLogCursor.getString(0);
String cacheNumber = callLogCursor.getString(1);
String number = callLogCursor.getString(2);
long dateTimeMillis = callLogCursor.getLong(3);
long durationMillis = callLogCursor.getLong(4);
int callType = callLogCursor.getInt(5);
String duration = getDuration(durationMillis * 1000);
String dateString = getDateTime(dateTimeMillis);
if (cacheNumber == null)
cacheNumber = number;
if (name == null)
name = "Unknown";
Uri image = null;
try {
String conId = fetchContactIdFromPhoneNumber(cacheNumber);
long contId = Long.parseLong(conId);
image = getPhotoUri(contId);
}catch(Exception e) {
Log.e("Exception", e.getMessage());
}
//CallLogModel callLogModel = new CallLogModel(image, name, cacheNumber,
// duration, dateString);
ContentValues values = new ContentValues();
values.put(NAME, name);
values.put(NUMBER, cacheNumber);
values.put(DATE, dateString);
values.put(DURATION,duration );
database.insert(CALL_LOG_TABLE, null, values);
Cursor cursor = database.query(CALL_LOG_TABLE, new String [] {LOG_ID, NAME, NUMBER, DATE, DURATION}, null, null, null, null, null);
int row =0;
if(!cursor.isAfterLast()) {
cursor.moveToFirst();
do{
int pId=cursor.getInt(0);
String pName = cursor.getString(1);
String pNumber = cursor.getString(2);
String pDate = cursor.getString(3);
String pDuration = cursor.getString(4);
int value = 0;
CallLogModel callLogModel = new CallLogModel(image, name, cacheNumber, duration, dateString);
if (callType == CallLog.Calls.OUTGOING_TYPE) {
for(int i=0;i<outgoingList.size();i++){
------------------------------Actually i want Logic here what should i do here--------------
}
}
outgoingList.add(callLogModel);
} else if (callType == CallLog.Calls.INCOMING_TYPE) {
incomingList.add(callLogModel);
} else if (callType == CallLog.Calls.MISSED_TYPE) {
missedcallList.add(callLogModel);
}
cursor.moveToNext();
} while (!cursor.isAfterLast());
}
}
callLogCursor.close();
}
}
You could model the outgoing calls in a hashmap, something like:
Map<String, Integer> outgoingCallsMap = new HashMap<String, Integer>();
for (int i = 0; i < outgoingList.size(); i++) {
String nameOfCallee = outgoingList.get(i);
if (!outgoingCallsMap.containsKey(nameOfCallee)) {
outgoingCallsMap.put(nameOfCallee, 1);
} else {
//Increment calls to this person
outgoingCallsMap.put(nameOfCallee, outgoingCallsMap.get(nameOfCallee) + 1);
}
}
Remove the duplicates in your outGoingList, by iterating it and putting the result to a map, with contact name as key and list of CallLogModel object as value.
You can refer this method.
private void convertToOutGoingMap(List<CallLogModel > outGoingList) {
HashMap<String,List<CallLogModel>> outGoingMap = new HashMap<String, List<CallLogModel>>();//map which has CallLogModel.name as key and List<CallLogModel> as value.
for(CallLogModel model : outGoingList){//Iterate thru the list.
if(outGoingMap.containsKey(model.name))
{
outGoingMap.get(model.name).add(model);//if map contains key, add model to the list.
} else {
List<CallLogModel> modelList = new ArrayList<CallLogModel>();//if it does not contains, initialize a list and add model to it.
modelList.add(model);
outGoingMap.put(model.name, modelList);
}
}
}
}
The key set of this map gives you the unique call log names and corresponding value list gives all occurrences and its size gives you number of occurrences.
Hope this help you.
Related
I have gone through a lot of posts but didn't find any answer that answers the question efficiently or even correctly. The closest I came was this How to avoid duplicate contact name (data ) while loading contact info to listview? but this has too much overhead. Is there any simpler or more efficient way to solve this?
I had the same problem you had: I was getting duplicate phone numbers. I solved this problem by obtaining the normalized number for each cursor entry and using a HashSet to keep track of which numbers I'd already found. Try this:
private void doSomethingForEachUniquePhoneNumber(Context context) {
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
//plus any other properties you wish to query
};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
} catch (SecurityException e) {
//SecurityException can be thrown if we don't have the right permissions
}
if (cursor != null) {
try {
HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();
int indexOfNormalizedNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER);
int indexOfDisplayName = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int indexOfDisplayNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
while (cursor.moveToNext()) {
String normalizedNumber = cursor.getString(indexOfNormalizedNumber);
if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {
String displayName = cursor.getString(indexOfDisplayName);
String displayNumber = cursor.getString(indexOfDisplayNumber);
//haven't seen this number yet: do something with this contact!
} else {
//don't do anything with this contact because we've already found this number
}
}
} finally {
cursor.close();
}
}
}
After API 21 We Write this Query for remove contact duplicacy.
String select = ContactsContract.Data.HAS_PHONE_NUMBER + " != 0 AND " +
ContactsContract.Data.MIMETYPE
+ " = " + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "
AND "+ ContactsContract.Data.RAW_CONTACT_ID + " = " +
ContactsContract.Data.NAME_RAW_CONTACT_ID;
Cursor cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, select,
null, null);
ContentResolver cr = this.getContentResolver();
String[] FieldList = {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,ContactsContract.CommonDataKinds.Phone.CONTACT_ID};
Cursor c = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,FieldList,
null,null,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name,phone,ContactID;
HashSet<String> normalizedNumbers = new HashSet<>();
if(c!=null)
{
while(c.moveToNext()!=false)
{
phone = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER));
if(normalizedNumbers.add(phone)==true)
{
name = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
ContactID = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
MyContacts m = new MyContacts(name,phone,ContactID);
ContactList.add(m);
}
}
c.close();
I am using Contact picker library for selecting multiple contacts but if a contact doesn't contain any number and if it is selected then it is showing some null pointer exception in the edit text field. How to remove that message and also how to remove trailing comma. Below is my Code.
try {
int pos = 0;
for (Contact contact : contacts) {
String displayName = contact.getDisplayName();
result.append(displayName + ",");
result.setSpan(new BulletSpan(15), pos, pos + displayName.length() + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//pos += displayName.length() + 1;
}
}
catch (Exception e) {
result.append(e.getMessage());
}
contactsView.setText(result);
please try to check this code
void getAllContacts() {
ArrayList<String> nameList = new ArrayList<>();
ArrayList<String> numberList = new ArrayList<>();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
String[] list = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.Contacts._ID};
Cursor cursor = getContentResolver().query(uri, list, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
cursor.moveToFirst();
if (cursor.moveToFirst()) {
do {
String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
contactNuber.add(contactNumber);
contactsName.add(contactName);
nameList.add(contactName);
numberList.add(contactNumber);
} while (cursor.moveToNext());
cursor.close();
myContacts.put("name", nameList);
myContacts.put("number", numberList);
}
}
Here is the log of my map entries. That have two same key exists. How this is possible?
Map<String, Objects> map = new HashMap<String, Objects>();
addContact("+917111111111");
addContact("+919222222222");
addContact("+919222222222");
private void addContact(String number){
if(TextUtils.isEmpty(number))return;
number = number.trim();
number = number.replaceAll("-", "");
number = number.replaceAll(" ", "");
if(!map.containsKey(number)) {
map.put(number, null);
}
}
/* While debugging in android studio. I have found the map have below entry.
0 = {HashMap$HashMapEntry#3798} "+919222222222" -> "null"
1 = {HashMap$HashMapEntry#3832} "+919222222222" -> "null"
2 = {HashMap$HashMapEntry#3694} "+917111111111" -> "null"
*/
map.containsKey("+919222222222");// ==> return false
Why this is happen ?
Actual task:
private void getContacts(){
try {
Cursor cursor = null;
StringBuffer sb = new StringBuffer();
Map<String, Object> map = new HashMap<String, Object>();
try {
String strOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, strOrder);
int contactIdIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int photoIdIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_ID);
cursor.moveToFirst();
do {
String idContact = cursor.getString(contactIdIdx);
String name = cursor.getString(nameIdx);
String phoneNumber = cursor.getString(phoneNumberIdx);
//...
phoneNumber = getFormatedNumber(phoneNumber);
//as map key same phone number can not be two times
if(!map.containsKey(phoneNumber)) {
map.put(phoneNumber, null);
sb.append("\nPhone Number:--- " + phoneNumber + "\nUser Name:--- "
+ name);
sb.append("\n----------------------------------");
}
} while (cursor.moveToNext());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
textView.setText(sb); //As in output it shows one number showing two times
} catch (Exception e) {
e.printStackTrace();
}
}
private String getFormatedNumber(String number){
if(TextUtils.isEmpty(number))return null;
number = number.trim();
number = number.replaceAll("-", "");
number = number.replaceAll(" ", "");
return number;
}
After all discussion, I found the issue like the problem occur due to unicode character append in my string that is invisible while debugging but if we copied into notepad then it clearly visible. as like :
'\u202A\u202A+91922222222\u202A\u202C'
I have a database table with eight columns, with the following fields:
|_id|flag|HVID|Vname|Vdate|Vtime|Vcost|Vmedicine|
I am querying on this database to extract all records which belong to a certain 'HVID':
public Cursor fetchAllVac(String ID) {
String Key = ID;
Cursor mCursor = mDb.query(DATABASE_TABLE1, new String[] { IDx, FLAG,
HVID1, Vname1, VDate1, Vtime1, Vcost1, Vmedicine1 }, "HVID=?",
new String[] { Key }, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
And in the Activity, I fetch values from the cursor and store them in an Array list:
public void Vacforshare() {
String B = null;
ArrayList<String> mArrayList = new ArrayList<String>();
mCursor = DBHelper.fetchAllVac(IDB);
if (mCursor.moveToFirst()) {
do {
try {
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("_id")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("flag")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("HVID")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vname")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vdate")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vtime")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vcost")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vmedicine")));
} catch (Exception h) {
}
} while (mCursor.moveToNext());
}
for (int i = 0; i < mArrayList.size(); i++) {
String G = (mArrayList.get(i));
B = B + G;
}
System.out.println("" + B);
}
What I am getting in B is a redundant(all rows) string of values (My records can be of multiple rows) I want to separate these values into Name-Value pairs, I am confused as how to achieve that.
You can introduce a new class that would have the list of values for one record only like below:
public class Record {
List<String> values = new ArrayList<String>();
public List<String> getValues() {
return values;
}
}
Then in your loop fill-in a list of records:
ArrayList<Record> mArrayList = new ArrayList<Record>();
do {
try {
Record record = new Record();
List<String> values = record.getValues();
values.add(mCursor.getString(mCursor.getColumnIndex("_id")));
...
mArrayList.add(record);
} catch (Exception h) {
}
}
Now you can iterate through the field names and the values for each record to create the output you want:
String[] names = new String[] {"_id", "flag", ....};
for (int i = 0; i < mArrayList.size(); i++) {
Record record = mArrayList.get(i);
String current = "";
List<String> values = record.getValues();
for (int j = 0; j < values.size(); j++) {
String fieldName = names[j];
String s = values.get(j);
current += " " + fieldName + "=" + s;
}
B = B + "[" + current.trim() + "]";
}
System.out.println(B); // will print: [_id=value1 flag=value2 ...][_id=value1 flag=value2 ...] etc
ArrayList<ArrayList<NameValuePair>> table = new ArrayList<ArrayList<NameValuePair>>();
if (mCursor.moveToFirst()) {
do {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
try {
nameValuePairs.add(new BasicNameValuePair("_id",mCursor.getString(mCursor.getColumnIndex("_id"))));
//do this for the rest columns...
//...
//...
table.add(nameValuePairs);
} catch (Exception h) {
}
} while (mCursor.moveToNext());
in table you will have the rows as an ArrayList from NameValuePairs
after, you can get a value from a row like
ArrayList<NameValuePair> row = table.get(0);
NameValuePair column = row.get(0);
String columnName = column.getName();
String columnValue = column.getValue();
You can make B an ArrayList of HashMaps and store the pairs in B. Put the keys in the map as you extract them from mCursor in the loop. If B must be a string, use JSON format.
It is not exactly clear what You wanna do. If I am understanding You problem the right way, You get a String like this
"Vname|Vdate|Vtime|Vcost|VmedicineVname|Vdate|Vtime|Vcost|Vmedicine"
but You want to have a single String for every row, like this:
String "Vname|Vdate|Vtime|Vcost|Vmedicine"
String "Vname|Vdate|Vtime|Vcost|Vmedicine"
If this is what You want, You can pass every Row to an ArrayList, and that ArrayList to an ArrayList, this looks similar to this:
private ArrayList<ArrayList<String>> doubleArray = new ArrayList<ArrayList<String>>();
and then when You get Your values from DB:
ArrayList<String> mArrayList = new ArrayList<String>();
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("_id")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("flag")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("HVID")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vname")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vdate")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vtime")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vcost")));
mArrayList.add(mCursor.getString(mCursor
.getColumnIndex("Vmedicine")));
doubleArray.add(mArrayList);
So You can get exactly one row as:
for(int i=0;i<doubleArray.size();i++){
String a = doubleArray.get(i)
// now pass the String wherever You want
}
but like I am said, I don´t know from Your explanation if this is what You want...
i got no idea why it return me nullpointerexception. I think is because the table don't have data. So, the data seem like did not add into database
this is my activity class.
private void createdata(){
String title[] = {"rancangan1", "rancangan2", "rancangan3", "rancangan4", "rancangan5"};
String date[] = {"isnin", "selasa", "rabu", "khamis", "jumaat"};
String time[] = {"17:00-18:00", "18:00-19:00", "17:00-18:00", "18:00-19:00", "19:00-20:00"};
String channel[] = {"astro ria", "astro ria", "astro ria", "astro ria", "astro ria"};
try{
for(int i = 0; i < title.length; i++){
ContentValues values = new ContentValues();
values.put(ImamShareData.DataContent.KEY_PROGRAM_TITLE, title[i]);
values.put(ImamShareData.DataContent.KEY_PROGRAM_DATE, date[i]);
values.put(ImamShareData.DataContent.KEY_PROGRAM_TIME, time[i]);
values.put(ImamShareData.DataContent.KEY_PROGRAM_CHANNEL, channel[i]);
cr.insert(ImamShareData.DataContent.PROGRAM_URI, values);
//Log.i(TAG, "Successfully added index " + i + " as ID " + mId[i]);
}
}catch(Exception e){
Log.v("error",""+e);
}
}
private void filldata(){
String[] from = new String[]{ImamShareData.DataContent.KEY_PROGRAM_DATE, ImamShareData.DataContent.KEY_PROGRAM_TIME, ImamShareData.DataContent.KEY_PROGRAM_CHANNEL};
String[] from1 = new String[]{ImamShareData.DataContent.KEY_PROGRAM_TITLE};
int[] to = new int[]{R.id.programdate, R.id.programtime, R.id.programchannel};
int[] to1 = new int[]{R.id.programtitle};
SimpleExpandableListAdapter SEL = new SimpleExpandableListAdapter(this,
createGroupList(), R.layout.programgroup_row, from1, to1,
createChildList(), R.layout.programchild_row, from, to);
setListAdapter( SEL );
}
private List createGroupList() {
String[] column = new String[]{ImamShareData.DataContent.KEY_PROGRAM_TITLE};
ArrayList result = new ArrayList();
String title[] = null;
for( int i = 1 ; i <= 5; ++i ) {
Cursor cursor = managedQuery(ImamShareData.DataContent.PROGRAM_URI, column, null, null, null);
HashMap m = new HashMap();
title[i] = cursor.getColumnName(cursor.getColumnIndex(ImamShareData.DataContent.KEY_PROGRAM_TITLE));
m.put(ImamShareData.DataContent.KEY_PROGRAM_TITLE, title[i]);
result.add( m );
}
return result;
}
private List createChildList() {
String date;
String time;
String channel;
String[] column = new String[]{ImamShareData.DataContent.KEY_PROGRAM_DATE, ImamShareData.DataContent.KEY_PROGRAM_TIME, ImamShareData.DataContent.KEY_PROGRAM_CHANNEL};
ArrayList result = new ArrayList();
for( int i = 1 ; i <= 5 ; ++i ) {
ArrayList secList = new ArrayList();
for( int n = 0 ; n < 3 ; n+=3 ) {
Cursor cursor = managedQuery(ImamShareData.DataContent.PROGRAM_URI, column, null, null, null);
HashMap child = new HashMap();
date = cursor.getColumnName(cursor.getColumnIndex(ImamShareData.DataContent.KEY_PROGRAM_DATE));
time = cursor.getColumnName(cursor.getColumnIndex(ImamShareData.DataContent.KEY_PROGRAM_TIME));
channel = cursor.getColumnName(cursor.getColumnIndex(ImamShareData.DataContent.KEY_PROGRAM_CHANNEL));
child.put(ImamShareData.DataContent.KEY_PROGRAM_DATE, date);
child.put(ImamShareData.DataContent.KEY_PROGRAM_TIME, time);
child.put(ImamShareData.DataContent.KEY_PROGRAM_CHANNEL, channel);
secList.add( child );
}
result.add( secList );
}
return result;
}
this is my contentprovider class
#Override
public Uri insert(Uri uri, ContentValues initialvalues) {
TableNumber = sUriMatcher.match(uri);
if( TableNumber != PROGRAM){
throw new IllegalArgumentException("Unknown URI " + uri);
}
ContentValues values;
if(initialvalues != null){
values = new ContentValues(initialvalues);
}else{
values = new ContentValues();
}
SQLiteDatabase mDb = mDbHelper.getWritableDatabase();
long rowId = mDb.insert(DatabaseHelper.TABLE_PROGRAM, null, values);
if(rowId > 0){
Uri programUri = ContentUris.withAppendedId(ImamShareData.DataContent.PROGRAM_URI, rowId);
getContext().getContentResolver().notifyChange(programUri, null);
return programUri;
}
throw new IllegalArgumentException("Failed to insert row into " + uri);
}
this is my datasharing class
public static final class DataContent implements BaseColumns{
public static final Uri PROGRAM_URI = Uri.parse("content://" + AUTHORITY + "/" + PROGRAMPATH);
public static final String CONTENT_MORE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.android.imammuda";
public static final String CONTENT_ONE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.android.imammuda";
public static final String KEY_PROGRAM_ID = "_id";
public static final String KEY_PROGRAM_TITLE = "ProgramTitle";
public static final String KEY_PROGRAM_DATE = "ProgramDate";
public static final String KEY_PROGRAM_TIME = "ProgramTime";
public static final String KEY_PROGRAM_CHANNEL = "ProgramChannel";
}
this is my logcat
05-12 16:05:46.024: ERROR/AndroidRuntime(5175): Caused by: java.lang.NullPointerException
05-12 16:05:46.024: ERROR/AndroidRuntime(5175): at com.android.imammuda.Program.createGroupList(Program.java:112)
05-12 16:05:46.024: ERROR/AndroidRuntime(5175): at com.android.imammuda.Program.filldata(Program.java:82)
You have not initialized your title variable in method createGroupList:
String title[] = null;
...
title[i] = cursor.getColumnName....
in the for loop the length is hard coded to maximum 5, so the easiest fix is:
String[] title = new String[5];