1

In my Android SMS app ,i can send and receive SMS. When i send SMS, i store a flag in Sqlite DB to indicate that this is sent SMS as follows on button Click :

protected void SendSMS() {
    SmsManager sms_manager = SmsManager.getDefault();
    message_body = et_chat.getText().toString();
    ArrayList<String> parts = sms_manager.divideMessage(message_body);
    sms_manager.sendMultipartTextMessage(contact_no, null, parts, null, null);
    flag = "1";
    manager.Insert_sms_data(time, contact_no, message_body,flag);
    msg+= "SMS to :" + contact_for_chat + " \n";
    msg += "having number:" + contact_no + " \n";
    msg += "as" +message_body + " \n";
    msg += "at"+ time + " \n";
    Toast.makeText(getApplicationContext(), ""+msg , Toast.LENGTH_LONG).show();

}

When SMS is received , i save flag as 0 as follows :

public class IncomingSMS extends BroadcastReceiver {

Context context;
DbManager DBmanager;
private long timestamp;
private String number;
private String body = "";
String msg="";
Cursor cursor;
String display_name;
String flag;

@Override
public void onReceive(Context context, Intent intent) {
    try {

        final Bundle bundle = intent.getExtras();


            if (bundle != null) {

                //—retrieve the SMS message received—
                Object messages[] = (Object[]) bundle.get("pdus");
                SmsMessage smsMessage[] = new SmsMessage[messages.length];

                for (int n = 0; n < messages.length; n++) {
                    smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
                    timestamp = smsMessage[n].getTimestampMillis();

                    number = smsMessage[n].getOriginatingAddress();
                    body += smsMessage[n].getDisplayMessageBody();
                    display_name = Util.getContactName(context, number);
                    DBmanager = new DbManager(context);
                    cursor = DBmanager.Return_All_Contacts();
                    String [] contactArr = showcontactsInfo(cursor);
                Toast.makeText(context, contactArr[0]+"", 3000).show();
                    if(contactArr.length==0)
                    {}
                    else{
                    for(int i= 0;i<=contactArr.length;i++)
                    {

                        abortBroadcast();

                            }
                    blockMessage(context);

                    }
                        }
                    }

                }
        catch (Exception e) {
            Log.e("SmsReceiver", "Exception smsReceiver" +e);

        }

            } // end for loop
        // bundle is null




    private String[] showcontactsInfo(Cursor cursor) {
        String[] contact = new String [cursor.getCount()];
        int i= 0;
        while(cursor.moveToNext()){
            contact[i] = cursor.getString(1);
            i++;
        }
        return contact;
    }
    private void blockMessage(Context context) {

        // instantiate DbMNager object to insert sms in database
        //formating receiving time:
        //SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-hh.mm.ss");

        SimpleDateFormat formatter = new SimpleDateFormat("EEEE, MMMM d  HH:mm:ss a");
        String formatedTime = formatter.format(timestamp);
        flag = "0";
        DBmanager= new DbManager(context);
        DBmanager.open();
        DBmanager.Insert_sms_data(formatedTime ,number,body,flag);
        DBmanager.close();
        msg+= "SMS from " + number + " \n";
        msg += body + " \n";
        msg += formatedTime + " \n";
        msg += flag + " \n";
        Log.i("SmsReceiver", "senderNum: "+ display_name + "; message: " + body);
        Toast.makeText(context,msg, Toast.LENGTH_LONG).show();
        //Toast.makeText(context, "New message received in Discrete", Toast.LENGTH_LONG).show();
    }    
}

Data is stored successfully in DB, After that i want to retreive it in ListView , if flag is 1(we have sent SMS) then background should be differnet, If flag is 0(we have received SMS) then background should be different. I am able to retreive "sent SMS" but not "Received SMS". Here is the code :

