I'm trying to do an app that can send to a web service the phone numbers (and the contact name only if it is already registered) from incoming calls, so I found this question here, and I implemented the answer as the follow way:
public class PhoneStateReceiver extends BroadcastReceiver {
public String phoneNumber;
public String contactName;
ShareUuid su = new ShareUuid();
String uuid;
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving an Intent broadcast.
//throw new UnsupportedOperationException("Not yet implemented");
Bundle extras = intent.getExtras();
if (extras != null) {
if (extras.getString("state").equals(TelephonyManager.EXTRA_STATE_RINGING)) {
phoneNumber = extras.getString("incoming_number");
Log.e("PhoneNumber", "onReceive: "+phoneNumber);
String nombre_prueba = contactExists(context, phoneNumber);
Log.e("nombre_prueba", nombre_prueba);
uuid = su.getUuid();
Log.e("UUID - PhoneStateReceiver", uuid);
Uri uri = Uri.withAppendedPath(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI,Uri.encode(phoneNumber));
Cursor rCursor = context.getContentResolver().query(uri,
new String[] {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID},
null,null,null);
String nombre = rCursor.getString(0);
//new SendData(uuid, phoneNumber, nombre).execute();
Log.e("rCursor", nombre);
}
}
}
public String contactExists(Context context, String number) {
/// number is the phone number
Uri lookupUri = Uri.withAppendedPath(
ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI,
Uri.encode(number));
String[] mPhoneNumberProjection = {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
};
Cursor cur = context.getContentResolver().query(lookupUri,mPhoneNumberProjection, null, null, null);
try {
if (cur.moveToFirst()) {
Log.d("Phone number ID", ContactsContract.CommonDataKinds.Phone._ID);
Log.d("Phone number DISPLAY_NAME", ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
contactName = ContactsContract.CommonDataKinds.Phone._ID;
return contactName;
}
} finally {
if (cur != null) cur.close();
contactName = "Número no registrado";
}
return contactName;
}
}
}
And there are no errors compiling, but when I receive a call this is not showing anything in the logcat or the "run" section, so, I don't know if it is already working, here is my intent-filter from Android Manifest:
<receiver
android:name=".PhoneStateReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
I think it was probably my error, so I followed this tutotial for an SMS receiver, but it also doesn't show anything when I receive a SMS.
What am I missing?
I just forgot to asked for permissions in runtime, I added this in my onCreate and works perfectly:
if (ContextCompat.checkSelfPermission(
this, Manifest.permission.READ_PHONE_STATE
)!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{(Manifest.permission.READ_PHONE_STATE)},
REQUEST_PERMISSION_PHONE_STATE);
}
if (ContextCompat.checkSelfPermission(
this, Manifest.permission.READ_CONTACTS
)!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{(Manifest.permission.READ_CONTACTS)},
REQUEST_PERMISSION_READ_CONTACTS);
}
if (ContextCompat.checkSelfPermission(
this, Manifest.permission.READ_CALL_LOG
)!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{(Manifest.permission.READ_CALL_LOG)},
REQUEST_PERMISSION_READ_CALL_LOG);
}
I also modified my PhoneStateReceiver class, I had a lot of problems trying to get the contact name when the incoming number is already registered, I found some questions here on StackOverflow but unfortunately none of them helped me (they were deprecated solutions), finally I managed to make it work with the following code, I hope it will be helpful to someone else
public class PhoneStateReceiver extends BroadcastReceiver {
public String phoneNumber = "";
public String contactName = "";
@Override
public void onReceive(Context context, Intent intent) {
try {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
phoneNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING) && phoneNumber!=null){
Toast.makeText(context,"Ringing State Number is - " + phoneNumber, Toast.LENGTH_SHORT).show();
contactName = getContactName(context, phoneNumber);
}
}
catch (Exception e){
e.printStackTrace();
}
}
public String getContactName(Context context, String phoneNumber) {
if(phoneNumber == null){
return null;
}
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
if(cursor == null) {
return null;
}
String contactName = "Contacto no registrado";
if(cursor.moveToFirst()) {
contactName = cursor.getString(0);
}
if(!cursor.isClosed()) {
cursor.close();
}
return contactName;
}
}