0
Googleプレイスからデータを取得し、リストビューにデータを表示するAndroidアプリケーションを作成しています。問題は、asynctaskがリフレッシュしてhttpリクエストを作成し続け、最終的にアダプタのoutOfBoundsにつながるということです。私は、デバイスの場所を取得し、それをブロードキャストレシーバを通してロケーションを取得するアクティビティに送信するサービスを使用しています。AsyncTaskがonResumeを繰り返し続けます
onResumeが引き続き呼び出される問題はありますか?
ブロードキャスト受信機のonRecieveメソッドは絶えず呼び出されていますか?
サービス上のlocationListenerは繰り返していますか?
ありがとうございます!
リストビュー、broadcastReceiverとAsyncTaskと活性:
public class NearbyLocationsActivity extends BaseActivity implements AsyncDelegate {
private Location mLastLocation;
private GetLocations nearbyLocations;
private PlaceAdapter adapter;
private ArrayList<Place> nearbyPlaces;
private double mLat;
private double mLong;
private ListView locationsList;
public Spinner typesSpinner;
private BroadcastReceiver broadcastReceiver;
private String radius = "10000";
private int selectedSpinnerIndex;
private String [] types = {"everything", "restaurant", "bar", "museum", "night_club", "cafe", "movie_theater"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nearby_locations);
locationsList = (ListView) findViewById(R.id.locations_list);
typesSpinner = (Spinner) findViewById(R.id.type_spinner);
nearbyPlaces = new ArrayList();
adapter = new PlaceAdapter(getApplicationContext(), nearbyPlaces);
locationsList.setAdapter(adapter);
if(!runtimePermissions()) {
enableService();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
return true;
}
public void enableService() {
Intent i = new Intent(getApplicationContext(), LocationService.class);
startService(i);
}
private boolean runtimePermissions() {
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return true;
}
return false;
}
@Override
public void onResume() {
super.onResume();
if (broadcastReceiver == null) {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mLastLocation = (Location) intent.getExtras().get("coordinates");
mLat = mLastLocation.getLatitude();
mLong = mLastLocation.getLongitude();
nearbyLocations = new GetLocations(NearbyLocationsActivity.this);
nearbyLocations.execute();
}
};
}
registerReceiver(broadcastReceiver, new IntentFilter("location_updates"));
}
@Override
public void onDestroy() {
super.onDestroy();
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
}
}
@Override
public void onStop() {
Intent i = new Intent(getApplicationContext(), LocationService.class);
stopService(i);
super.onStop();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
enableService();
} else {
runtimePermissions();
}
}
}
@Override
public void asyncComplete(boolean success) {
typesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedSpinnerIndex = typesSpinner.getSelectedItemPosition();
new GetLocations(NearbyLocationsActivity.this).execute();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
selectedSpinnerIndex = 0;
}
});
locationsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Place p = adapter.getItem(position);
Intent intent = new Intent(getApplicationContext(), CreateEventActivity.class);
intent.putExtra("selectedPlace", p);
startActivity(intent);
}
});
}
public class GetLocations extends AsyncTask<Void, Void, Void> {
private AsyncDelegate delegate;
public GetLocations (AsyncDelegate delegate){
this.delegate = delegate;
}
@Override
protected Void doInBackground(Void... params) {
nearbyPlaces.clear();
StringBuilder sb = new StringBuilder();
String http = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + mLat + "," + mLong +
"&radius=10000";
if (selectedSpinnerIndex != 0) {
http += "&types=" + types[selectedSpinnerIndex];
}
http += "&key=AIzaSyDFb37i6VGPj2EG6L7dLO5H7tDhLCqCW2k";
HttpURLConnection urlConnection;
try {
URL url = new URL(http);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
JSONObject jsonObject = new JSONObject(sb.toString());
JSONArray array = jsonObject.getJSONArray("results");
for (int i = 0; i < array.length(); i++) {
JSONObject placeLine = (JSONObject) array.get(i);
Place place = new Place();
JSONObject geometryLine = placeLine.getJSONObject("geometry");
JSONObject locationLine = geometryLine.getJSONObject("location");
Place.Location location = new Place.Location();
location.setLat(locationLine.getDouble("lat"));
location.setLon(locationLine.getDouble("lng"));
place.setLocation(location);
place.setIcon(placeLine.getString("icon"));
place.setPlaceId(placeLine.getString("place_id"));
String detailsHttp = "https://maps.googleapis.com/maps/api/place/details/json?key=AIzaSyDFb37i6VGPj2EG6L7dLO5H7tDhLCqCW2k&placeid=" + place.getPlaceId();
getPlaceDetails(detailsHttp, place);
place.setName(placeLine.getString("name"));
/*JSONArray typesJson = new JSONArray("types");
String [] types = new String[typesJson.length()];
for (int a = 0; i < typesJson.length(); i++) {
types[a] = typesJson.getString(a);
}
place.setTypes(types);*/
place.setVicinity(placeLine.getString("vicinity"));
try {
place.setRating(placeLine.getInt("rating"));
} catch (JSONException je) {
place.setRating(-1);
}
try {
JSONArray photosJson = placeLine.getJSONArray("photos");
//for (int k = 0; i < photosJson.length(); i++) {
JSONObject photoLine = (JSONObject) photosJson.get(0);
String photoHttp = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&" +
"photoreference=" + photoLine.getString("photo_reference") + "&key=AIzaSyDFb37i6VGPj2EG6L7dLO5H7tDhLCqCW2k";
place.setPhotoHttp(photoHttp);
//place.addPhotoHttp(photoHttp);
//}
} catch (JSONException je) {
place.setPhotoHttp(null);
}
nearbyPlaces.add(place);
}
} catch(MalformedURLException mue){
System.out.println("A malformed URL exception occurred. " + mue.getMessage());
} catch(IOException ioe){
System.out.println("A input/output exception occurred. " + ioe.getMessage());
} catch(JSONException je){
System.out.println("A JSON error occurred. " + je.getMessage());
}
return null;
}
public void getPlaceDetails(String http, Place p) {
StringBuilder sb = new StringBuilder();
HttpURLConnection urlConnection;
try {
URL url = new URL(http);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
JSONObject jsonObject = new JSONObject(sb.toString());
JSONObject resultsJson = jsonObject.getJSONObject("result");
String address = resultsJson.getString("formatted_address");
p.setAddress(address);
} catch(MalformedURLException mue){
System.out.println("A malformed URL exception occurred. " + mue.getMessage());
} catch(IOException ioe){
System.out.println("A input/output exception occurred. " + ioe.getMessage());
} catch(JSONException je){
System.out.println("A JSON error occurred. " + je.getMessage());
}
}
@Override
protected void onPostExecute(Void aVoid) {
// Thread is finished downloading and parsing JSON, asyncComplete is
adapter.notifyDataSetChanged();
delegate.asyncComplete(true);
}
}}
デバイスの位置を取得するためのサービス:
public class LocationService extends Service {
private LocationListener listener;
private LocationManager locationManager;
@Override
public void onCreate() {
super.onCreate();
listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_updates");
i.putExtra("coordinates", location);
sendBroadcast(i);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, listener);
}
@Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates(listener);
}
}
public IBinder onBind(Intent intent) {
return null;
}}
リストビュー用アダプター:
public class PlaceAdapter extends ArrayAdapter<Place> {
private Context mContext;
private ArrayList<Place> places;
public PlaceAdapter(Context context, ArrayList<Place> nearbyPlaces) {
super(context, R.layout.place_list_item, nearbyPlaces);
mContext = context;
this.places = nearbyPlaces;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.place_list_item, null);
final Place p = places.get(position);
TextView placeName = (TextView) view.findViewById(R.id.place_name);
placeName.setText(p.getName());
TextView placeAddress = (TextView) view.findViewById(R.id.place_address);
placeAddress.setText(p.getAddress());
ImageView placeImage = (ImageView) view.findViewById(R.id.place_picture);
if (p.getPhotoHttp() != null) {
Picasso.with(mContext).load(p.getPhotoHttp()).into(placeImage);
} else {
Picasso.with(mContext).load(p.getIcon()).into(placeImage);
}
return view;
}}