2

我正在尝试进行一项活动,使我能够按名称搜索餐馆。为此,我正在使用 android 搜索小部件。

我还使用 google places API Text Search Service 来获取与搜索查询匹配的餐厅列表。

我基本上有两个课程:

  1. 我将 searchableActivity 称为“最近的餐馆”的班级表格
  2. 显示我的结果的类。“可搜索的活动”

我正在使用异步任务来获取 google 地方 API 文本搜索服务并在用户界面中显示它们。

我的问题是当我尝试从 NearestRestaurantsActivity 调用 SearchableActivity 时,应用程序崩溃了。使用堆栈跟踪我发现问题出在哪里: doInbackground() 中的 getTextPlaces() 返回 null ,我猜这是因为 http post 连接不起作用,而且我真的不知道如何遇到这个问题我搜索了很多但是没有任何有价值的结果!!

这是我正在使用的代码:

我的清单文件:

<!-- Internet Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Access Location -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- List of nearest restaurants -->
<activity
android:name="com.nearest_restaurants.Nearest_Restaurants"
android:label="nearest restaurants" >
      <meta-data
       android:name="android.app.default_searchable"
       android:value=".nearest_restaurants.SearchableActivity" />
</activity>
<!--Contains the list of restaurants  that match  the text query -->
<activity android:name=".nearest_restaurants.SearchableActivity"
          android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
     <meta-data android:name="android.app.searchable"
                android:resource="@xml/searchable"/>
</activity>

我称之为 SearchableActivity的最近餐厅活动

      /*****search restaurant by name with the search widget***/

     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
     MenuInflater inflater = getMenuInflater();
     inflater.inflate(R.menu.options_menu, menu);
     Log.d("oncreateOptionMenu",""+menu);
     SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
     SearchView searchView =
             (SearchView) menu.findItem(R.id.searchit).getActionView();
      searchView.setSearchableInfo(
             searchManager.getSearchableInfo(getComponentName()));
     //searchView.setSubmitButtonEnabled(true);

    return true;
}

可搜索活动:

     @Override
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

      setContentView(R.layout.nearest_restaurants);
      Intent intent = getIntent();
      if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
           query = intent.getStringExtra(SearchManager.QUERY);
          Log.d("Event",query);
          //an asychronous task to search the restaurants by name 
          LoadPlacesByText loadplaces= new LoadPlacesByText();
          loadplaces.execute();  
      }

 /**
     * Background Async Task to Load Google places
     * */
    class LoadPlacesByText extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */


        /**
         * getting Places JSON
         * */
        protected String doInBackground(String... args) {
            // creating Places class object
            googlePlaces = new GooglePlaces();
            nearPlaces = new PlacesList();
            try {
                // Separeate your place types by PIPE symbol "|"
                // If you want all types places make it as null
                // Check list of types supported by google


                String types = "cafe|restaurant"; // Listing places only cafes, restaurants

                // Radius in meters - increase this value if you don't find any places
                double radius = 100; // 1000 meters 
                Log.d( "QUERY", query);
                // get  places list

                nearPlaces = googlePlaces.getTextPlaces(query,gps.getLatitude(),gps.getLongitude() ,radius, types);


            } catch (Exception e) {
                Log.d( "QUERY", query);
                Log.d("Exeptionstack", ""+e);
                e.printStackTrace();
            }
            return "n";
        }


        protected void onPostExecute(String file_url) {
            // dismiss the dialog after getting all products
            //pDialog.dismiss();
            // updating UI from Background Thread

                    /**
                     * Updating parsed Places into LISTVIEW
                     * */
                    // Get json response status

                    String status = nearPlaces.status;

                    // Check for all possible status
                    if(status.equals("OK")){
                        // Successfully got places details
                        if (nearPlaces.results != null) {
                            // loop through each place
                            for (Place p : nearPlaces.results) {
                                HashMap<String, String> map = new HashMap<String, String>();

                                // Place reference won't display in list View - it will be hidden
                                // Place reference is used to get "place full details"
                                map.put(KEY_REFERENCE, p.reference);

                                // Place name
                                map.put(KEY_NAME, p.name);


                                // adding HashMap to ArrayList
                                placesListItems.add(map);
                            }
                            // list adapter
                            ListAdapter adapter = new SimpleAdapter(getApplicationContext(), placesListItems,
                                    R.layout.list_item,
                                    new String[] { KEY_REFERENCE, KEY_NAME}, new int[] {
                                            R.id.reference, R.id.name });

                            // Adding data into listview
                            lv.setAdapter(adapter);
                        }
                    }
                    else if(status.equals("ZERO_RESULTS")){
                        // Zero results found
                        alert.showAlertDialog(getApplicationContext(), "Near Places",
                                "Sorry no places found. Try to change the types of places",
                                false);
                    }
                    else if(status.equals("UNKNOWN_ERROR"))
                    {
                        alert.showAlertDialog(getApplicationContext(), "Places Error",
                                "Sorry unknown error occured.",
                                false);
                    }
                    else if(status.equals("OVER_QUERY_LIMIT"))
                    {
                        alert.showAlertDialog(getApplicationContext(), "Places Error",
                                "Sorry query limit to google places is reached",
                                false);
                    }
                    else if(status.equals("REQUEST_DENIED"))
                    {
                        alert.showAlertDialog(getApplicationContext(), "Places Error",
                                "Sorry error occured. Request is denied",
                                false);
                    }
                    else if(status.equals("INVALID_REQUEST"))
                    {
                        alert.showAlertDialog(getApplicationContext(), "Places Error",
                                "Sorry error occured. Invalid Request",
                                false);
                    }
                    else
                    {
                        alert.showAlertDialog(getApplicationContext(), "Places Error",
                                "Sorry error occured.",
                                false);
                    }
                }


    }

