2017-04-21 40 views
0

我正在製作一個Android應用程序,它可以從Google地方獲取數據並在列表視圖中顯示數據。問題在於asynctask不斷刷新併發出http請求,最終導致適配器上出現outOfBounds。我正在使用服務來獲取設備的位置並將其發送到通過廣播接收器獲取位置的活動。AsyncTask不斷重複onResume

onResume一直在調用的問題?

廣播接收機的onRecieve方法是否被不斷調用?

服務上的locationListener是否重複?

在此先感謝!

與ListView中,廣播接收器和的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; 
}} 

爲ListView適配器:

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

回答

0
@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")); 
    } 
} 

移動註冊表terreceiver內部如果區域