2014-04-17 39 views
2

我正在關注本教程http://wptrafficanalyzer.in/blog/adding-google-places-autocomplete-api-as-custom-suggestions-in-android-search-dialog/

但是,當我嘗試搜索搜索框時,它什麼也沒有顯示。
爲什麼自動完成搜索對話框不顯示任何建議?

其他信息:



我想說明的建議,當用戶嘗試輸入位置地址自動完成框。那麼如何解決這個問題。謝謝你的幫助。

代碼

MainActivity.java

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; 
} 
} 


AndroidManifest。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. 
+0

你找到一個解決方案?我得到同樣的錯誤 – Sumedh

回答

1

有關錯誤有關地圖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" /> 

這裏所提供

A required meta-data tag in your app's AndroidManifest.xml does not exist.

關於地方和自動完成試試這個也許,

https://developers.google.com/places/training/autocomplete-android

相關問題