private MyListAdapter adapter;
ArrayList<String> item_id = new ArrayList<String>();
ArrayList<String> item_phone_num = new ArrayList<String>();
ArrayList<String> item_msg_body = new ArrayList<String>();
ArrayList<String> item_time = new ArrayList<String>();
ArrayList<String> item_flag = new ArrayList<String>();
ArrayList<String> items = new ArrayList<String>();
private Button btn_send;
DbManager manager;
Cursor Cursor;
ViewHolder holder12;
String contact_for_chat;
String contact_no;
String message_body = "";
Calendar c;
SimpleDateFormat sdf;
String time;
EditText et_chat;
String flag;
String msg = "";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);
    try{
    Bundle bundle = getIntent().getExtras();
    contact_for_chat = bundle.getString("contact_name");
    contact_for_chat = contact_for_chat.replace(" ", "");
    contact_no = Util.getContactNumber(contact_for_chat, ChatActivity.this);
    Toast.makeText(getApplicationContext(), contact_no, Toast.LENGTH_LONG).show();
    final ViewHolder holder = new ViewHolder();
    manager = new DbManager(this);
    Cursor = manager.Return_SMS(contact_no);
    showEvents(Cursor);

    c = Calendar.getInstance();
    sdf = new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
    time = sdf.format(c.getTime());
    //setActionBar();
    findViewsById();
    adapter = new MyListAdapter(this);
    adapter.notifyDataSetChanged();
    setListAdapter(adapter);

    btn_send = (Button) findViewById(R.id.button1);
    btn_send.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {

            SendSMS();
        }
    });
    }
    catch(Exception ex)
    {
        Log.e("ERROR", ex.toString());
    }
}

protected void SendSMS() {
    SmsManager sms_manager = SmsManager.getDefault();
    message_body = et_chat.getText().toString();
    ArrayList<String> parts = sms_manager.divideMessage(message_body);
    sms_manager.sendMultipartTextMessage(contact_no, null, parts, null, null);
    flag = "1";
    manager.Insert_sms_data(time, contact_no, message_body,flag);
    msg+= "SMS to :" + contact_for_chat + " \n";
    msg += "having number:" + contact_no + " \n";
    msg += "as" +message_body + " \n";
    msg += "at"+ time + " \n";
    Toast.makeText(getApplicationContext(), ""+msg , Toast.LENGTH_LONG).show();

}

private void setActionBar() {
    ActionBar mActionBar = getActionBar();
    mActionBar.setDisplayHomeAsUpEnabled(false);
    mActionBar.setDisplayShowTitleEnabled(false);
    LayoutInflater mInflater = LayoutInflater.from(this);
    View mCustomView = mInflater.inflate(R.layout.actionbar_chat, null);
    TextView tv_chat = (TextView)mCustomView.findViewById(R.id.title_text);
    tv_chat.setText(contact_for_chat);
    ColorDrawable colorDaawable = new ColorDrawable(Color.parseColor("#CFCFC4"));
    mActionBar.setBackgroundDrawable(colorDaawable);
    mActionBar.setLogo(R.drawable.ic_launcher);
    mActionBar.setDisplayHomeAsUpEnabled(true);
    mActionBar.setCustomView(mCustomView);
    mActionBar.setDisplayShowCustomEnabled(true);
}

private void findViewsById() {
    et_chat = (EditText)findViewById(R.id.et_chat);
    btn_send = (Button)findViewById(R.id.button1);
}

private void showEvents(Cursor cursor) {

    item_id = new ArrayList<String>(cursor.getCount());
    item_phone_num = new ArrayList<String>(cursor.getCount());
    item_msg_body = new ArrayList<String>(cursor.getCount());
    item_time = new ArrayList<String>(cursor.getCount());
    item_flag = new ArrayList<String>(cursor.getCount());
    int i=0;
    while (cursor.moveToNext()) {
        item_id.add(i+"");
        item_time.add(cursor.getString(1));
        item_msg_body.add(cursor.getString(3));
        item_phone_num.add(cursor.getString(2));
        item_flag.add(cursor.getString(4));
        i++;
    }

  }
public class MyListAdapter extends BaseAdapter {
    Context con;
    private LayoutInflater layoutinf;
    ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
    ArrayList<String> items_ = new ArrayList<String>();

    public MyListAdapter(ChatActivity context) {
        con = context;
    }

    public int getCount() {
        return item_id.size();
    }

    public Object getItem(int position) {
        return item_id.size();
    }

    public long getItemId(int position) {
        return item_id.get(position).hashCode();
    }

    public View getView(final int position, View arg1, ViewGroup arg2) {

        View v = arg1;
        ViewHolder holder = null;
        if (v == null) {
            layoutinf = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = layoutinf.inflate(R.layout.row_chat, null);
            holder = new ViewHolder();

            holder.tv_contact = (TextView) v.findViewById(R.id.phone_num);
            holder.tv_sms_body = (TextView) v.findViewById(R.id.msg_body);
            holder.tv_time = (TextView) v.findViewById(R.id.time);

            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }

        if(item_flag.get(position).equals("1"))
        {
            holder.tv_sms_body.setBackgroundResource(R.drawable.bubble_green);

        }
                    else
                    {
                        holder.tv_sms_body.setBackgroundResource(R.drawable.bubble_yellow);

                    }


        holder.tv_contact.setText("" + item_phone_num.get(position));


        holder.tv_sms_body.setText(item_msg_body.get(position));

        holder.tv_time.setText(item_time.get(position));

        return v;
    }
}

