异步任务在使用可搜索活动时不起作用:应用程序崩溃

时间:2013-08-02 17:01:47

标签: android android-asynctask http-post google-places-api

我正在尝试制作一项活动,让我可以按名称搜索餐馆。 因为我正在使用android搜索小部件。

我还使用google places API文字搜索服务来获取与搜索查询匹配的餐馆列表。

我基本上有两个班级:

  1. 我称之为searchableActivity“最近的餐馆”的课程表格
  2. 显示结果的课程。 “搜索活动”
  3. 我正在使用一个非同步任务来获取谷歌放置API文本搜索服务并在UI中显示它们。

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

    这是我正在使用的代码:

    我的清单文件:

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

    SearchableActivity:

         @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中添加了一个带有按钮的edittext,在onclick事件中,我启动了另一个活动,我调用了LoadPlacesByText(),它运行正常! 所以我不知道这是否有关于搜索小部件的事情。

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

2 个答案:

答案 0 :(得分: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;
    } 

希望它对你有所帮助。

答案 1 :(得分:0)

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

在doInBackground()中

         Thread.sleep(1000);

和getTextPlaces():

         request.setConnectTimeout(50000);

希望有所帮助