How read a sms from android - android

I try to make a simple app for read sms from my smartphone,
I run the code but and but anythings shows in my application
I try to debug the code I found this variable cur cannot be found
what is the problem here ?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private static final int request_permission = 123;
#RequiresApi(api = Build.VERSION_CODES.M)
public void ButtonLoad(View view) {
if((int) Build.VERSION.SDK_INT >=23){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)!= PackageManager.PERMISSION_GRANTED){
if(!shouldShowRequestPermissionRationale(Manifest.permission.READ_SMS)){
requestPermissions( new String[]{Manifest.permission.READ_SMS},request_permission);
}
return;
}
}
LoadInboxMassges();
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode){
case request_permission:
if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
LoadInboxMassges();
}else {
//permission_Denied
}
}
}
void LoadInboxMassges(){
try {
String sms = "";
Uri uriSMSURI = Uri.parse("content://sms/inbox");
Cursor cur = getContentResolver().query(uriSMSURI, null,null, null, null);
cur.moveToPosition(0);
while (cur.moveToNext()) {
sms += "From : " + cur.getString(cur.getColumnIndex("adress")) + " : " + cur.getString(cur.getColumnIndex("body")) + "\n";
TextView txtDisplay = (TextView) findViewById(R.id.txtv);
txtDisplay.setText(sms);
}
}catch (Exception ex)
{
}
}

1 remove this line cur.moveToPosition(0);
2 Change the word "adress" of this line:
sms += "From : " + cur.getString(cur.getColumnIndex("adress")) + " : " + cur.getString(cur.getColumnIndex("body")) + "\n";
to "address".
Other suggestions:
There are some other errors or something improper in your code, such as:
1 Reading sms in your inbox may spend a long time. That may crash your app.
2 Your txtDisplay should be placed out of the loop body.
3 You should call cur.close(); after cur is in the end.

In your LoadInboxMassges() method
remove the code cur.moveToPosition(0);
change in the following manner
if (cursor != null) {
while (cursor.moveToNext()) {
// read your cursor here
}

Related

How can I reach contacts when I have taken permission?

I am writing an application to Google Play. I have to take permission from user because İf I don"t my app will be shut down. My purpose is first time user start my app. I want to take Contacts permission from him/her then load her/his contacts to customized listview. But When I want permission from users, My contacts are not loading to my customized Listview. How can I fix it?
Here my permission is in xml file
<uses-permission android:name="android.permission.READ_CONTACTS"
/>
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
My request Permissions method:
if (ContextCompat
.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_CONTACTS) != (int) PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE)
!= (int)PackageManager.PERMISSION_GRANTED) {
// Check if user has opted "Never show again"
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_CONTACTS) ||
ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CALL_PHONE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[] {
Manifest.permission.READ_CONTACTS,
Manifest.permission.CALL_PHONE
}, requestCode);
}
}
} else {
getNumber(this.getContentResolver()); // it is taking method of contacts
}
chosinglist = (ListView) findViewById(R.id.chosing);
chosinglist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
GetNumber methods:
private void getNumber(ContentResolver contentResolver) {
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cursor.moveToFirst()) {
// ArrayList<String> alContacts = new ArrayList<String>();
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 = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
while (pCur.moveToNext()) {
String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String name = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
listte.add(name);
listtearama.add(phoneNumber);
// alContacts.add(contactNumber);
break;
}
pCur.close();
}
} while (cursor.moveToNext());
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.checkrow,
R.id.checkedTextView2, listte);
kaydet.setEnabled(false);
chosinglist.setAdapter(adapter); }
I think you are initializing ListView after fetching the contacts
Try this:
chosinglist = (ListView) findViewById(R.id.chosing);
chosinglist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
if (permissionNotGranted)
{
}
else
{
getNumber(this.getContentResolver()); // it is taking method of contacts
}
Please try this:
if (ContextCompat
.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_CONTACTS) != (int) PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE)
!= (int)PackageManager.PERMISSION_GRANTED) {
// Check if user has opted "Never show again"
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_CONTACTS) ||
ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CALL_PHONE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[] {
Manifest.permission.READ_CONTACTS,
Manifest.permission.CALL_PHONE
}, requestCode);
}else{
getContactDetails();
}
}
} else {
getContactDetails(); // it is taking method of contacts
}
public void getContactDetails() {
ContentResolver cr = getActivity().getContentResolver();
String[] PROJECTION = new String[]{ContactsContract.RawContacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID,
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.RawContacts.VERSION};
String order = "CASE WHEN "
+ ContactsContract.Contacts.DISPLAY_NAME
+ " NOT LIKE '%#%' THEN 1 ELSE 2 END, "
+ ContactsContract.Contacts.DISPLAY_NAME
+ ", "
+ ContactsContract.CommonDataKinds.Phone.DATA
+ " COLLATE NOCASE";
String filter = ""+ ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 and " + ContactsContract.CommonDataKinds.Phone.TYPE +"=" + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
Cursor cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, filter, null, order);
for (int i = 0; i < cur.getColumnCount(); i++) {
Timber.e("column " + i + "=" + cur.getColumnName(i));
}
if (cur.moveToFirst()) {
do {
String name = cur.getString(1);
String number = cur.getString(4);
number = Utils.removeExtraCharFromString(number);
if (number.length() > 8) {
mContactNumbers = mContactNumbers + number + ",";
PhoneContacts phoneContacts = new PhoneContacts();
try {
phoneContacts.setName(URLEncoder.encode(name, "UTF-8"));
phoneContacts.setNumber(number);
phoneContacts.setNameInitial(String.valueOf(phoneContacts.getName().charAt(0)));
listOfContactsRaw.add(phoneContacts);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
} while (cur.moveToNext());
}
cur.close();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Set set = new TreeSet(new Comparator() {
#Override
public int compare(Object o1, Object o2) {
PhoneContacts phoneContacts1 = (PhoneContacts) o1;
PhoneContacts phoneContacts2 = (PhoneContacts) o2;
if (phoneContacts1.getNumber().equalsIgnoreCase(phoneContacts2.getNumber())) {
return 0;
}
return 1;
}
});
set.addAll(listOfContactsRaw);
System.out.println("\n***** After removing duplicates *******\n");
listOfContacts = new ArrayList(set);
initRecyclerView();
}
}, 200);
}

