Adding Synchronize Login WebView which is displayed when user needs to log in.

pull/14/head
Tim Su 17 years ago
parent 966fae0941
commit 74798781fa

@ -48,6 +48,9 @@
</intent-filter>
</activity>
<!-- Activity that lets users log in to sync providers -->
<activity android:name=".activities.SyncLoginActivity"/>
<!-- Activity that lets users edit app preferences -->
<activity android:name=".activities.EditPreferences"/>

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ASTRID: Android's Simple Task Recording Dashboard
Copyright (c) 2009 Tim Su
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/login_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rtm_login_label"
style="@style/TextAppearance.TaskList_Task"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:baselineAligned="false">
<Button android:id="@+id/done"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/done_label"
/>
<Button android:id="@+id/cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@android:string/cancel"
/>
</LinearLayout>
<WebView android:id="@+id/browser"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

@ -175,9 +175,9 @@
<!-- labels -->
<string name="name_label">Summary</string>
<string name="name_hint">Task Description</string>
<string name="importance_label">How Important is it?</string>
<string name="tags_label">Tags:</string>
<string name="tag_hint">Tag</string>
<string name="estimatedDuration_label">How Long Will it Take?</string>
<string name="elapsedDuration_label">Time Already Spent on Task</string>
@ -267,11 +267,6 @@ If you don\'t want to see the new task right after you complete the old one, you
<string name="sync_bgwifi_title">Auto-Sync Wifi Only</string>
<string name="sync_bgwifi_desc">If set, auto-sync only happens when Wifi is active</string>
<string name="sync_error">Sync Error! Sorry for the inconvenience! Error:</string>
<string name="sync_auth_request">
In order to synchronize, please log in to your %s account and authorize Astrid to read your data.
\n\n
When finished, restart Astrid.
</string>
<string name="sync_upgrade_v99">
Astrid 2.7 now performs synchronization with RTM in the background. You will
be directed to the preferences page to configure how often you want this to
@ -296,9 +291,14 @@ occur (it is a minor drain on battery).
<string name="sync_progress_remote">Reading Remote Data</string>
<string name="sync_progress_rxlist">Reading List: %s</string>
<string name="sync_progress_repeating">Synchronizing Repeating Task</string>
<string name="sync_progress_localtx">Sending Task: %s</string>
<string name="sync_progress_localtx">Transmitting: %s</string>
<string name="sync_progress_localdel">Locally Deleted Tasks</string>
<string name="sync_progress_remotetx">Receiving Task: %s</string>
<string name="sync_progress_remotetx">Receiving: %s</string>
<string name="rtm_login_label">Please Log In to RTM...</string>
<string name="rtm_login_error">
Sorry, there was an error verifying your login. Please let us know about this error:
</string>
<!-- Dialog Boxes -->
@ -307,6 +307,7 @@ occur (it is a minor drain on battery).
<string name="updating">Updating List...</string>
<string name="information_title">Information</string>
<string name="question_title">Question</string>
<string name="done_label">Done</string>
<string name="notify_yes">View Task</string>
<string name="notify_done">Already Done!</string>
<string name="notify_snooze">Snooze</string>

@ -0,0 +1,137 @@
/*
* ASTRID: Android's Simple Task Recording Dashboard
*
* Copyright (c) 2009 Tim Su
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.timsu.astrid.activities;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.timsu.astrid.utilities.Constants;
/**
* This activity displays a <code>WebView</code> that allows users to log in to the
* synchronization provider requested. A callback method determines whether
* their login was successful and therefore whether to dismiss the dialog.
*
* @author timsu
*
*/
public class SyncLoginActivity extends Activity {
// --- bundle arguments
/**
* URL to display
*/
public static final String URL_TOKEN = "u";
/**
* Resource for the label to display at the top of the screen
*/
public static final String LABEL_TOKEN = "l";
// --- callback
/** Callback interface */
public interface SyncLoginCallback {
/**
* Verifies whether the user's login attempt was successful. Will be
* called off of the UI thread, use the handler to post messages.
*
* @return true if activity should be dismissed, false otherwise
*/
public boolean verifyLogin(Handler handler);
}
private static SyncLoginCallback callback = null;
/** Sets callback method */
public static void setCallback(SyncLoginCallback newCallback) {
callback = newCallback;
}
// --- ui initialization
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sync_login);
String urlParam = getIntent().getStringExtra(URL_TOKEN);
int labelParam = getIntent().getIntExtra(LABEL_TOKEN, 0);
TextView label = (TextView)findViewById(R.id.login_label);
WebView webView = (WebView)findViewById(R.id.browser);
Button done = (Button)findViewById(R.id.done);
Button cancel = (Button)findViewById(R.id.cancel);
if(labelParam != 0)
label.setText(labelParam);
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSavePassword(false);
webView.getSettings().setSupportZoom(false);
webView.loadUrl(urlParam);
final Handler handler = new Handler();
done.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(callback == null) {
finish();
return;
}
new Thread(new Runnable() {
@Override
public void run() {
boolean result = callback.verifyLogin(handler);
if(result) {
setResult(Constants.RESULT_SYNCHRONIZE);
finish();
}
}
}).start();
}
});
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setResult(RESULT_CANCELED);
finish();
}
});
}
}

@ -77,6 +77,8 @@ public class SyncPreferences extends PreferenceActivity {
public void onClick(DialogInterface dialog,
int which) {
Synchronizer.clearUserData(SyncPreferences.this);
// force a synchronization if sync preference is still set
rtmSyncPreference = false;
}
}, null);
}