public class ViewHolder {

    private TextView tv_contact;
    private TextView tv_sms_body;
    private TextView tv_time;

}

DB cursor to retreive sms is as follows :

public Cursor Return_SMS(String contact_no)
    {       
        SQLiteDatabase db=this.getReadableDatabase();        
        String[] params=new String[]{contact_no};
        Cursor c=db.rawQuery("SELECT * FROM "+ "SMS_TABLE_RCV"+" WHERE "+ "Phone_number " +"=?",params);
        return c;
    }

I don't know whats wrong with my code and how can i retreive received and sent both sms but with different background. Any help will be appreciated .

user3381979
  • 75
  • 1
  • 2
  • 11

3 Answers3

1

I suggest you to use Loaders and Provider.

With them your view will update whenever a change is made to DB's data.

The first time is quite difficult, but then is easy and stable in all devices since API 10.

Little example: in onCreate Fragment extends ListFragment

   getActivity().getSupportLoaderManager().initLoader(MyProvider.LOADER_ID, null, this);

   mCursorAdapter = new SimpleCursorAdapter(
            getActivity(),
            R.layout.my_row_layout,
            null,
            new String[]{"DBcolumnName1", "DBcolumnName2"},
            new int[]{
                    R.id.my_textView,
                    R.id.my_textView2},
            SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); //get update

    DocumentoCursorAdapter adapter = new DocumentoCursorAdapter(getActivity());

    mCursorAdapter.setViewBinder(adapter);

Then the fragment must implements LoaderManager.LoaderCallbacks<Cursor> and implement the interface:

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    String condition = null;
    String[] args = null;
    if (bundle!=null) {
        final String search = bundle.getString(BUNDLE_SEARCH);

        condition = DbMapping.myColumn1.name() + " LIKE ? OR " +
                DbMapping.myColumn2.name() + " LIKE ?";
        args = new String[]{'%'+search+'%', '%'+search+'%'};
    }

    return new CursorLoader(
            getActivity().getApplicationContext(),
            MyProvider.CONTENT_URI,
            new String[]{"DBcolumnName1", "DBcolumnName2"}, // selectable columns
            condition,
            args,
            DbMapping.myColumn1.name() + " DESC");
}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
    switch (cursorLoader.getId()) {
        case MyProvider.LOADER_ID:
            mCursorAdapter.swapCursor(cursor);
            break;
    }
}

@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
    mCursorAdapter.swapCursor(null);
}

In the end you have to write your Data Provider

public class MyProvider extends ContentProvider {...}

and override some method like this:

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    final int uriType = sURIMatcher.match(uri);
    Log.d(TAG, "Richiesto UPDATE "+ selectionArgs[0]);

    SQLiteDatabase sqlDB = mDbHelper.getWritableDatabase();
    int updated;
    switch (uriType) {
        case INDICATOR_UPDATE_DOCUMENTO:
            updated = sqlDB.update(DbMapping.MY_TABLE_NAME,
                    values,
                    DbMapping._id.name() +"= ?",
                    selectionArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
    }
    if (updated>=0) {
        getContext().getContentResolver().notifyChange(uri, null);
    }

    return updated;
}

and the magic is this line getContext().getContentResolver().notifyChange(uri, null); that notify to the loader to update the view.

So you must update olny the db and the view will automatically updated!!

With this pattern (loader and dataprovider) you'll never have db exception access and you'll never have to write extra code for update the view!

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73
0

For this kind of View of sms in android..

enter image description here

you need to make changes in you code like

you can add where clause in your Return_all() function of your sqllite database code. Pass the value of where when you call return_all().

Like

public Cursor Return_All(Arraylist Where){

SQLiteDatabase db = this.getReadableDatabase();
String query= "where ";
For(int i=0;i<where.size;i++)
{
     query=query+"contact = "+where[i]+ " or "; }

Cursor cur = db.rawQuery("SELECT * FROM "+"SMS_TABLE_RCV" + query , null); return cur; }

or else try these for reference..

1.android Custom list veiw

2.Create Custom Listview

3.Customize list view

follow these references and use them for SQLite...

Whats Going On
  • 1,379
  • 6
  • 20
  • 49
0

I have tried a lot and finally get the issue and solution of it. Actually problem was there in the changed pattern of sender's Number. You can notice that when you save number in emulator, its is save like 1 555-521-5556 and when receive sms then 15555215556 so that was the basic issue. you have to deal with it or use contact name directly to get rid of this solution.

user3381979
  • 75
  • 1
  • 2
  • 11