getTextPlaces方法:

     public PlacesList getTextPlaces(String query,double latitude, double longitude,  double radius, String types) 
   throws Exception {

    this._latitude = latitude;
    this._longitude = longitude;
    this._radius = radius;


    try {

        HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
        HttpRequest request = httpRequestFactory
                .buildGetRequest(new GenericUrl(PLACES_TEXT_SEARCH_URL));
        request.getUrl().put("key", API_KEY);
        request.getUrl().put("location", _latitude + "," + _longitude);
        request.getUrl().put("radius", _radius); // in meters
        request.getUrl().put("sensor", "true");
        if(types != null)
            request.getUrl().put("types", types);
        request.getUrl().put("query", query);
        request.getUrl().put("sensor", "true");

        PlacesList list = request.execute().parseAs(PlacesList.class);
        // Check log cat for places response status
        Log.d("Places Status", "" + list.status);
        return list;

    } catch (HttpResponseException e) {
        Log.d("Error:", e.getMessage());
        Log.d("Its an Httpresponse exeption","");
        return null;
    }
}

/**
 * Creating http request Factory
 * */
public static HttpRequestFactory createRequestFactory(
        final HttpTransport transport) {
    return transport.createRequestFactory(new HttpRequestInitializer() {
        public void initialize(HttpRequest request) {
            GoogleHeaders headers = new GoogleHeaders();
            headers.setApplicationName("app_name");
            request.setHeaders(headers);
            JsonHttpParser parser = new JsonHttpParser(new JacksonFactory());
            request.addParser(parser);
        }
    });
}

这是堆栈跟踪

    W/System.err(14206): java.lang.NullPointerException 
    W/System.err(14206): at      com.nearest_restaurants.SearchableActivity$LoadPlacesByText.doInBackground(SearchableActivi ty.java:160)
    W/System.err(14206):    at com.nearest_restaurants.SearchableActivity$LoadPlacesByText.doInBackground(SearchableActivity.java:1)
    W/System.err(14206):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    W/System.err(14206):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    W/System.err(14206):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    W/System.err(14206):    at  android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
   W/System.err(14206):     at  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
   W/System.err(14206):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
   W/System.err(14206):     at java.lang.Thread.run(Thread.java:856)


   E/AndroidRuntime(14206): FATAL EXCEPTION: main   
   E/AndroidRuntime(14206): java.lang.NullPointerException// comes from nearplaces in doInbackground
   E/AndroidRuntime(14206):     at com.nearest_restaurants.SearchableActivity$LoadPlacesByText.onPostExecute(SearchableActivity.java:191)
   E/AndroidRuntime(14206):     at com.nearest_restaurants.SearchableActivity$LoadPlacesByText.onPostExecute(SearchableActivity.java:1)
   E/AndroidRuntime(14206):     at android.os.AsyncTask.finish(AsyncTask.java:631)
   E/AndroidRuntime(14206):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
   E/AndroidRuntime(14206):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
   E/AndroidRuntime(14206):     at android.os.Handler.dispatchMessage(Handler.java:99)
   E/AndroidRuntime(14206):     at android.os.Looper.loop(Looper.java:137)
   E/AndroidRuntime(14206):     at android.app.ActivityThread.main(ActivityThread.java:4898)
   E/AndroidRuntime(14206):     at java.lang.reflect.Method.invokeNative(Native Method)
   E/AndroidRuntime(14206):     at java.lang.reflect.Method.invoke(Method.java:511)
   E/AndroidRuntime(14206):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
   E/AndroidRuntime(14206):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
   E/AndroidRuntime(14206):     at dalvik.system.NativeStart.main(Native Method)

PS:我在 NearestPlacesActivity 中放置了一个带有按钮的编辑文本,在 onclick 事件中我开始了另一个活动,我调用 LoadPlacesByText() 并且它工作正常!所以我不知道这是否与搜索小部件有关。

我从这篇文章http://www.androidhive.info/2012/08/android-working-with-google-places-and-maps-tutorial/修改了一些 LoadPlaces asynctask 以在 LoadPlacesByText 中使用它

4

2 回答 2

0

我建议你使用 Apache 的 org.apache.http.client 包中的类。它只会减少你的努力。示例代码:

public static String connectToServer(String url, List<NameValuePair> nameValuePairs) {
        String result = null;
        HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
        HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);

        // Instantiate an HttpClient 
        HttpClient httpclient = new DefaultHttpClient(httpParams); 
        HttpPost httppost = new HttpPost(url); // Instantiate a POST HTTP method
        try {
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            result = httpclient.execute(httppost, responseHandler);

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    } 

希望它可以帮助你。

于 2013-08-05T08:20:23.080 回答
0

最后我弄清楚是什么问题,我不得不增加连接超时所以添加了这两行代码:

在 doInBackground() 中:

         Thread.sleep(1000);

在 getTextPlaces() 中:

         request.setConnectTimeout(50000);

希望能帮助到你

于 2013-08-06T12:02:30.787 回答