我正在尝试进行一项活动,使我能够按名称搜索餐馆。为此,我正在使用 android 搜索小部件。
我还使用 google places API Text Search Service 来获取与搜索查询匹配的餐厅列表。
我基本上有两个课程:
- 我将 searchableActivity 称为“最近的餐馆”的班级表格
- 显示我的结果的类。“可搜索的活动”
我正在使用异步任务来获取 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 中使用它