@ -19,7 +19,6 @@ package com.timsu.astrid.activities;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -93,7 +92,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
private static Format alarmFormat = null;
private final Activity activity;
private ArrayList<TaskModelForList> objects;
private List<TaskModelForList> objects;
private int resource;
private LayoutInflater inflater;
private TaskListAdapterHooks hooks;
@ -111,7 +110,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
*
*/
public interface TaskListAdapterHooks {
ArrayList<TaskModelForList> getTaskArray();
List<TaskModelForList> getTaskArray();
String getTagsFor(TaskModelForList task);
TaskController taskController();
TagController tagController();
@ -133,7 +132,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
* @param hooks
*/
public TaskListAdapter(Activity activity, int resource,
ArrayList<TaskModelForList> objects, TaskListAdapterHooks hooks) {
List<TaskModelForList> objects, TaskListAdapterHooks hooks) {
super(activity, resource, objects);
inflater = (LayoutInflater)activity.getSystemService(

@ -18,14 +18,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.timsu.astrid.activities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.List;
import java.util.Random;
import android.app.AlertDialog;
@ -138,8 +137,8 @@ public class TaskListSubActivity extends SubActivity {
// other instance variables
static class TaskListContext {
Map<TagIdentifier, TagModelForView> tagMap;
ArrayList<TaskModelForList> taskArray;
HashMap<TagIdentifier, TagModelForView> tagMap;
List<TaskModelForList> taskArray;
HashMap<Long, TaskModelForList> tasksById;
HashMap<TaskModelForList, String> taskTags;
TaskModelForList selectedTask = null;
@ -504,7 +503,8 @@ public class TaskListSubActivity extends SubActivity {
tasksCursor = getTaskController().getActiveTaskListCursor();
}
startManagingCursor(tasksCursor);
context.taskArray = getTaskController().createTaskListFromCursor(tasksCursor);
context.taskArray = Collections.synchronizedList(getTaskController().
createTaskListFromCursor(tasksCursor));
// read tags and apply filters
context.tagMap = getTagController().getAllTagsAsMap();
@ -650,7 +650,7 @@ public class TaskListSubActivity extends SubActivity {
class TaskListHooks implements TaskListAdapterHooks {
private HashMap<TaskModelForList, String> myTaskTags;
private ArrayList<TaskModelForList> myTaskArray;
private List<TaskModelForList> myTaskArray;
public TaskListHooks() {
this.myTaskTags = context.taskTags;
@ -665,7 +665,7 @@ public class TaskListSubActivity extends SubActivity {
return myTaskTags.get(task);
}
public ArrayList<TaskModelForList> getTaskArray() {
public List<TaskModelForList> getTaskArray() {
return myTaskArray;
}

@ -28,10 +28,9 @@ import java.util.StringTokenizer;
import java.util.Map.Entry;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import com.mdt.rtm.ApplicationInfo;
@ -48,7 +47,8 @@ import com.mdt.rtm.data.RtmTasks;
import com.mdt.rtm.data.RtmAuth.Perms;
import com.mdt.rtm.data.RtmTask.Priority;
import com.timsu.astrid.R;
import com.timsu.astrid.activities.TaskList;
import com.timsu.astrid.activities.SyncLoginActivity;
import com.timsu.astrid.activities.SyncLoginActivity.SyncLoginCallback;
import com.timsu.astrid.data.enums.Importance;
import com.timsu.astrid.data.sync.SyncMapping;
import com.timsu.astrid.data.tag.TagController;
@ -93,6 +93,8 @@ public class RTMSyncProvider extends SynchronizationProvider {
/** Perform authentication with RTM. Will open the SyncBrowser if necessary */
private void authenticate(final Context context) {
final Resources r = context.getResources();
try {
String apiKey = "bd9883b3384a21ead17501da38bb1e68";
String sharedSecret = "a19b2a020345219b";
@ -130,17 +132,40 @@ public class RTMSyncProvider extends SynchronizationProvider {
apiKey, sharedSecret, appName));
final String url = rtmService.beginAuthorization(Perms.delete);
progressDialog.dismiss();
Resources r = context.getResources();
DialogUtilities.okCancelDialog(context,
r.getString(R.string.sync_auth_request, "RTM"),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
TaskList.synchronizeNow = true;
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(url));
context.startActivity(intent);
Intent intent = new Intent(context, SyncLoginActivity.class);
SyncLoginActivity.setCallback(new SyncLoginCallback() {
@Override
public boolean verifyLogin(final Handler syncLoginHandler) {
if(rtmService == null) {
Log.e("rtmsync", "Error: sync login activity displayed with no service!");
return true;
}
try {
String token = rtmService.completeAuthorization();
Log.w("astrid", "got RTM token: " + token);
Preferences.setSyncRTMToken(context, token);
return true;
} catch (final Exception e) {
// didn't work
syncLoginHandler.post(new Runnable() {
@Override
public void run() {
DialogUtilities.okDialog(context,
r.getString(R.string.rtm_login_error) +
" " + e.getMessage(), null);
}
});
return false;
}
}
}, null);
});
intent.putExtra(SyncLoginActivity.URL_TOKEN, url);
intent.putExtra(SyncLoginActivity.LABEL_TOKEN, R.string.rtm_login_label);
context.startActivity(intent);
} else {
performSync(context);

Loading…
Cancel
Save