mirror of
https://github.com/fergalmoran/chrometophone.git
synced 2025-12-22 09:41:51 +00:00
Add history
This commit is contained in:
@@ -19,9 +19,8 @@
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
|
||||
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
|
||||
<activity android:name=".MainActivity"
|
||||
<activity android:name=".HistoryActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@@ -29,7 +28,14 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".SetupActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".HelpActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="portrait">
|
||||
</activity>
|
||||
|
||||
|
||||
BIN
android/res/drawable-hdpi/history_browser_item_indicator.png
Executable file
BIN
android/res/drawable-hdpi/history_browser_item_indicator.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 840 B |
BIN
android/res/drawable-hdpi/history_maps_item_indicator.png
Executable file
BIN
android/res/drawable-hdpi/history_maps_item_indicator.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 683 B |
BIN
android/res/drawable-hdpi/history_yt_item_indicator.png
Executable file
BIN
android/res/drawable-hdpi/history_yt_item_indicator.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 605 B |
BIN
android/res/drawable-mdpi/history_browser_item_indicator.png
Executable file
BIN
android/res/drawable-mdpi/history_browser_item_indicator.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 627 B |
BIN
android/res/drawable-mdpi/history_maps_item_indicator.png
Executable file
BIN
android/res/drawable-mdpi/history_maps_item_indicator.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 531 B |
BIN
android/res/drawable-mdpi/history_yt_item_indicator.png
Executable file
BIN
android/res/drawable-mdpi/history_yt_item_indicator.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 471 B |
24
android/res/layout/history.xml
Normal file
24
android/res/layout/history.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/background_gradient">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/header"
|
||||
android:background="@drawable/header"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dip"/>
|
||||
|
||||
<ExpandableListView android:id="@android:id/list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/header"
|
||||
android:drawSelectorOnTop="false"
|
||||
android:layout_margin="5dip"
|
||||
android:background="@android:color/transparent"
|
||||
android:cacheColorHint="@android:color/transparent"/>
|
||||
|
||||
</RelativeLayout>
|
||||
10
android/res/layout/history_header.xml
Normal file
10
android/res/layout/history_header.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:paddingLeft="35dip"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#000000"/>
|
||||
43
android/res/layout/history_item.xml
Normal file
43
android/res/layout/history_item.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?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="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="6dip"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView android:id="@+id/icon"
|
||||
android:layout_width="20dip"
|
||||
android:layout_height="20dip"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:layout_marginRight="11dip"
|
||||
android:padding="2dip"/>
|
||||
|
||||
<LinearLayout android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView android:id="@+id/title"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:maxLines="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textColor="#000000"/>
|
||||
|
||||
<TextView android:id="@+id/url"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:maxLines="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textColor="#000000"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
14
android/res/menu/history.xml
Normal file
14
android/res/menu/history.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/clear"
|
||||
android:icon="@android:drawable/ic_menu_close_clear_cancel"
|
||||
android:title="@string/clear_all"/>
|
||||
|
||||
<item android:id="@+id/settings"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
android:title="@string/settings"/>
|
||||
|
||||
<item android:id="@+id/help"
|
||||
android:icon="@android:drawable/ic_menu_help"
|
||||
android:title="@string/help"/>
|
||||
</menu>
|
||||
@@ -3,4 +3,4 @@
|
||||
<item android:id="@+id/help"
|
||||
android:icon="@android:drawable/ic_menu_help"
|
||||
android:title="@string/help"/>
|
||||
</menu>
|
||||
</menu>
|
||||
11
android/res/values/arrays.xml
Normal file
11
android/res/values/arrays.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string-array name="link_action_dialog_items">
|
||||
<item>Open</item>
|
||||
<item>Add bookmark</item>
|
||||
<item>Share link</item>
|
||||
<item>Copy link url</item>
|
||||
<item>Remove from history</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -77,18 +77,6 @@
|
||||
<!-- Notification shown when text from the desktop is copied to Android's clipboard (user can now paste the text) [CHAR LIMIT=NONE] -->
|
||||
<string name="copied_desktop_clipboard">Copied desktop clipboard</string>
|
||||
|
||||
<!-- Brief notification that appears when user sends link from phone to desktop [CHAR LIMIT=NONE] -->
|
||||
<string name="sending_link_toast">Sending link...</string>
|
||||
|
||||
<!-- Brief notification that appears when user has sent link from phone to desktop [CHAR LIMIT=NONE] -->
|
||||
<string name="link_sent_toast">Link sent</string>
|
||||
|
||||
<!-- Brief notification that appears when link cannot be sent from phone to desktop [CHAR LIMIT=NONE] -->
|
||||
<string name="link_not_sent_toast">Link not sent</string>
|
||||
|
||||
<!-- Brief notification that appears when link cannot be sent from phone to desktop (because of auth issue) [CHAR LIMIT=NONE] -->
|
||||
<string name="link_not_sent_auth_toast">Link not sent - authentication required</string>
|
||||
|
||||
<!-- Introduction text at start of setup flow. Preserve occurrences of <br>, <a href="{tos_link}">, <a href="{pp_link}">, and <a/> [CHAR LIMIT=NONE] -->
|
||||
<string name="intro_text">
|
||||
Chrome to Phone lets you easily share links, maps, and currently selected phone numbers and text
|
||||
@@ -117,4 +105,38 @@
|
||||
<a href="{tos_link}">Terms of Service</a> and
|
||||
<a href="{pp_link}">Privacy Policy</a>.
|
||||
</string>
|
||||
|
||||
<!-- Label for items received today [CHAR LIMIT=NONE] -->
|
||||
<string name="today_text">Today</string>
|
||||
|
||||
<!-- Label for items received in the last 7 days [CHAR LIMIT=NONE] -->
|
||||
<string name="last_seven_days_text">Last 7 days</string>
|
||||
|
||||
<!-- Label for items received in the last month [CHAR LIMIT=NONE] -->
|
||||
<string name="last_month_text">Last month</string>
|
||||
|
||||
<!-- Label for items received older [CHAR LIMIT=NONE] -->
|
||||
<string name="older_text">Older</string>
|
||||
|
||||
<!-- Menu option for 'Clear all' [CHAR LIMIT=NONE] -->
|
||||
<string name="clear_all">Clear all</string>
|
||||
|
||||
<!-- Menu option for 'Settings' [CHAR LIMIT=NONE] -->
|
||||
<string name="settings">Settings</string>
|
||||
|
||||
<!-- Title for dialog where user is asked to share a link with their choice of app [CHAR LIMIT=NONE] -->
|
||||
<string name="share_chooser_title">Share with</string>
|
||||
|
||||
<!-- Brief notification that appears when user sends link from phone to desktop [CHAR LIMIT=NONE] -->
|
||||
<string name="sending_link_toast">Sending link...</string>
|
||||
|
||||
<!-- Brief notification that appears when user has sent link from phone to desktop [CHAR LIMIT=NONE] -->
|
||||
<string name="link_sent_toast">Link sent</string>
|
||||
|
||||
<!-- Brief notification that appears when link cannot be sent from phone to desktop [CHAR LIMIT=NONE] -->
|
||||
<string name="link_not_sent_toast">Link not sent</string>
|
||||
|
||||
<!-- Brief notification that appears when link cannot be sent from phone to desktop (because of auth issue) [CHAR LIMIT=NONE] -->
|
||||
<string name="link_not_sent_auth_toast">Link not sent - authentication required</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -132,7 +132,7 @@ public class AppEngineClient {
|
||||
// User will be asked for "App Engine" permission.
|
||||
if (authToken == null) {
|
||||
// No auth token - will need to ask permission from user.
|
||||
Intent intent = new Intent(MainActivity.AUTH_PERMISSION_ACTION);
|
||||
Intent intent = new Intent(SetupActivity.AUTH_PERMISSION_ACTION);
|
||||
intent.putExtra("AccountManagerBundle", bundle);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
@@ -21,19 +21,10 @@ import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.ClipboardManager;
|
||||
|
||||
import com.google.android.c2dm.C2DMBaseReceiver;
|
||||
|
||||
@@ -61,147 +52,55 @@ public class C2DMReceiver extends C2DMBaseReceiver {
|
||||
|
||||
@Override
|
||||
public void onMessage(Context context, Intent intent) {
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras != null) {
|
||||
String url = (String) extras.get("url");
|
||||
String title = (String) extras.get("title");
|
||||
String sel = (String) extras.get("sel");
|
||||
String debug = (String) extras.get("debug");
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras != null) {
|
||||
String url = (String) extras.get("url");
|
||||
String title = (String) extras.get("title");
|
||||
String sel = (String) extras.get("sel");
|
||||
String debug = (String) extras.get("debug");
|
||||
|
||||
if (debug != null) {
|
||||
// server-controlled debug - the server wants to know
|
||||
// we received the message, and when. This is not user-controllable,
|
||||
// we don't want extra traffic on the server or phone. Server may
|
||||
// turn this on for a small percentage of requests or for users
|
||||
// who report issues.
|
||||
DefaultHttpClient client = new DefaultHttpClient();
|
||||
HttpGet get = new HttpGet(AppEngineClient.BASE_URL + "/debug?id="
|
||||
+ extras.get("collapse_key"));
|
||||
// No auth - the purpose is only to generate a log/confirm delivery
|
||||
// (to avoid overhead of getting the token)
|
||||
try {
|
||||
client.execute(get);
|
||||
} catch (ClientProtocolException e) {
|
||||
// ignore
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (title != null && url != null && url.startsWith("http")) {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
Intent launchIntent = getLaunchIntent(context, url, title, sel);
|
||||
|
||||
if (settings.getBoolean("launchBrowserOrMaps", true) && launchIntent != null) {
|
||||
playNotificationSound(context);
|
||||
context.startActivity(launchIntent);
|
||||
} else {
|
||||
if (sel != null && sel.length() > 0) { // have selection
|
||||
generateNotification(context, sel,
|
||||
context.getString(R.string.copied_desktop_clipboard), launchIntent);
|
||||
} else {
|
||||
generateNotification(context, url, title, launchIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Intent getLaunchIntent(Context context, String url, String title, String sel) {
|
||||
Intent intent = null;
|
||||
String number = parseTelephoneNumber(sel);
|
||||
if (number != null) {
|
||||
intent = new Intent("android.intent.action.DIAL",
|
||||
Uri.parse("tel:" + number));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
ClipboardManager cm =
|
||||
(ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
|
||||
cm.setText(number);
|
||||
} else if (sel != null && sel.length() > 0) {
|
||||
// No intent for selection - just copy to clipboard
|
||||
ClipboardManager cm =
|
||||
(ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
|
||||
cm.setText(sel);
|
||||
} else {
|
||||
final String GMM_PACKAGE_NAME = "com.google.android.apps.maps";
|
||||
final String GMM_CLASS_NAME = "com.google.android.maps.MapsActivity";
|
||||
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (isMapsURL(url)) {
|
||||
intent.setClassName(GMM_PACKAGE_NAME, GMM_CLASS_NAME);
|
||||
if (debug != null) {
|
||||
// server-controlled debug - the server wants to know
|
||||
// we received the message, and when. This is not user-controllable,
|
||||
// we don't want extra traffic on the server or phone. Server may
|
||||
// turn this on for a small percentage of requests or for users
|
||||
// who report issues.
|
||||
DefaultHttpClient client = new DefaultHttpClient();
|
||||
HttpGet get = new HttpGet(AppEngineClient.BASE_URL + "/debug?id="
|
||||
+ extras.get("collapse_key"));
|
||||
// No auth - the purpose is only to generate a log/confirm delivery
|
||||
// (to avoid overhead of getting the token)
|
||||
try {
|
||||
client.execute(get);
|
||||
} catch (ClientProtocolException e) {
|
||||
// ignore
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back if we can't resolve intent (i.e. app missing)
|
||||
PackageManager pm = context.getPackageManager();
|
||||
if (null == intent.resolveActivity(pm)) {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (title != null && url != null && url.startsWith("http")) {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
Intent launchIntent = LauncherUtils.getLaunchIntent(context, title, url, sel);
|
||||
|
||||
// Notify and optionally start activity
|
||||
if (settings.getBoolean("launchBrowserOrMaps", true) && launchIntent != null) {
|
||||
LauncherUtils.playNotificationSound(context);
|
||||
context.startActivity(launchIntent);
|
||||
} else {
|
||||
if (sel != null && sel.length() > 0) { // have selection
|
||||
LauncherUtils.generateNotification(context, sel,
|
||||
context.getString(R.string.copied_desktop_clipboard), launchIntent);
|
||||
} else {
|
||||
LauncherUtils.generateNotification(context, url, title, launchIntent);
|
||||
}
|
||||
}
|
||||
|
||||
// Record history (for link/maps only)
|
||||
if (launchIntent != null && launchIntent.getAction().equals(Intent.ACTION_VIEW)) {
|
||||
HistoryDatabase.get(context).insertHistory(title, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
private void generateNotification(Context context, String msg, String title, Intent intent) {
|
||||
int icon = R.drawable.status_icon;
|
||||
long when = System.currentTimeMillis();
|
||||
|
||||
Notification notification = new Notification(icon, title, when);
|
||||
notification.setLatestEventInfo(context, title, msg,
|
||||
PendingIntent.getActivity(context, 0, intent, 0));
|
||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
int notificatonID = settings.getInt("notificationID", 0); // allow multiple notifications
|
||||
|
||||
NotificationManager nm =
|
||||
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(notificatonID, notification);
|
||||
playNotificationSound(context);
|
||||
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putInt("notificationID", ++notificatonID % 32);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
private void playNotificationSound(Context context) {
|
||||
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||
if (uri != null) {
|
||||
Ringtone rt = RingtoneManager.getRingtone(context, uri);
|
||||
if (rt != null) {
|
||||
rt.setStreamType(AudioManager.STREAM_NOTIFICATION);
|
||||
rt.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String parseTelephoneNumber(String sel) {
|
||||
if (sel == null || sel.length() == 0) return null;
|
||||
|
||||
// Hack: Remove trailing left-to-right mark (Google Maps adds this)
|
||||
if (sel.codePointAt(sel.length() - 1) == 8206) {
|
||||
sel = sel.substring(0, sel.length() - 1);
|
||||
}
|
||||
|
||||
String number = null;
|
||||
if (sel.matches("([Tt]el[:]?)?\\s?[+]?(\\(?[0-9|\\s|\\-|\\.]\\)?)+")) {
|
||||
String elements[] = sel.split("([Tt]el[:]?)");
|
||||
number = elements.length > 1 ? elements[1] : elements[0];
|
||||
number = number.replace(" ", "");
|
||||
|
||||
// Remove option (0) in international numbers, e.g. +44 (0)20 ...
|
||||
if (number.matches("\\+[0-9]{2,3}\\(0\\).*")) {
|
||||
int openBracket = number.indexOf('(');
|
||||
int closeBracket = number.indexOf(')');
|
||||
number = number.substring(0, openBracket) +
|
||||
number.substring(closeBracket + 1);
|
||||
}
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
private boolean isMapsURL(String url) {
|
||||
return url.matches("http://maps\\.google\\.[a-z]{2,3}(\\.[a-z]{2})?[/?].*") ||
|
||||
url.matches("http://www\\.google\\.[a-z]{2,3}(\\.[a-z]{2})?/maps.*");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Browser;
|
||||
import android.text.ClipboardManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ExpandableListView.OnChildClickListener;
|
||||
|
||||
/**
|
||||
* Activity that shows the history of links received.
|
||||
*/
|
||||
public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
private static final int DIALOG_LINK_ACTION = 1;
|
||||
|
||||
private ExpandableListView mList;
|
||||
private HistoryExpandableListAdapter mListAdapter;
|
||||
private Context mContext = null;
|
||||
|
||||
private Link mSelectedLink;
|
||||
private int mSelectedGroup;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Run the setup first if necessary
|
||||
SharedPreferences prefs = Prefs.get(this);
|
||||
if (prefs.getString("deviceRegistrationID", null) == null) {
|
||||
startActivity(new Intent(this, SetupActivity.class));
|
||||
}
|
||||
|
||||
setContentView(R.layout.history);
|
||||
mList = (ExpandableListView) findViewById(android.R.id.list);
|
||||
mList.setOnCreateContextMenuListener(this);
|
||||
mList.setOnChildClickListener(this);
|
||||
|
||||
mListAdapter = new HistoryExpandableListAdapter(this);
|
||||
mList.setAdapter(mListAdapter);
|
||||
|
||||
mContext = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.history, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.clear: {
|
||||
HistoryDatabase.get(this).deleteAllHistory();
|
||||
mListAdapter.refresh();
|
||||
for (int i = 0; i < DateBinSorter.NUM_BINS; i++) {
|
||||
mList.collapseGroup(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case R.id.settings: {
|
||||
startActivity(new Intent(this, SetupActivity.class));
|
||||
return true;
|
||||
}
|
||||
case R.id.help: {
|
||||
startActivity(new Intent(this, HelpActivity.class));
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
|
||||
int childPosition, long id) {
|
||||
mSelectedLink = mListAdapter.getLinkAtPosition(groupPosition, childPosition);
|
||||
mSelectedGroup = groupPosition;
|
||||
showDialog(DIALOG_LINK_ACTION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mListAdapter.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case DIALOG_LINK_ACTION:
|
||||
return new AlertDialog.Builder(this)
|
||||
.setTitle(ellipsis(mSelectedLink.mTitle))
|
||||
.setItems(R.array.link_action_dialog_items, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == 0) { // Open
|
||||
startActivity(LauncherUtils.getLaunchIntent(mContext,
|
||||
mSelectedLink.mTitle, mSelectedLink.mUrl, null));
|
||||
} else if (which == 1) { // Add bookmark
|
||||
Browser.saveBookmark(mContext, mSelectedLink.mTitle,
|
||||
mSelectedLink.mUrl);
|
||||
} else if (which == 2) { // Share link
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.putExtra(Intent.EXTRA_TEXT, mSelectedLink.mUrl);
|
||||
intent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(intent,
|
||||
getString(R.string.share_chooser_title)));
|
||||
} else if (which == 3) { // Copy link URL
|
||||
ClipboardManager cm =
|
||||
(ClipboardManager) mContext.getSystemService(CLIPBOARD_SERVICE);
|
||||
cm.setText(mSelectedLink.mUrl);
|
||||
} else if (which == 4) { // Remove from history
|
||||
HistoryDatabase.get(mContext).deleteHistory(mSelectedLink.mUrl);
|
||||
mListAdapter.refresh();
|
||||
mList.collapseGroup(mSelectedGroup);
|
||||
mList.expandGroup(mSelectedGroup);
|
||||
}
|
||||
}
|
||||
}).create();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialog(int id, Dialog dialog) {
|
||||
dialog.setTitle(ellipsis(mSelectedLink.mTitle));
|
||||
}
|
||||
|
||||
private String ellipsis(String string) {
|
||||
int MAX_LENGTH = 50;
|
||||
if (string.length() > MAX_LENGTH - 3) {
|
||||
string = string.substring(0, MAX_LENGTH - 3);
|
||||
string += "...";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
class HistoryExpandableListAdapter extends BaseExpandableListAdapter {
|
||||
private final Context mContext;
|
||||
private Cursor mCursor;
|
||||
private DateBinSorter mDateBinSorter;
|
||||
private int mChildCounts[];
|
||||
|
||||
public HistoryExpandableListAdapter(Context context) {
|
||||
this.mContext = context;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
mCursor = HistoryDatabase.get(mContext).lookupHistory();
|
||||
mDateBinSorter = new DateBinSorter(mContext);
|
||||
calculateCounts();
|
||||
}
|
||||
|
||||
private void calculateCounts() {
|
||||
mChildCounts = new int[DateBinSorter.NUM_BINS];
|
||||
for (int j = 0; j < DateBinSorter.NUM_BINS; j++) {
|
||||
mChildCounts[j] = 0;
|
||||
}
|
||||
|
||||
int dateIndex = -1;
|
||||
if (mCursor.moveToFirst() && mCursor.getCount() > 0) {
|
||||
while (!mCursor.isAfterLast()) {
|
||||
long date = mCursor.getLong(HistoryDatabase.RECEIVE_TIME_INDEX);
|
||||
int index = mDateBinSorter.getBin(date);
|
||||
if (index > dateIndex) {
|
||||
if (index == DateBinSorter.NUM_BINS - 1) {
|
||||
mChildCounts[index] = mCursor.getCount() - mCursor.getPosition();
|
||||
break;
|
||||
}
|
||||
dateIndex = index;
|
||||
}
|
||||
mChildCounts[dateIndex]++;
|
||||
mCursor.moveToNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object getChild(int groupPosition, int childPosition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return moveCursorPosition(groupPosition, childPosition);
|
||||
}
|
||||
|
||||
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
|
||||
View convertView, ViewGroup parent) {
|
||||
HistoryItemView itemView;
|
||||
if (null == convertView || !(convertView instanceof HistoryItemView)) {
|
||||
itemView = new HistoryItemView(mContext);
|
||||
// Add padding on the left so it will be indented from the
|
||||
// arrows on the group views.
|
||||
itemView.setPadding(itemView.getPaddingLeft() + 10,
|
||||
itemView.getPaddingTop(),
|
||||
itemView.getPaddingRight(),
|
||||
itemView.getPaddingBottom());
|
||||
} else {
|
||||
itemView = (HistoryItemView) convertView;
|
||||
}
|
||||
|
||||
|
||||
moveCursorPosition(groupPosition, childPosition);
|
||||
itemView.setTitle(mCursor.getString(HistoryDatabase.TITLE_INDEX));
|
||||
itemView.setUrl(mCursor.getString(HistoryDatabase.URL_INDEX));
|
||||
|
||||
return itemView;
|
||||
}
|
||||
|
||||
public int getChildrenCount(int groupPosition) {
|
||||
return mChildCounts[groupPosition];
|
||||
}
|
||||
|
||||
public Object getGroup(int groupPosition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getGroupCount() {
|
||||
return DateBinSorter.NUM_BINS;
|
||||
}
|
||||
|
||||
public long getGroupId(int groupPosition) {
|
||||
return groupPosition;
|
||||
}
|
||||
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
|
||||
ViewGroup parent) {
|
||||
TextView item;
|
||||
if (null == convertView || !(convertView instanceof TextView)) {
|
||||
LayoutInflater factory = LayoutInflater.from(mContext);
|
||||
item = (TextView) factory.inflate(R.layout.history_header, null);
|
||||
} else {
|
||||
item = (TextView) convertView;
|
||||
}
|
||||
String label = mDateBinSorter.getBinLabel(groupPosition);
|
||||
item.setText(label);
|
||||
return item;
|
||||
}
|
||||
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int moveCursorPosition(int groupPosition, int childPosition) {
|
||||
int index = childPosition;
|
||||
for (int i = 0; i < groupPosition; i++) {
|
||||
index += mChildCounts[i];
|
||||
}
|
||||
mCursor.moveToPosition(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
private Link getLinkAtPosition(int groupPosition, int childPosition) {
|
||||
moveCursorPosition(groupPosition, childPosition);
|
||||
return new Link(mCursor.getString(HistoryDatabase.TITLE_INDEX),
|
||||
mCursor.getString(HistoryDatabase.URL_INDEX));
|
||||
}
|
||||
}
|
||||
|
||||
class DateBinSorter {
|
||||
public static final int NUM_BINS = 4;
|
||||
private final long [] mBins = new long[NUM_BINS-1];
|
||||
private final Context mContext;
|
||||
|
||||
public DateBinSorter(Context context) {
|
||||
this.mContext = context;
|
||||
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||
c.set(Calendar.MINUTE, 0);
|
||||
c.set(Calendar.SECOND, 0);
|
||||
c.set(Calendar.MILLISECOND, 0);
|
||||
mBins[0] = c.getTimeInMillis(); // today
|
||||
|
||||
c.add(Calendar.DAY_OF_YEAR, -7);
|
||||
mBins[1] = c.getTimeInMillis(); // seven days ago
|
||||
|
||||
c.add(Calendar.DAY_OF_YEAR, 7);
|
||||
c.add(Calendar.MONTH, -1);
|
||||
mBins[2] = c.getTimeInMillis(); // one month ago
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date bin for a specified time:
|
||||
* 0 => today, 1 => last week,
|
||||
* 2 => last month, 3 => older
|
||||
*/
|
||||
public int getBin(long time) {
|
||||
int lastDay = NUM_BINS - 1;
|
||||
for (int i = 0; i < lastDay; i++) {
|
||||
if (time > mBins[i]) return i;
|
||||
}
|
||||
return lastDay;
|
||||
}
|
||||
|
||||
private String getBinLabel(int index) {
|
||||
if (index == 0) {
|
||||
return mContext.getString(R.string.today_text);
|
||||
} else if (index == 1) {
|
||||
return mContext.getString(R.string.last_seven_days_text);
|
||||
} else if (index == 2) {
|
||||
return mContext.getString(R.string.last_month_text);
|
||||
} else {
|
||||
return mContext.getString(R.string.older_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Link {
|
||||
public final String mTitle;
|
||||
public final String mUrl;
|
||||
|
||||
public Link(String title, String url) {
|
||||
mTitle = title;
|
||||
mUrl = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteStatement;
|
||||
|
||||
/**
|
||||
* Database to store and retrieve history of received links.
|
||||
*/
|
||||
public class HistoryDatabase {
|
||||
public static final int URL_INDEX = 0;
|
||||
public static final int TITLE_INDEX = 1;
|
||||
public static final int RECEIVE_TIME_INDEX = 2;
|
||||
|
||||
private static final String DATABASE_NAME = "history.db";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
private static final String TABLE_NAME = "history";
|
||||
private static final String URL_COL_NAME = "url";
|
||||
private static final String TITLE_COL_NAME = "title";
|
||||
private static final String RECEIVE_TIME_COL_NAME = "receive_time";
|
||||
|
||||
private static final String[] ALL_COLUMNS =
|
||||
new String[] { URL_COL_NAME, TITLE_COL_NAME, RECEIVE_TIME_COL_NAME };
|
||||
|
||||
private final SQLiteDatabase mDb;
|
||||
private SQLiteStatement mInsertStatement;
|
||||
private SQLiteStatement mDeleteStatement;
|
||||
private SQLiteStatement mDeleteAllStatement;
|
||||
|
||||
private static HistoryDatabase mSingleton;
|
||||
|
||||
private HistoryDatabase(Context context) {
|
||||
mDb = new DatabaseHelper(context).getWritableDatabase();
|
||||
}
|
||||
|
||||
public synchronized static HistoryDatabase get(Context context) {
|
||||
if (mSingleton == null) {
|
||||
mSingleton = new HistoryDatabase(context);
|
||||
}
|
||||
return mSingleton;
|
||||
}
|
||||
|
||||
public void insertHistory(String title, String url) {
|
||||
if (mInsertStatement == null) {
|
||||
mInsertStatement = mDb.compileStatement("INSERT OR REPLACE INTO "+ TABLE_NAME +
|
||||
"(" + URL_COL_NAME + ", " +
|
||||
TITLE_COL_NAME + ", " +
|
||||
RECEIVE_TIME_COL_NAME +
|
||||
") VALUES (?, ?, ?)");
|
||||
}
|
||||
|
||||
mInsertStatement.bindString(1, url);
|
||||
mInsertStatement.bindString(2, title);
|
||||
mInsertStatement.bindLong(3, System.currentTimeMillis());
|
||||
mInsertStatement.execute();
|
||||
}
|
||||
|
||||
public Cursor lookupHistory() {
|
||||
return mDb.query(TABLE_NAME, ALL_COLUMNS, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public void deleteHistory(String url) {
|
||||
if (mDeleteStatement == null) {
|
||||
mDeleteStatement = mDb.compileStatement("DELETE FROM "+ TABLE_NAME +
|
||||
" WHERE " + URL_COL_NAME + " == ?");
|
||||
}
|
||||
mDeleteStatement.bindString(1, url);
|
||||
mDeleteStatement.execute();
|
||||
}
|
||||
|
||||
public void deleteAllHistory() {
|
||||
if (mDeleteAllStatement == null) {
|
||||
mDeleteAllStatement = mDb.compileStatement("DELETE FROM "+ TABLE_NAME);
|
||||
}
|
||||
mDeleteAllStatement.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Database helper that creates and maintains the SQLite database.
|
||||
*/
|
||||
static class DatabaseHelper extends SQLiteOpenHelper {
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
createHistoryTable(db);
|
||||
}
|
||||
|
||||
private void createHistoryTable(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE "+ TABLE_NAME + "(" +
|
||||
URL_COL_NAME + " TEXT PRIMARY KEY, " +
|
||||
TITLE_COL_NAME + " TEXT NOT NULL, " +
|
||||
RECEIVE_TIME_COL_NAME + " INTEGER)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
// Implement the upgrade path to databases with DATABASE_VERSION > 1 here
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* A single history item (child view for expandable list).
|
||||
*/
|
||||
public class HistoryItemView extends LinearLayout {
|
||||
private final TextView mTextView;
|
||||
private final TextView mUrlText;
|
||||
private final ImageView mImageView;
|
||||
private final Context mContext;
|
||||
|
||||
public HistoryItemView(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
LayoutInflater factory = LayoutInflater.from(context);
|
||||
factory.inflate(R.layout.history_item, this);
|
||||
mTextView = (TextView) findViewById(R.id.title);
|
||||
mUrlText = (TextView) findViewById(R.id.url);
|
||||
mImageView = (ImageView) findViewById(R.id.icon);
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
mTextView.setText(ellipsis(title));
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
int id = R.drawable.history_browser_item_indicator;
|
||||
if (LauncherUtils.isMapsURL(url)) {
|
||||
id = R.drawable.history_maps_item_indicator;
|
||||
} else if (LauncherUtils.isYouTubeURL(url)) {
|
||||
id = R.drawable.history_yt_item_indicator;
|
||||
}
|
||||
Drawable icon = mContext.getResources().getDrawable(id);
|
||||
mImageView.setImageDrawable(icon);
|
||||
mUrlText.setText(ellipsis(url));
|
||||
}
|
||||
|
||||
private String ellipsis(String string) {
|
||||
int MAX_LENGTH = 50;
|
||||
if (string.length() > MAX_LENGTH - 3) {
|
||||
string = string.substring(0, MAX_LENGTH - 3);
|
||||
string += "...";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.text.ClipboardManager;
|
||||
|
||||
/**
|
||||
* Common set of utility functions for launching apps.
|
||||
*/
|
||||
public class LauncherUtils {
|
||||
private static final String GMM_PACKAGE_NAME = "com.google.android.apps.maps";
|
||||
private static final String GMM_CLASS_NAME = "com.google.android.maps.MapsActivity";
|
||||
|
||||
public static Intent getLaunchIntent(Context context, String title, String url, String sel) {
|
||||
Intent intent = null;
|
||||
String number = parseTelephoneNumber(sel);
|
||||
if (number != null) {
|
||||
intent = new Intent(Intent.ACTION_DIAL,
|
||||
Uri.parse("tel:" + number));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
ClipboardManager cm =
|
||||
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cm.setText(number);
|
||||
} else if (sel != null && sel.length() > 0) {
|
||||
// No intent for selection - just copy to clipboard
|
||||
ClipboardManager cm =
|
||||
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cm.setText(sel);
|
||||
} else {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (isMapsURL(url)) {
|
||||
intent.setClassName(GMM_PACKAGE_NAME, GMM_CLASS_NAME);
|
||||
}
|
||||
|
||||
// Fall back if we can't resolve intent (i.e. app missing)
|
||||
PackageManager pm = context.getPackageManager();
|
||||
if (null == intent.resolveActivity(pm)) {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static void generateNotification(Context context, String msg, String title, Intent intent) {
|
||||
int icon = R.drawable.status_icon;
|
||||
long when = System.currentTimeMillis();
|
||||
|
||||
Notification notification = new Notification(icon, title, when);
|
||||
notification.setLatestEventInfo(context, title, msg,
|
||||
PendingIntent.getActivity(context, 0, intent, 0));
|
||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
int notificatonID = settings.getInt("notificationID", 0); // allow multiple notifications
|
||||
|
||||
NotificationManager nm =
|
||||
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(notificatonID, notification);
|
||||
playNotificationSound(context);
|
||||
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putInt("notificationID", ++notificatonID % 32);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static void playNotificationSound(Context context) {
|
||||
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||
if (uri != null) {
|
||||
Ringtone rt = RingtoneManager.getRingtone(context, uri);
|
||||
if (rt != null) {
|
||||
rt.setStreamType(AudioManager.STREAM_NOTIFICATION);
|
||||
rt.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String parseTelephoneNumber(String sel) {
|
||||
if (sel == null || sel.length() == 0) return null;
|
||||
|
||||
// Hack: Remove trailing left-to-right mark (Google Maps adds this)
|
||||
if (sel.codePointAt(sel.length() - 1) == 8206) {
|
||||
sel = sel.substring(0, sel.length() - 1);
|
||||
}
|
||||
|
||||
String number = null;
|
||||
if (sel.matches("([Tt]el[:]?)?\\s?[+]?(\\(?[0-9|\\s|\\-|\\.]\\)?)+")) {
|
||||
String elements[] = sel.split("([Tt]el[:]?)");
|
||||
number = elements.length > 1 ? elements[1] : elements[0];
|
||||
number = number.replace(" ", "");
|
||||
|
||||
// Remove option (0) in international numbers, e.g. +44 (0)20 ...
|
||||
if (number.matches("\\+[0-9]{2,3}\\(0\\).*")) {
|
||||
int openBracket = number.indexOf('(');
|
||||
int closeBracket = number.indexOf(')');
|
||||
number = number.substring(0, openBracket) +
|
||||
number.substring(closeBracket + 1);
|
||||
}
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
public static boolean isMapsURL(String url) {
|
||||
return url.matches("http://maps\\.google\\.[a-z]{2,3}(\\.[a-z]{2})?[/?].*") ||
|
||||
url.matches("http://www\\.google\\.[a-z]{2,3}(\\.[a-z]{2})?/maps.*");
|
||||
}
|
||||
|
||||
public static boolean isYouTubeURL(String url) {
|
||||
return url.matches("http://www\\.youtube\\.[a-z]{2,3}(\\.[a-z]{2})?/.*");
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,9 @@ import android.widget.RadioGroup.OnCheckedChangeListener;
|
||||
import com.google.android.c2dm.C2DMessaging;
|
||||
|
||||
/**
|
||||
* Main activity - takes user through set up.
|
||||
* Setup activity - takes user through the setup.
|
||||
*/
|
||||
public class MainActivity extends Activity {
|
||||
public class SetupActivity extends Activity {
|
||||
public static final String UPDATE_UI_ACTION = "com.google.ctp.UPDATE_UI";
|
||||
public static final String AUTH_PERMISSION_ACTION = "com.google.ctp.AUTH_PERMISSION";
|
||||
|
||||
@@ -95,7 +95,7 @@ public class MainActivity extends Activity {
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.help, menu);
|
||||
inflater.inflate(R.menu.setup, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user