mirror of https://github.com/tasks/tasks
commit
e8bfb35cb4
@ -0,0 +1,195 @@
|
||||
package com.todoroo.astrid.calls;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ContentUris;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.timsu.astrid.R;
|
||||
import com.todoroo.andlib.service.Autowired;
|
||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
import com.todoroo.andlib.utility.DialogUtilities;
|
||||
import com.todoroo.andlib.utility.Preferences;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
import com.todoroo.astrid.reminders.NotificationFragment.SnoozeDialog;
|
||||
import com.todoroo.astrid.reminders.Notifications;
|
||||
import com.todoroo.astrid.reminders.SnoozeCallback;
|
||||
import com.todoroo.astrid.service.TaskService;
|
||||
import com.todoroo.astrid.service.ThemeService;
|
||||
|
||||
public class MissedCallActivity extends Activity {
|
||||
|
||||
public static final String EXTRA_NUMBER = "number"; //$NON-NLS-1$
|
||||
public static final String EXTRA_NAME = "name"; //$NON-NLS-1$
|
||||
public static final String EXTRA_TIME = "time"; //$NON-NLS-1$
|
||||
public static final String EXTRA_CONTACT_ID = "contactId"; //$NON-NLS-1$
|
||||
|
||||
private static final String PREF_IGNORE_PRESSES = "missedCallsIgnored"; //$NON-NLS-1$
|
||||
|
||||
// Prompt user to ignore all missed calls after this many ignore presses
|
||||
private static final int IGNORE_PROMPT_COUNT = 3;
|
||||
|
||||
@Autowired private TaskService taskService;
|
||||
|
||||
private final OnClickListener dismissListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
AndroidUtilities.callOverridePendingTransition(MissedCallActivity.this, 0, android.R.anim.fade_out);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnClickListener ignoreListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
// Check for number of ignore presses
|
||||
int ignorePresses = Preferences.getInt(PREF_IGNORE_PRESSES, 0);
|
||||
ignorePresses++;
|
||||
if (ignorePresses == IGNORE_PROMPT_COUNT) {
|
||||
DialogUtilities.okCancelCustomDialog(MissedCallActivity.this,
|
||||
getString(R.string.MCA_ignore_title),
|
||||
getString(R.string.MCA_ignore_body),
|
||||
R.string.MCA_ignore_all,
|
||||
R.string.MCA_ignore_this,
|
||||
0,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Preferences.setBoolean(R.string.p_field_missed_calls, false);
|
||||
dismissListener.onClick(v);
|
||||
}
|
||||
},
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismissListener.onClick(v);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dismissListener.onClick(v);
|
||||
}
|
||||
Preferences.setInt(PREF_IGNORE_PRESSES, ignorePresses);
|
||||
}
|
||||
};
|
||||
|
||||
private String name;
|
||||
private String number;
|
||||
private String timeString;
|
||||
|
||||
private TextView returnCallButton;
|
||||
private TextView callLaterButton;
|
||||
private TextView ignoreButton;
|
||||
private View dismissButton;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
DependencyInjectionService.getInstance().inject(this);
|
||||
|
||||
setContentView(R.layout.missed_call_activity);
|
||||
|
||||
Intent intent = getIntent();
|
||||
|
||||
name = intent.getStringExtra(EXTRA_NAME);
|
||||
number = intent.getStringExtra(EXTRA_NUMBER);
|
||||
timeString = intent.getStringExtra(EXTRA_TIME);
|
||||
long contactId = intent.getExtras().getLong(EXTRA_CONTACT_ID);
|
||||
|
||||
int color = ThemeService.getThemeColor();
|
||||
|
||||
returnCallButton = (TextView) findViewById(R.id.call_now);
|
||||
callLaterButton = (TextView) findViewById(R.id.call_later);
|
||||
ignoreButton = (TextView) findViewById(R.id.call_ignore);
|
||||
dismissButton = findViewById(R.id.dismiss);
|
||||
((TextView) findViewById(R.id.reminder_title))
|
||||
.setText(getString(R.string.MCA_title,
|
||||
TextUtils.isEmpty(name) ? number : name, timeString));
|
||||
|
||||
ImageView pictureView = ((ImageView) findViewById(R.id.contact_picture));
|
||||
if (contactId >= 0) {
|
||||
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
|
||||
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), uri);
|
||||
if (input == null)
|
||||
return;
|
||||
pictureView.setImageBitmap(BitmapFactory.decodeStream(input));
|
||||
pictureView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
Resources r = getResources();
|
||||
returnCallButton.setBackgroundColor(r.getColor(color));
|
||||
callLaterButton.setBackgroundColor(r.getColor(color));
|
||||
|
||||
addListeners();
|
||||
|
||||
|
||||
if (!Preferences.getBoolean(R.string.p_rmd_nagging, true)) {
|
||||
findViewById(R.id.missed_calls_speech_bubble).setVisibility(View.GONE);
|
||||
} else {
|
||||
TextView dialogView = (TextView) findViewById(R.id.reminder_message);
|
||||
dialogView.setText(Notifications.getRandomReminder(getResources().getStringArray(R.array.MCA_dialog_speech_options)));
|
||||
}
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
ignoreButton.setOnClickListener(ignoreListener);
|
||||
dismissButton.setOnClickListener(dismissListener);
|
||||
|
||||
returnCallButton.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent call = new Intent(Intent.ACTION_CALL);
|
||||
call.setData(Uri.parse("tel:" + number)); //$NON-NLS-1$
|
||||
startActivity(call);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
callLaterButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final String taskTitle;
|
||||
String dialogTitle;
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
taskTitle = getString(R.string.MCA_task_title_no_name, number);
|
||||
dialogTitle = getString(R.string.MCA_schedule_dialog_title, number);
|
||||
} else {
|
||||
taskTitle = getString(R.string.MCA_task_title_name, name, number);
|
||||
dialogTitle = getString(R.string.MCA_schedule_dialog_title, name);
|
||||
}
|
||||
SnoozeDialog sd = new SnoozeDialog(MissedCallActivity.this, new SnoozeCallback() {
|
||||
@Override
|
||||
public void snoozeForTime(long time) {
|
||||
|
||||
Task newTask = new Task();
|
||||
newTask.setValue(Task.TITLE, taskTitle);
|
||||
newTask.setValue(Task.DUE_DATE, time);
|
||||
taskService.save(newTask);
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
new AlertDialog.Builder(MissedCallActivity.this)
|
||||
.setTitle(dialogTitle)
|
||||
.setView(sd)
|
||||
.setPositiveButton(android.R.string.ok, sd)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show().setOwnerActivity(MissedCallActivity.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package com.todoroo.astrid.calls;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
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.timsu.astrid.R;
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
import com.todoroo.andlib.utility.DateUtilities;
|
||||
import com.todoroo.andlib.utility.Preferences;
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
public class PhoneStateChangedReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String PREF_LAST_INCOMING_NUMBER = "last_incoming_number";
|
||||
|
||||
private static final long WAIT_BEFORE_READ_LOG = 3000L;
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
if (!Preferences.getBoolean(R.string.p_field_missed_calls, true)) {
|
||||
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 = context.getContentResolver().query(
|
||||
Calls.CONTENT_URI,
|
||||
null,
|
||||
Calls.TYPE + " = ? AND " + Calls.NEW + " = ?",
|
||||
new String[] { Integer.toString(Calls.MISSED_TYPE), "1" },
|
||||
Calls.DATE + " DESC"
|
||||
);
|
||||
try {
|
||||
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);
|
||||
|
||||
int timeIndex = calls.getColumnIndex(Calls.DATE);
|
||||
long time = calls.getLong(timeIndex);
|
||||
String timeString = DateUtilities.getTimeString(context, new Date(time));
|
||||
|
||||
long contactId = getContactIdFromNumber(context, number);
|
||||
|
||||
Intent missedCallIntent = new Intent(context, MissedCallActivity.class);
|
||||
missedCallIntent.putExtra(MissedCallActivity.EXTRA_NUMBER, number);
|
||||
missedCallIntent.putExtra(MissedCallActivity.EXTRA_NAME, name);
|
||||
missedCallIntent.putExtra(MissedCallActivity.EXTRA_TIME, timeString);
|
||||
missedCallIntent.putExtra(MissedCallActivity.EXTRA_CONTACT_ID, contactId);
|
||||
missedCallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
context.startActivity(missedCallIntent);
|
||||
}
|
||||
} finally {
|
||||
calls.close();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
private String digitsOnly(String number) {
|
||||
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()) {
|
||||
long id = c.getLong(c.getColumnIndex(ContactsContract.PhoneLookup._ID));
|
||||
return id;
|
||||
}
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/reminder_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/reminder_dialog_background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="5dip"
|
||||
android:layout_marginRight="5dip"
|
||||
android:layout_marginBottom="15dip"
|
||||
android:layout_marginLeft="10dip">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/contact_picture"
|
||||
android:layout_marginTop="5dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:visibility="gone"
|
||||
android:layout_width="46dip"
|
||||
android:layout_height="46dip"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reminder_title"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dip"
|
||||
android:textSize="24sp"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/MCA_title"/>
|
||||
<ImageView
|
||||
android:id="@+id/dismiss"
|
||||
android:layout_width="25dip"
|
||||
android:layout_height="25dip"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/close_clear_cancel"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/call_now"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="35dip"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp"
|
||||
android:gravity="center"
|
||||
android:text="@string/MCA_return_call"/>
|
||||
<TextView
|
||||
android:id="@+id/call_later"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="35dip"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp"
|
||||
android:gravity="center"
|
||||
android:text="@string/MCA_add_task"/>
|
||||
<TextView
|
||||
android:id="@+id/call_ignore"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="35dip"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp"
|
||||
android:gravity="center"
|
||||
android:text="@string/MCA_ignore"
|
||||
android:background="#707070"/>
|
||||
|
||||
<include layout="@layout/astrid_speech_bubble" android:id="@+id/missed_calls_speech_bubble"/>
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
|
||||
<include layout="@layout/astrid_missed_call_view"/>
|
||||
</LinearLayout>
|
Loading…
Reference in New Issue