我正在学习本教程http://wptrafficanalyzer.in/blog/adding-google-places-autocomplete-api-as-custom-suggestions-in-android-search-dialog/但当我试图在搜索框中搜索时,它什么也没有显示
其他信息:
当用户尝试在自动完成框中输入位置地址时,我想显示建议。那么如何解决这个问题。谢谢你的帮助。
密码
主要活动。爪哇语
package in.wptrafficanalyzer.locationsearchdialogv2;
import android.app.SearchManager;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor>{
GoogleMap mGoogleMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mGoogleMap = fragment.getMap();
handleIntent(getIntent());
}
private void handleIntent(Intent intent){
if(intent.getAction().equals(Intent.ACTION_SEARCH)){
doSearch(intent.getStringExtra(SearchManager.QUERY));
}else if(intent.getAction().equals(Intent.ACTION_VIEW)){
getPlace(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
handleIntent(intent);
}
private void doSearch(String query){
Bundle data = new Bundle();
data.putString("query", query);
getSupportLoaderManager().restartLoader(0, data, this);
}
private void getPlace(String query){
Bundle data = new Bundle();
data.putString("query", query);
getSupportLoaderManager().restartLoader(1, data, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()){
case R.id.action_search:
onSearchRequested();
break;
}
return super.onMenuItemSelected(featureId, item);
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle query) {
CursorLoader cLoader = null;
if(arg0==0)
cLoader = new CursorLoader(getBaseContext(), PlaceProvider.SEARCH_URI, null, null, new String[]{ query.getString("query") }, null);
else if(arg0==1)
cLoader = new CursorLoader(getBaseContext(), PlaceProvider.DETAILS_URI, null, null, new String[]{ query.getString("query") }, null);
return cLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor c) {
showLocations(c);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
// TODO Auto-generated method stub
}
private void showLocations(Cursor c){
MarkerOptions markerOptions = null;
LatLng position = null;
mGoogleMap.clear();
while(c.moveToNext()){
markerOptions = new MarkerOptions();
position = new LatLng(Double.parseDouble(c.getString(1)),Double.parseDouble(c.getString(2)));
markerOptions.position(position);
markerOptions.title(c.getString(0));
mGoogleMap.addMarker(markerOptions);
}
if(position!=null){
CameraUpdate cameraPosition = CameraUpdateFactory.newLatLng(position);
mGoogleMap.animateCamera(cameraPosition);
}
}
}
PlaceDetailsJSONParser.java
package in.wptrafficanalyzer.locationsearchdialogv2;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
public class PlaceDetailsJSONParser {
/** Receives a JSONObject and returns a list */
public List<HashMap<String,String>> parse(JSONObject jObject){
Double lat = Double.valueOf(0);
Double lng = Double.valueOf(0);
String formattedAddress = "";
HashMap<String, String> hm = new HashMap<String, String>();
List<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>();
try {
lat = (Double)jObject.getJSONObject("result").getJSONObject("geometry").getJSONObject("location").get("lat");
lng = (Double)jObject.getJSONObject("result").getJSONObject("geometry").getJSONObject("location").get("lng");
formattedAddress = (String) jObject.getJSONObject("result").get("formatted_address");
} catch (JSONException e) {
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
hm.put("lat", Double.toString(lat));
hm.put("lng", Double.toString(lng));
hm.put("formatted_address",formattedAddress);
list.add(hm);
return list;
}
}
PlaceJSONParser。Java语言
package in.wptrafficanalyzer.locationsearchdialogv2;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class PlaceJSONParser {
/** Receives a JSONObject and returns a list */
public List<HashMap<String,String>> parse(JSONObject jObject){
JSONArray jPlaces = null;
try {
/** Retrieves all the elements in the 'places' array */
jPlaces = jObject.getJSONArray("predictions");
} catch (JSONException e) {
e.printStackTrace();
}
/** Invoking getPlaces with the array of json object
* where each json object represent a place
*/
return getPlaces(jPlaces);
}
private List<HashMap<String, String>> getPlaces(JSONArray jPlaces){
int placesCount = jPlaces.length();
List<HashMap<String, String>> placesList = new ArrayList<HashMap<String,String>>();
HashMap<String, String> place = null;
/** Taking each place, parses and adds to list object */
for(int i=0; i<placesCount;i++){
try {
/** Call getPlace with place JSON object to parse the place */
place = getPlace((JSONObject)jPlaces.get(i));
placesList.add(place);
} catch (JSONException e) {
e.printStackTrace();
}
}
return placesList;
}
/** Parsing the Place JSON object */
private HashMap<String, String> getPlace(JSONObject jPlace){
HashMap<String, String> place = new HashMap<String, String>();
String id="";
String reference="";
String description="";
try {
description = jPlace.getString("description");
id = jPlace.getString("id");
reference = jPlace.getString("reference");
place.put("description", description);
place.put("_id",id);
place.put("reference",reference);
} catch (JSONException e) {
e.printStackTrace();
}
return place;
}
}
PlaceProvider.java
package in.wptrafficanalyzer.locationsearchdialogv2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.util.Log;
public class PlaceProvider extends ContentProvider {
public static final String AUTHORITY = "in.wptrafficanalyzer.locationsearchdialogv2.PlaceProvider";
public static final Uri SEARCH_URI = Uri.parse("content://"+AUTHORITY+"/search");
public static final Uri DETAILS_URI = Uri.parse("content://"+AUTHORITY+"/details");
private static final int SEARCH = 1;
private static final int SUGGESTIONS = 2;
private static final int DETAILS = 3;
// Obtain browser key from https://code.google.com/apis/console
String mKey = "key=YOUR_BROWSER_KEY";
// Defines a set of uris allowed with this content provider
private static final UriMatcher mUriMatcher = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// URI for "Go" button
uriMatcher.addURI(AUTHORITY, "search", SEARCH );
// URI for suggestions in Search Dialog
uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY,SUGGESTIONS);
// URI for Details
uriMatcher.addURI(AUTHORITY, "details",DETAILS);
return uriMatcher;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor c = null;
PlaceJSONParser parser = new PlaceJSONParser();
PlaceDetailsJSONParser detailsParser = new PlaceDetailsJSONParser();
String jsonString = "";
String jsonPlaceDetails = "";
List<HashMap<String, String>> list = null;
List<HashMap<String, String>> detailsList = null;
MatrixCursor mCursor = null;
switch(mUriMatcher.match(uri)){
case SEARCH:
// Defining a cursor object with columns description, lat and lng
mCursor = new MatrixCursor(new String[] { "description","lat","lng" });
// Create a parser object to parse places in JSON format
parser = new PlaceJSONParser();
// Create a parser object to parse place details in JSON format
detailsParser = new PlaceDetailsJSONParser();
// Get Places from Google Places API
jsonString = getPlaces(selectionArgs);
try {
// Parse the places ( JSON => List )
list = parser.parse(new JSONObject(jsonString));
// Finding latitude and longitude for each places using Google Places Details API
for(int i=0;i<list.size();i++){
HashMap<String, String> hMap = (HashMap<String, String>) list.get(i);
detailsParser =new PlaceDetailsJSONParser();
// Get Place details
jsonPlaceDetails = getPlaceDetails(hMap.get("reference"));
// Parse the details ( JSON => List )
detailsList = detailsParser.parse(new JSONObject(jsonPlaceDetails));
// Creating cursor object with places
for(int j=0;j<detailsList.size();j++){
HashMap<String, String> hMapDetails = detailsList.get(j);
// Adding place details to cursor
mCursor.addRow(new String[]{ hMap.get("description") , hMapDetails.get("lat") , hMapDetails.get("lng") });
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c = mCursor;
break;
case SUGGESTIONS :
// Defining a cursor object with columns id, SUGGEST_COLUMN_TEXT_1, SUGGEST_COLUMN_INTENT_EXTRA_DATA
mCursor = new MatrixCursor(new String[] { "_id", SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA } );
// Creating a parser object to parse places in JSON format
parser = new PlaceJSONParser();
// Get Places from Google Places API
jsonString = getPlaces(selectionArgs);
try {
// Parse the places ( JSON => List )
list = parser.parse(new JSONObject(jsonString));
// Creating cursor object with places
for(int i=0;i<list.size();i++){
HashMap<String, String> hMap = (HashMap<String, String>) list.get(i);
// Adding place details to cursor
mCursor.addRow(new String[] { Integer.toString(i), hMap.get("description"), hMap.get("reference") });
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c = mCursor;
break;
case DETAILS :
// Defining a cursor object with columns description, lat and lng
mCursor = new MatrixCursor(new String[] { "description","lat","lng" });
detailsParser = new PlaceDetailsJSONParser();
jsonPlaceDetails = getPlaceDetails(selectionArgs[0]);
try {
detailsList = detailsParser.parse(new JSONObject(jsonPlaceDetails));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<detailsList.size();j++){
HashMap<String, String> hMapDetails = detailsList.get(j);
mCursor.addRow(new String[]{ hMapDetails.get("formatted_address") , hMapDetails.get("lat") , hMapDetails.get("lng") });
}
c = mCursor;
break;
}
return c;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
return false;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
iStream.close();
urlConnection.disconnect();
}
return data;
}
private String getPlaceDetailsUrl(String ref){
// reference of place
String reference = "reference="+ref;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = reference+"&"+sensor+"&"+mKey;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/place/details/"+output+"?"+parameters;
return url;
}
private String getPlacesUrl(String qry){
try {
qry = "input=" + URLEncoder.encode(qry, "utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
// Sensor enabled
String sensor = "sensor=false";
// place type to be searched
String types = "types=geocode";
// Building the parameters to the web service
String parameters = qry+"&"+types+"&"+sensor+"&"+mKey;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;
return url;
}
private String getPlaces(String[] params){
// For storing data from web service
String data = "";
String url = getPlacesUrl(params[0]);
try{
// Fetching the data from web service in background
data = downloadUrl(url);
}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}
private String getPlaceDetails(String reference){
String data = "";
String url = getPlaceDetailsUrl(reference);
try {
data = downloadUrl(url);
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
}
anifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.wptrafficanalyzer.locationsearchdialogv2"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<!-- Protect the map component of the application using application signature -->
<permission
android:name="in.wptrafficanalyzer.locationsearchdialogv2.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<!-- Allows to receive map -->
<uses-permission android:name="in.wptrafficanalyzer.locationsearchdialogv2.permission.MAPS_RECEIVE" />
<!-- Used by the Google Maps Android API V2 to download map tiles from Google Maps servers -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Allows the Google Maps Android API V2 to cache map tile data in the device's external storage area -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Allows the Google Maps Android API V2 to use WiFi or mobile cell data (or both) to determine the device's location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Allows the Google Maps Android API V2 to use the Global Positioning System (GPS)
to determine the device's location to within a very small area -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Allows to contact Google Serves -->
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!-- Google Maps Android API V2 requires OpenGL ES version 2 -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="in.wptrafficanalyzer.locationsearchdialogv2.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<!-- Points to searchable activity -->
<meta-data android:name="android.app.default_searchable"
android:value=".MainActivity" />
<!-- Points to searchable meta data -->
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
<provider
android:name=".PlaceProvider"
android:authorities="in.wptrafficanalyzer.locationsearchdialogv2.PlaceProvider"
android:exported="false" />
<!-- Specifies the Android API Key, which is obtained from Google API Console -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="YOUR_ANDROID_API_KEY" />
</application>
</manifest>
Logcat公司
04-17 05:23:22.709: D/PackageBroadcastService(1518): Received broadcast action=android.intent.action.PACKAGE_ADDED and uri=in.wptrafficanalyzer.locationsearchdialogv2
04-17 05:23:22.779: E/Icing(1518): Couldn't handle android.intent.action.PACKAGE_ADDED intent due to initialization failure.
04-17 05:23:22.779: I/PeopleContactsSync(1518): CP2 sync disabled
04-17 05:23:23.849: I/MultiDex(2227): load(/system/priv-app/PrebuiltGmsCore.apk, forceReload=false)
04-17 05:23:24.059: D/dalvikvm(2227): GC_FOR_ALLOC freed 187K, 10% free 3047K/3356K, paused 17ms, total 17ms
04-17 05:23:24.059: I/MultiDex(2227): Need extracted file /data/data/com.google.android.gms/files/secondary-dexes/PrebuiltGmsCore.apk.classes2.zip
04-17 05:23:24.059: I/MultiDex(2227): No extraction needed for /data/data/com.google.android.gms/files/secondary-dexes/PrebuiltGmsCore.apk.classes2.zip of size 1547068
04-17 05:23:25.119: D/dalvikvm(2227): GC_FOR_ALLOC freed 354K, 13% free 3204K/3680K, paused 75ms, total 76ms
04-17 05:23:35.429: I/MultiDex(2288): load(/system/priv-app/PrebuiltGmsCore.apk, forceReload=false)
04-17 05:23:35.579: D/dalvikvm(2288): GC_FOR_ALLOC freed 184K, 10% free 3053K/3356K, paused 4ms, total 4ms
04-17 05:23:35.599: I/MultiDex(2288): Need extracted file /data/data/com.google.android.gms/files/secondary-dexes/PrebuiltGmsCore.apk.classes2.zip
04-17 05:23:35.609: I/MultiDex(2288): No extraction needed for /data/data/com.google.android.gms/files/secondary-dexes/PrebuiltGmsCore.apk.classes2.zip of size 1547068
04-17 05:23:35.649: D/PackageBroadcastService(2288): Received broadcast action=android.intent.action.PACKAGE_CHANGED and uri=com.google.android.gms
04-17 05:23:35.649: I/PackageBroadcastService(2288): Null package name or gms related package. Ignoreing.
04-17 05:23:35.699: D/dalvikvm(2288): No JNI_OnLoad found in /system/lib/libAppDataSearch.so 0xb2fd39d8, skipping init
04-17 05:23:35.699: E/Icing(2288): Native load error: Version mismatch 4323070 vs 4323030
04-17 05:23:36.019: I/Icing(2288): Storage manager: low false usage 9.34KB avail 122.16MB capacity 167.55MB
04-17 05:23:36.179: D/dalvikvm(2288): GC_FOR_ALLOC freed 355K, 13% free 3195K/3672K, paused 4ms, total 4ms
04-17 05:23:36.199: E/Icing(2288): Error initializing, resetting corpora: Could not create native index
04-17 05:23:36.209: E/Icing(2288): Internal init failed
04-17 05:23:36.209: E/Icing(2288): Couldn't handle android.intent.action.PACKAGE_CHANGED intent due to initialization failure.
关于maps api的错误,
您不需要使用:
<permission
android:name="in.wptrafficanalyzer.locationsearchdialogv2.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<!-- Allows to receive map -->
请在应用程序标签下方使用此选项:
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
如本文所述,
应用的AndroidManifest.xml中所需的元数据标记不存在。
关于位置和自动完成,请尝试一下,
https://developers.google.com/places/training/autocomplete-android
我有这样一个dialogfragment类: 在其布局xml文件中。xml它包含一个自动完成的文本视图。这是from的代码。xml文件 我使用以下代码在单击按钮时弹出对话框片段。所以我给出了这样的答案: 现在我需要创建一个自动完成文本视图的对象,它应该向我展示建议。我有一个数组列表,其中包含自动完成文本视图的数组适配器的数据,我这样编码(这里actv1是自动完成文本视图的对象): 但问题是我不知道
本文向大家介绍自动完成的搜索框javascript实现,包括了自动完成的搜索框javascript实现的使用技巧和注意事项,需要的朋友参考一下 在很多需要搜索的网站, 都会有一个自动完成的搜索框. 方便用户查找他们想要的搜索词. 帮助用户快速找到自己想要的结果. 这种方式是比较友好的. 所以是比较提倡使用的. 我们这次就来实现这一效果. 我们通过两篇文章来进行讲解. 首先我们来完成界面的设计布局.
我试图得到一个自动完成列表弹出,使用此链接作为指导。 我得到的错误消息: w/filter:performFiltering()期间发生异常!java.lang.nullPointerException:collection==null at java.util.ArrayList.(arrayList.java:94)at android.widget.arrayAdapter$arrayFil
本文向大家介绍JavaScript实现搜索框的自动完成功能(一),包括了JavaScript实现搜索框的自动完成功能(一)的使用技巧和注意事项,需要的朋友参考一下 在很多需要搜索的网站, 都会有一个自动完成的搜索框. 方便用户查找他们想要的搜索词. 帮助用户快速找到自己想要的结果. 这种方式是比较友好的. 所以是比较提倡使用的. 先给大家展示下效果图: 实现这个功能需要服务端配合。客户端通过脚
问题内容: 我正在对具有字符串类型数组的文档字段进行自动完成建议。我的文件如下所示; 我正在 标签 字段上执行自动完成搜索。我的查询就像; 当用户键入“ word”时,我要显示“ wordland”和“ wordpress”。但是,我无法做到这一点。 您能帮上忙吗? 谢谢 问题答案: 您是否尝试过完成建议?解决问题的一种方法如下: 1)创建索引: 2)使用完成建议者类型创建映射: 3)添加文件:
嗨,我是primefaces的新手,我对数据表中显示的值有一些问题。我从sql数据库加载数据,并在dataTable中显示这些数据。有一个柱子叫做“评论”,里面有一个按钮。如果你点击这个按钮,就会打开一个对话框。在这个对话框框架内,也应该有一些与我在dataTable中显示的相同的值,但它不起作用。我无法显示该对话框框中的值。我在谷歌上搜索了很多次,也尝试了很多次,但都无济于事。下面是xhtml: