You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/src/main/java/com/todoroo/astrid/calls/PhoneStateChangedReceiver.java

170 lines
6.5 KiB
Java

/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.calls;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import org.tasks.Notifier;
import org.tasks.injection.BroadcastComponent;
import org.tasks.injection.InjectingBroadcastReceiver;
import org.tasks.preferences.Preferences;
import javax.inject.Inject;
import timber.log.Timber;
public class PhoneStateChangedReceiver extends InjectingBroadcastReceiver {
private static final String PREF_LAST_INCOMING_NUMBER = "last_incoming_number";
private static final long WAIT_BEFORE_READ_LOG = 3000L;
@Inject Preferences preferences;
@Inject Notifier notifier;
@Override
public void onReceive(final Context context, Intent intent) {
super.onReceive(context, intent);
if (!preferences.fieldMissedPhoneCalls()) {
preferences.clear(PREF_LAST_INCOMING_NUMBER);
return;
}
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
String number = digitsOnly(intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));
if (TextUtils.isEmpty(number)) {
return;
}
preferences.setString(PREF_LAST_INCOMING_NUMBER, number);
} else if (TelephonyManager.EXTRA_STATE_IDLE.equals(state)) {
final String lastNumber = preferences.getStringValue(PREF_LAST_INCOMING_NUMBER);
if (TextUtils.isEmpty(lastNumber)) {
return;
}
preferences.clear(PREF_LAST_INCOMING_NUMBER);
new Thread() {
@Override
public void run() {
AndroidUtilities.sleepDeep(WAIT_BEFORE_READ_LOG);
Cursor calls;
try {
calls = context.getContentResolver().query(
Calls.CONTENT_URI,
new String[] { Calls.NUMBER, Calls.DATE, Calls.CACHED_NAME },
Calls.TYPE + " = ? AND " + Calls.NEW + " = ?",
new String[] { Integer.toString(Calls.MISSED_TYPE), "1" },
Calls.DATE + " DESC"
);
} catch (Exception e) { // Sometimes database is locked, retry once
Timber.e(e, e.getMessage());
AndroidUtilities.sleepDeep(300L);
try {
calls = context.getContentResolver().query(
Calls.CONTENT_URI,
new String[] { Calls.NUMBER, Calls.DATE, Calls.CACHED_NAME },
Calls.TYPE + " = ? AND " + Calls.NEW + " = ?",
new String[] { Integer.toString(Calls.MISSED_TYPE), "1" },
Calls.DATE + " DESC"
);
} catch (Exception e2) {
Timber.e(e2, e2.getMessage());
calls = null;
}
}
try {
if (calls == null) {
return;
}
if (calls.moveToFirst()) {
int numberIndex = calls.getColumnIndex(Calls.NUMBER);
String number = calls.getString(numberIndex);
// Sanity check for phone number match
// in case the phone logs haven't updated for some reaosn
if (!lastNumber.equals(digitsOnly(number))) {
return;
}
// If a lot of time has passed since the most recent missed call, ignore
// It could be the same person calling you back before you call them back,
// but if you answer this time, the missed call will still be in the database
// and will be processed again.
int dateIndex = calls.getColumnIndex(Calls.DATE);
long date = calls.getLong(dateIndex);
if (DateUtilities.now() - date > 2 * DateUtilities.ONE_MINUTE) {
return;
}
int nameIndex = calls.getColumnIndex(Calls.CACHED_NAME);
String name = calls.getString(nameIndex);
long contactId = getContactIdFromNumber(context, number);
notifier.triggerMissedCallNotification(name, number, contactId);
}
} catch (Exception e) {
Timber.e(e, e.getMessage());
} finally {
if (calls != null) {
calls.close();
}
}
}
}.start();
}
}
@Override
protected void inject(BroadcastComponent component) {
component.inject(this);
}
private String digitsOnly(String number) {
if (number == null) {
return "";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < number.length(); i++) {
char c = number.charAt(i);
if (Character.isDigit(c)) {
builder.append(c);
}
}
return builder.toString();
}
private long getContactIdFromNumber(Context context, String number) {
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
Cursor c = context.getContentResolver().query(contactUri, new String[] { ContactsContract.PhoneLookup._ID }, null, null, null);
try {
if (c.moveToFirst()) {
return c.getLong(c.getColumnIndex(ContactsContract.PhoneLookup._ID));
}
} finally {
c.close();
}
return -1;
}
}