using sqlite in BroadcastReceiver

I want perform a easy task in android, which when receiving a call the phonenumber will be matched to a number in my database. However I already read that sqlite and BroadcastReceiver are not that easy to combine. Below is the code:
public class incomingcall extends BroadcastReceiver{
String caller;
Cursor c;
#Override
public void onReceive(Context context, Intent intent) {
sqlitedatabase search = new sqlitedatabase(context);
Bundle bundle = intent.getExtras();
if(null == bundle)
return;
Log.i("IncomingCallReceiver",bundle.toString());
String state = bundle.getString(TelephonyManager.EXTRA_STATE);
Log.i("IncomingCallReceiver","State: "+ state);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))
{
String phonenumber = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.i("IncomingCallReceiver","Incomng Number: " + phonenumber);
try{
search.open();
c = search.callinfo(phonenumber);
if(c != null){
int iFN = c.getColumnIndex("firstname");
int iLN = c.getColumnIndex("lastname");
String FN = c.getString(iFN);
String LN = c.getString(iLN);
caller = FN + " " + LN;
}
else{
caller = "Unknown";
}
search.close();
}
catch (Exception e){
Toast.makeText(context, "error"+e.toString(), Toast.LENGTH_LONG).show();
}
Toast.makeText(context, caller, Toast.LENGTH_LONG).show();
}
}
}
I don't think the problem lies with the methode ".callinfo()", nonetheless I posted it below:
public Cursor callinfo(String l) {
// TODO Auto-generated method stub
String[] columns = new String[]{"phonenumber", "homenumber"};
Cursor c = db.query("mycontacts", columns, "phonenumber = " + l + " OR " + "homenumber = " + l, null, null, null, null);
return c;
}
The Catch returns : errorandroid.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1.
Thank you in advance for any help you can give me.
Cheers
Because the initial cursor position is -1, try to use if(c.moveToNext()) instead of if(c != null).

Get the Email from Contacts using AutoComplete TextView?

In my application i've one AutoComplete TextView and EditText In this AutoComplete TextView provides all the contact names from Contacts.
I want to get the primary email id which contact was selected in my AutoComplete Textview to the editText. How can i achieve this? Anyone guide me?
public class Contact extends Activity {
/** Called when the activity is first created. */
private static final int CONTACT_PICKER_RESULT = 10;
private static final String DEBUG_TAG = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void doLaunchContactPicker(View view) {
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
startActivityForResult(contactPickerIntent, CONTACT_PICKER_RESULT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CONTACT_PICKER_RESULT:
Cursor cursor = null;
String email = "";
try {
Uri result = data.getData();
Log.v(DEBUG_TAG, "Got a contact result: "
+ result.toString());
// get the contact id from the Uri
String id = result.getLastPathSegment();
// query for everything email
cursor = getContentResolver().query(Email.CONTENT_URI, null, Email.CONTACT_ID + "=?", new String[] { id }, null);
int emailIdx = cursor.getColumnIndex(Email.DATA);
// let's just get the first email
if (cursor.moveToFirst()) {
email = cursor.getString(emailIdx);
Log.v(DEBUG_TAG, "Got email: " + email);
} else {
Log.w(DEBUG_TAG, "No results");
}
} catch (Exception e) {
Log.e(DEBUG_TAG, "Failed to get email data", e);
} finally {
if (cursor != null) {
cursor.close();
}
EditText emailEntry = (EditText) findViewById(R.id.invite_email);
emailEntry.setText(email);
if (email.length() == 0) {
Toast.makeText(this, "No email found for contact.",
Toast.LENGTH_LONG).show();
}
}
break;
}
} else {
Log.w(DEBUG_TAG, "Warning: activity result not ok");
}
}
}
Make sure you have READ_CONTACTS permission for your App.
AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
Cursor emailCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, null, null, null);
startManagingCursor(emailCursor);
autoCompleteTextView.setAdapter(new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, emailCursor, new String[] {Email.DATA1}, new int[] {android.R.id.text1}));
autoCompleteTextView.setThreshold(0);
Please Note AutoCompleteTextView is Case Sensitive.

