This is the code i am using to read the inbox message when view button is pressed in context menu but i am unable to read messages i get only the body of the first message.
public class Smsread extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView view = new TextView(this);
Uri uri = Uri.parse("content://sms/inbox");
Cursor c= getContentResolver().query(uri, null, null ,null,null);
startManagingCursor(c);
String sms = "";
if(c.moveToFirst()){
for(int i=0;i<c.getCount();i++){
sms= c.getString(c.getColumnIndexOrThrow("body")).toString();
// sms=c.getString(c.getColumnIndexOrThrow("address")).toString();
}
c.close();
c.moveToNext();
/*
sms ="From :" + c.getString(2) + " : " + c.getString(11)+"\n";
*/
}
view.setText(sms);
setContentView(view);
}
}
Try this:
if(c.moveToFirst()){
for(int i=0;i<c.getCount();i++){
sms= c.getString(c.getColumnIndexOrThrow("body")).toString();
c.moveToNext();
}
}
You will have to move to next record for each iteration of for loop.then only,you will get all messages there.Here,in for loop,after you get String sms,you can use that sms to show up somewhere.Each time,it will grab next sms into it!
Hope you got the point!
You must change
sms= c.getString(c.getColumnIndexOrThrow("body")).toString();
to
sms+= c.getString(c.getColumnIndexOrThrow("body")).toString();
Try this:
String[] sms=new String[c.getCount()];
if(c.moveToFirst()){
do{
sms= c.getString(c.getColumnIndexOrThrow("body")).toString();
} while(c.moveToNext());
}
Related
Am trying to use the ContactsProvider with my AutoCompleteTextview using a method that fetches the data (name and phone number) and stores them in a list. As expected, this method will always take time to complete as am calling the method in the onCreateView method of my Fragment class.
This is the method:
...
ArrayList<String> phoneValues;
ArrayList<String> nameValues;
...
private void readContactData() {
try {
/*********** Reading Contacts Name And Number **********/
String phoneNumber = "";
ContentResolver contentResolver = getActivity()
.getContentResolver();
//Query to get contact name
Cursor cursor = contentResolver
.query(ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
null);
// If data data found in contacts
if (cursor.getCount() > 0) {
int k=0;
String name = "";
while (cursor.moveToNext())
{
String id = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
name = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
//Check contact have phone number
if (Integer
.parseInt(cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
//Create query to get phone number by contact id
Cursor pCur = contentResolver
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?",
new String[] { id },
null);
int j=0;
while (pCur
.moveToNext())
{
// Sometimes get multiple data
if(j==0)
{
// Get Phone number
phoneNumber =""+pCur.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Add contacts names to adapter
autocompleteAdapter.add(name);
// Add ArrayList names to adapter
phoneValues.add(phoneNumber.toString());
nameValues.add(name.toString());
j++;
k++;
}
} // End while loop
pCur.close();
} // End if
} // End while loop
} // End Cursor value check
cursor.close();
} catch (Exception e) {
Log.i("AutocompleteContacts","Exception : "+ e);
}
}
Am sure there is a better way to accomplish this, but this method works and the suggestions are presented when I type into the AutocompleteTextview. Am just worried about the time it takes. How can I accomplish this without populating an ArrayList?
I have looked at this question: Getting name and email from contact list is very slow and applied the suggestions in the answer to my code, but now nothing is suggested when I type.How can I improve the performance of my current code?
This is how i have implemented AutoCompleteTextView and it works fine for me ..
final AutoCompleteTextView act=(AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
ArrayList<String> alContacts = new ArrayList<String>();
ArrayList<String> alNames= new ArrayList<String>();
ContentResolver cr = this.getContentResolver(); //Activity/Application android.content.Context
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.moveToFirst())
{
do
{
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
if(Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",new String[]{ id }, null);
while (pCur.moveToNext())
{
String contactNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactName=pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
alNames.add(contactName);
alContacts.add(contactNumber);
break;
}
pCur.close();
}
} while (cursor.moveToNext()) ;
}
String[] array=new String[alNames.size()];
array=(String[]) alNames.toArray(array);
ArrayAdapter<String> myArr= new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,array);
act.setAdapter(myArr);
act.setThreshold(1);
I got rid of the slow response by placing the method inside an AsynTask.
public class AutocompleteAsyncTask extends AsyncTask<Void, Void, Void> {
public Void doInBackground(Void...params) {
try {
/*********** Reading Contacts Name And Number **********/
String phoneNumber = "";
ContentResolver contentResolver = getActivity()
.getContentResolver();
//Query to get contact name
Cursor cursor = contentResolver
.query(ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
null);
// If data data found in contacts
if (cursor.getCount() > 0) {
int k=0;
String name = "";
while (cursor.moveToNext())
{
//...Rest of the same code as above
and then calling this in my onCreateView():
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
new AutocompleteAsyncTask().execute();
return rootView;
}
Now the task of inflating my view and fetching the data are separated into two different threads.
The CursorLoader option mentioned by Eugen Pechanec is kinda the best option, so I'll update this answer with that option when I can.
Using the code below i wrote in TextView "textStareLed" first unreaded message. How can write the last message?
I try to use the cursor.moveToPrevious() but didn`t work.
protected void AfisareStareLed() {
TextView view = new TextView(this);
Uri uriSMSURI = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uriSMSURI, null, null, null, null)
while (cursor.moveToNext()){
if(cursor.getString(2).equals("+4xxxxx") && cursor.getString(8).equals("0")){//cursor.getString(8)==0 <=> "read=0"
TextView textStareLed = (TextView) findViewById(R.id.textStareLed);
textStareLed.setText(cursor.getString(13));
}
}
markMessageRead();//mark all message "read=1"
}
Just add "date desc limit 1"
String msgData = "";
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), new String[] {"body"}, null ,null, "date desc limit 1"); //if you change the 1 to 2 you´ll get the last 2 sms...
cursor.moveToFirst();
do{
for(int idx=0;idx<cursor.getColumnCount();idx++)
{
msgData += cursor.getString(idx);
}
}while(cursor.moveToNext());
textStareLed.setText(msgData);
I wanna delete ALL the messages in my Messaging with just one click on the button. But I already tried the coding below, it is not working... Can someone just help me to achieve this? Thanks...
public class DeleteSMSActivity extends Activity implements OnClickListener{
/** Called when the activity is first created. */
Button press;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
press = (Button)findViewById(R.id.button1);
press.setOnClickListener(this);
}
public void onClick(View view){
ContentResolver cr = getContentResolver();
Uri inboxUri = Uri.parse("content://sms/inbox");
Cursor c = cr.query(inboxUri , null, null, null, null);
while (c.moveToNext()) {
// Delete the SMS
String pid = c.getString(0); // Get id;
String uri = "content://sms/" + pid;
cr.delete(Uri.parse(uri), null, null);
}
}
}
What should I add in Manifest? Having force close when testing with my Galaxy Tab 2
Try deleting with _id :
Cursor c = getApplicationContext().getContentResolver().query(Uri.parse("content://sms/"), null, null, null,null);
try {
while (c.moveToNext()) {
int id = c.getInt(0);
getApplicationContext().getContentResolver().delete(Uri.parse("content://sms/" + id), null, null);
}
}catch(Exception e){
Log.e(this.toString(),"Error deleting sms",e);
}finally {
c.close();
}
The delete uri is "content://sms/" + id;
Uri inboxUri = Uri.parse("content://sms/inbox");
int count = 0;
Cursor c = context.getContentResolver().query(inboxUri , null, null, null, null);
while (c.moveToNext()) {
try {
// Delete the SMS
String pid = c.getString(0); // Get id;
String uri = "content://sms/" + pid;
count = context.getContentResolver().delete(Uri.parse(uri),
null, null);
} catch (Exception e) {
}
}
return count;
you can Also Refere HERE & HERE for More Detail Information About this topic.
Hope it Will Help you.
for Deleting SMS from inbox you need uses permission declared in your manifest
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
now you will be able to delete your inbox sms and now you wont get the force close your emulator
Today I found the way to delete all messages without loop, just by query.
mContext.getContentResolver().delete(Uri.parse("content://sms/"), null, null);
Follow this link for more detail
http://www.wisdomitsol.com/blog/android/sms/programmatically-delete-all-messages-in-android
I am using 2.1 platform.Trying to retrieve all the SMS from the Emulator. No Compile error, NO Logcat Error in my code.I included the permission for ReadSMS in manifest file.When I run the code no display in the ListView. In my XML file there is only one ListView. On that ListView I am trying to display all the SMS of format ( Number : Sms Body) from the Emulator.
Code
public class SMSActivity extends Activity {
/** Called when the activity is first created. */
ListView lview;
String Body = "" ;
int Number;
ArrayList<String> smslist=new ArrayList<String>();
ArrayAdapter<String> itemAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lview =(ListView)findViewById(R.id.lv);
itemAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,smslist);
lview.setAdapter(itemAdapter);
ContentResolver cr = getContentResolver();
Cursor c = cr.query(Uri.parse("content://sms/"), new String[] { "_id", "address", "date", "body","read" },"_id = "+null, null, null);
while(c.moveToNext()){
Number = c.getInt(c.getColumnIndexOrThrow("address"));
Body = c.getString(c.getColumnIndexOrThrow("body")).toString();
smslist.add( Number + "\n" + Body);
}
itemAdapter.notifyDataSetChanged();
c.close();
}
}
How to solve this problem ?
The error you are doing is you just mentioning that you want to read sms but you forgot to say
from which folder you need them.e.g from inbox,outbox etc..
If you need to read SMS from inbox use following.
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
You can also query column names using
for (int i = 0; i < cursor.getColumnCount(); i++) {
Log.i("info", cursor.getColumnName(i));
}
How can I search the sms inbox and show latest message from a special number. For example search for "999999999" and show last message received from this number. Is any way to do this?
I have use this code to return the count of messages my inbox
TextView view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view = (TextView) findViewById(R.id.textView1);
final Uri SMS_INBOX = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(SMS_INBOX, null, null, null, null);
int unreadMessagesCount = c.getCount();
c.deactivate();
view.setText(String.valueOf(unreadMessagesCount));
If you only want the last message sent by a specific number use this:
final Uri SMS_INBOX = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(SMS_INBOX, null, "address = ?",
new String[] {"9999999999"}, "date desc limit 1");
if(cursor.moveToFirst()) {
// Do something
Log.v("Example", cursor.getString(cursor.getColumnIndex("body")));
}
cursor.close();
The second answer to How many database columns associated with a SMS in android? is a great reference for different columns in an SMS.
try as:
final Uri SMS_INBOX = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(SMS_INBOX,null,null, null,"DATE desc");
if(c.moveToFirst()){
for(int i=0;i<c.getCount();i++){
String body= c.getString(c.getColumnIndexOrThrow("body")).toString();
String number=c.getString(c.getColumnIndexOrThrow("address")).toString();
if(number=="999999999")
{
//get message body here
break;
}
else
c.moveToNext();
}
}
c.close();