summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike LeBeau <mlebeau@android.com>2009-06-30 11:09:34 -0700
committerMike LeBeau <mlebeau@android.com>2009-06-30 11:09:34 -0700
commit36d988b42d72c593bb7eba45366666a6da4673b5 (patch)
treef674848d04e448e8e1260d8dd4fc9282b578493d
parent09a1420152123f5c3c980be69b5bfe7aa6290a65 (diff)
downloadGoogleSearch-36d988b42d72c593bb7eba45366666a6da4673b5.tar.gz
Change GoogleSearch to use the new system-wide location opt-in setting
as was done with EnhancedGoogleSearchProvider. One difference is that if a system does not have GoogleSettingsProvider, we will simply omit the location request for GoogleSearch.
-rw-r--r--src/com/android/googlesearch/GoogleSearch.java58
-rw-r--r--src/com/android/googlesearch/LocationUtils.java104
2 files changed, 149 insertions, 13 deletions
diff --git a/src/com/android/googlesearch/GoogleSearch.java b/src/com/android/googlesearch/GoogleSearch.java
index ba52ed2..e08f2b1 100644
--- a/src/com/android/googlesearch/GoogleSearch.java
+++ b/src/com/android/googlesearch/GoogleSearch.java
@@ -24,11 +24,15 @@ import java.util.Locale;
import android.app.Activity;
import android.app.SearchManager;
+import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
+import android.location.Location;
+import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Browser;
-import android.provider.SearchRecentSuggestions;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -45,11 +49,24 @@ public class GoogleSearch extends Activity {
// "source" parameter for Google search requests from unknown sources (e.g. apps). This will get
// prefixed with the string 'android-' before being sent on the wire.
final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
+
+ private LocationUtils mLocationUtils;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mLocationUtils = LocationUtils.getLocationUtils(this);
+ Intent intent = getIntent();
+ if ((intent != null) && Intent.ACTION_WEB_SEARCH.equals(intent.getAction())) {
+ handleWebSearchIntent(intent);
+ }
+ finish();
+ }
/**
- * This function is the same exact one as found in
- * com.google.android.providers.genie.GenieLauncher. If you are changing this make sure you
- * change both.
+ * NOTE: This function is similar to the one found in
+ * com.google.android.providers.enhancedgooglesearch.Launcher. If you are changing this
+ * make sure you change both.
*/
private void handleWebSearchIntent(Intent intent) {
String query = intent.getStringExtra(SearchManager.QUERY);
@@ -94,21 +111,36 @@ public class GoogleSearch extends Activity {
+ "&source=android-" + source
+ "&q=" + URLEncoder.encode(query, "UTF-8");
Intent launchUriIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
- launchUriIntent.putExtra(Browser.EXTRA_APPEND_LOCATION, true);
+ launchUriIntent.putExtra(Browser.EXTRA_POST_DATA, getLocationData());
launchUriIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(launchUriIntent);
} catch (UnsupportedEncodingException e) {
Log.w(TAG, "Error", e);
}
}
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Intent intent = getIntent();
- if ((intent != null) && Intent.ACTION_WEB_SEARCH.equals(intent.getAction())) {
- handleWebSearchIntent(intent);
+
+ private byte[] getLocationData() {
+ byte[] postData = null;
+ ContentResolver cr = getContentResolver();
+
+ // Don't send any location if the system does not have GoogleSettingsProvider.
+ if (!mLocationUtils.systemHasGoogleSettingsProvider()) return postData;
+
+ if (!mLocationUtils.userRespondedToLocationOptIn()) {
+ // Bring up the consent dialog if it the user has yet responded to it. We
+ // will not send the location info for this query.
+ mLocationUtils.showLocationOptIn();
+ } else if (mLocationUtils.userAcceptedLocationOptIn() &&
+ Settings.Secure.isLocationProviderEnabled(cr, LocationManager.NETWORK_PROVIDER)) {
+ Location location = ((LocationManager) getSystemService(
+ Context.LOCATION_SERVICE)).getLastKnownLocation(
+ LocationManager.NETWORK_PROVIDER);
+ if (location != null) {
+ StringBuilder str = new StringBuilder("action=devloc&sll=");
+ str.append(location.getLatitude()).append(',').append(location.getLongitude());
+ postData = str.toString().getBytes();
+ }
}
- finish();
+ return postData;
}
}
diff --git a/src/com/android/googlesearch/LocationUtils.java b/src/com/android/googlesearch/LocationUtils.java
new file mode 100644
index 0000000..e684776
--- /dev/null
+++ b/src/com/android/googlesearch/LocationUtils.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.googlesearch;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+/**
+ * Utility methods for dealing with location (such as opt-in stuff).
+ */
+public class LocationUtils {
+ private Context mContext;
+
+ // The singleton object.
+ private static LocationUtils sLocationUtils;
+
+ /**
+ * Gets the singleton.
+ */
+ public static synchronized LocationUtils getLocationUtils(Context context) {
+ if (sLocationUtils == null) {
+ sLocationUtils = new LocationUtils(context);
+ }
+ return sLocationUtils;
+ }
+
+ /**
+ * Private constructor for singleton class; use {@link #getLocationUtils(Context)}.
+ */
+ private LocationUtils(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Identifies whether this system has the GoogleSettingsProvider, which determines
+ * whether the other methods in this class are relevant, or if we should just avoid
+ * using location.
+ */
+ public boolean systemHasGoogleSettingsProvider() {
+ try {
+ return mContext.getPackageManager().getPackageInfo(
+ "com.google.android.providers.settings", 0) != null;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Checks whether the user has responded (either positively or negatively) to the
+ * Google location opt-in.
+ */
+ public boolean userRespondedToLocationOptIn() {
+ return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Secure.USE_LOCATION_FOR_SERVICES, 2) != 2;
+ }
+
+ /**
+ * Shows the location opt-in because the user has not yet responded to it. If
+ * we have GoogleSettingsProvider, this fires up the 'security & location' settings
+ * and requests to show the opt-in. If we do not, this does nothing.
+ */
+ public void showLocationOptIn() {
+ if (systemHasGoogleSettingsProvider()) {
+ Intent consent = new Intent(
+ android.provider.Settings.ACTION_SECURITY_SETTINGS);
+ consent.putExtra("SHOW_USE_LOCATION", true);
+ consent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(consent);
+ }
+ }
+
+ /**
+ * Indicates whether the user has accepted the Google location opt-in. Checks the appropriate
+ * setting depending on whether we are using the GoogleSettingsProvider setting or our
+ * own package-local setting.
+ *
+ * If the answer is false, it could be because the user responded negatively to the opt-in,
+ * or because the system does not have GoogleSettingsProvider. Use
+ * {@link #userRespondedToLocationOptIn()} to distinguish between these two cases.
+ */
+ public boolean userAcceptedLocationOptIn() {
+ if (systemHasGoogleSettingsProvider()) {
+ return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Secure.USE_LOCATION_FOR_SERVICES, 2) == 1;
+ } else {
+ return false;
+ }
+ }
+}