Delete call from call log after call end

I am new to Android development. I want to make a call to a number but I don't want to store the number in my Call log. How can I delete the number from call log after the call ends?
First you have to set up a broadcast receiver to detect the phone state. Here's the exact same question: Stackoverflow - Intent to be fired when a call ends?
And now for deleting the call log entry, here is the first link on google: Call log deletion in Android
In the example he deletes all call entry for a specific number, but you can change the query to delete the entry for a specific call log id.
Hope this helps.
Cheers
Im using 4.2.2 anyway i had to modify the aftab's code as it was not working for me. It could be a asych issue giving what i was trying to do is update the call log right after an incoming call is ended. I think i have to give O/S enough time to update the table before i delete the entry or it wont exist :
private void deleteNumber(String phoneNumber) {
try {
Thread.sleep(4000);
String strNumberOne[] = { phoneNumber };
Cursor cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, null,
CallLog.Calls.NUMBER + " = ? ", strNumberOne, "");
boolean bol = cursor.moveToFirst();
if (bol) {
do {
int idOfRowToDelete = cursor.getInt(cursor
.getColumnIndex(CallLog.Calls._ID));
context.getContentResolver().delete(
CallLog.Calls.CONTENT_URI,
CallLog.Calls._ID + "= ? ",
new String[] { String.valueOf(idOfRowToDelete) });
} while (cursor.moveToNext());
}
} catch (Exception ex) {
Log.v("deleteNumber",
"Exception, unable to remove # from call log: "
+ ex.toString());
}
}
and to call the function i run on another thread (since im sleeping) :
new Thread() {
public void run() {
deleteNumber(incomingNumber);
}
}.start();
after adding the sleep it seems to work when trying to delete right after a call is ended.
UPDATE: after last comment realized we can set up a contentobserver on the android provider call log uri:
public class BlockerContentObserver extends ContentObserver{
private Context context;
private String phoneNumber;
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public BlockerContentObserver(Handler handler,Context context) {
super(handler);
this.context=context;
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
super.onChange(selfChange);
Log.v(Consts.TAG,"has call log changed:"+selfChange);
deleteNumber(phoneNumber);
}
private void deleteNumber(String phoneNumber) {
try {
String strNumberOne[] = { phoneNumber };
Cursor cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, null,
CallLog.Calls.NUMBER + " = ? ", strNumberOne, "");
boolean bol = cursor.moveToFirst();
if (bol) {
do {
int idOfRowToDelete = cursor.getInt(cursor
.getColumnIndex(CallLog.Calls._ID));
context.getContentResolver().delete(
CallLog.Calls.CONTENT_URI,
CallLog.Calls._ID + "= ? ",
new String[] { String.valueOf(idOfRowToDelete) });
} while (cursor.moveToNext());
}
} catch (Exception ex) {
Log.v(Consts.TAG,
"Exception, unable to remove # from call log: "
+ ex.toString());
}
}
}
Now we register to listen to changes in the call log DB using this:
mContentObserver = new BlockerContentObserver(new Handler(), context);
then we make a method to either register for events or unreigster:
/*handles the registration of our content observer used for monitoring the call log*/
private void RegisterContentObserver(boolean shouldRegister){
if(shouldRegister)
{
context.getContentResolver().registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI,
true,
mContentObserver);
}
else {
try {
context.getContentResolver().unregisterContentObserver(mContentObserver);
} catch (IllegalStateException ise) {
// Do Nothing. Observer has already been unregistered.
}
}
}
I just try this method its working great on my HTC with 4.0.3
private void deleteNumber() {
try {
String strNumberOne[] = { "00577698160" };
Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, CallLog.Calls.NUMBER + " = ? ", strNumberOne, "");
boolean bol = cursor.moveToFirst();
if (bol) {
do {
int idOfRowToDelete = cursor.getInt(cursor.getColumnIndex(CallLog.Calls._ID));
getContentResolver().delete(Uri.withAppendedPath(CallLog.Calls.CONTENT_URI, String.valueOf(idOfRowToDelete)), "", null);
} while (cursor.moveToNext());
}
} catch (Exception ex) {
System.out.print("Exception here ");
}
}
modified version of earlier answsers. you don't really need a while loop. Also you don't need Thread.sleep(4000), register a ContentObserver for CallLog.Calls.CONTENT_URI and call the following method in onChange. but just before calling that make sure you unregister that ContentObserver
public static void deleteLastCallLog(Context context, String phoneNumber) {
try {
//Thread.sleep(4000);
String strNumberOne[] = { phoneNumber };
Cursor cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, null,
CallLog.Calls.NUMBER + " = ? ", strNumberOne, CallLog.Calls.DATE + " DESC");
if (cursor.moveToFirst()) {
int idOfRowToDelete = cursor.getInt(cursor.getColumnIndex(CallLog.Calls._ID));
int foo = context.getContentResolver().delete(
CallLog.Calls.CONTENT_URI,
CallLog.Calls._ID + " = ? ",
new String[] { String.valueOf(idOfRowToDelete) });
}
} catch (Exception ex) {
Log.v("deleteNumber",
"Exception, unable to remove # from call log: "
+ ex.toString());
}
}

Android Contact list getting phone number

hi i am trying this code in my app i can get the contact list but when i press on contact name i didnt get any thing in my edittext which i expected to get the contact phone number
sorry about my poor english
public void doLaunchContactPicker(View view) {
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,
Contacts.CONTENT_URI);
startActivityForResult(contactPickerIntent, CONTACT_PICKER_RESULT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode=RESULT_OK) {
case CONTACT_PICKER_RESULT:
Cursor cursor = null;
String phone = "";
try {
Bundle extras = data.getExtras();
Set<String> keys = extras.keySet();
Iterator<String> iterate = keys.iterator();
while (iterate.hasNext()) {
String key = iterate.next();
Log.v(DEBUG_TAG, key + "[" + extras.get(key) + "]");
}
Uri result = data.getData();
Log.v(DEBUG_TAG, "Got a contact result: "
+ result.toString());
// get the contact id from the Uri
String id = result.getLastPathSegment();
cursor = getContentResolver().query(Phone.CONTENT_URI,
null, Phone.CONTACT_ID + "=?", new String[] { id },
null);
int PhoneIdx = cursor.getColumnIndex(Phone.DATA);
if (cursor.moveToFirst()) {
phone = cursor.getString(PhoneIdx);
Log.v(DEBUG_TAG, "Got number: " + phone);
} else {
Log.w(DEBUG_TAG, "No results");
}
} catch (Exception e) {
Log.e(DEBUG_TAG, "Failed to Number", e);
} finally {
if (cursor != null) {
cursor.close();
}
EditText ponenumber = (EditText) findViewById(R.id.ednum);
ponenumber.setText(phone);
if (phone.length() == 0) {
Toast.makeText(this, "No number found for contact.",
Toast.LENGTH_LONG).show();
}
}
break;
}
} else {
Log.w(DEBUG_TAG, "Warning: activity result not ok");
}
}
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String Name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
String Number=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
You're actually really close- A few things.
Your switch statement is basing off of the resultCode, not the request code. Change that- It should read "switch(requestCode)"
Phone.DATA will work, but use Phone.NUMBER instead for readability sake:)
Make sure you have the permission for android.permission.READ_CONTACTS set in your AndroidManifest.xml file, as an element inside the manifest element, but not in the application element. The line should should look like this.
<uses-permission android:name="android.permission.READ_CONTACTS" />
I made those modifications to your sample, and got working code.
you can change you code that you want get phone number,as the following
List numberList = new ArrayList();
Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,contactId);
Uri targetUri = Uri.withAppendedPath(baseUri,Contacts.Data.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(targetUri,
new String[] {Phone.NUMBER},Data.MIMETYPE+"='"+Phone.CONTENT_ITEM_TYPE+"'",null, null);
startManagingCursor(cursor);
while(cursor.moveToNext()){
numberList.add(cursor.getString(0));
}
cursor.close();
It is an old post but it could help someone.
If you just have to Pick-up a contact, you can use the first code of the post without this part:
Bundle extras = data.getExtras();
Set<String> keys = extras.keySet();
Iterator<String> iterate = keys.iterator();
while (iterate.hasNext()) {
String key = iterate.next();
Log.v(DEBUG_TAG, key + "[" + extras.get(key) + "]");
}

Categories

Resources