Pessoal estou desenvolvendo um aplicativo para meu tcc, com base no curso de Android III, a parte que usa o maps e coloca uma aluno lá de acordo com o endereço dele. Só que a minha vai exibir os estabelecimentos cadastrados, estou usando o servidor do Firebase como back-end , e preciso baixar a lista dos meus estabelecimentos de lá, para isso eu consulto e até ai tudo bem. O problema é em exibir essa lista no maps, ele usa várias threads para carregar parece e ele não deixa terminar de baixar minha lista do Firebase, ai dá o problema. Eu tentei resolver com notify e wait ,e AsyncTask e sem sucesso.
Se alguém poder ajudar agradeço muito, está muito em cima para mim e já pesquisei em muitos lugares e nada.
Segue meu código com notify e wait:
public class MapaFragment extends SupportMapFragment implements OnMapReadyCallback {
private final DatabaseReference database;
public static GoogleMap mapa;
private List<Bar> bares;
public MapaFragment(DatabaseReference database){
this.database = database;
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
this.mapa = googleMap;
try {
pegaBares();
bares.wait();
for(Bar bar : bares){
Toast.makeText(getContext(), "dentro do for", Toast.LENGTH_LONG).show();
Toast.makeText(getContext(), bar.getNome() + " - " + bar.getEndereco(), Toast.LENGTH_LONG).show();
LatLng coordenada = pegaCoordenadaDoEndereco(bar.getEndereco());
if(coordenada != null) {
MarkerOptions marcador = new MarkerOptions();
marcador.position(coordenada);
marcador.title(bar.getNome());
marcador.snippet(String.valueOf(bar.getTelefone()));
marcador.icon(BitmapDescriptorFactory.fromResource(R.drawable.copocheio));
MapaFragment.mapa.addMarker(marcador);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
new Localizador(getContext(), MapaFragment.this);
}
private LatLng pegaCoordenadaDoEndereco(String endereco) {
try{
Geocoder geocoder = new Geocoder(getContext());
List<Address> resultados = geocoder.getFromLocationName(endereco, 1);
if(!resultados.isEmpty()){
LatLng posicao = new LatLng(resultados.get(0).getLatitude(),
resultados.get(0).getLongitude());
return posicao;
}
}catch(IOException e){
e.printStackTrace();
}
return null;
}
public void centralizaEm(LatLng coordenada){
if(mapa != null){
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(coordenada, 17);
mapa.moveCamera(update);
MarkerOptions marcador = new MarkerOptions();
marcador.position(coordenada);
marcador.icon(BitmapDescriptorFactory.fromResource(R.drawable.copovazio));
mapa.addMarker(marcador);
}
}
private void pegaBares() {
bares = new ArrayList<>();
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Map<String, Object> map = (HashMap<String, Object>) snapshot.getValue();
String nome = String.valueOf(map.get("nome"));
String endereco = String.valueOf(map.get("endereco"));
String telefone = String.valueOf(map.get("telefone"));
String site = String.valueOf(map.get("site"));
String email = String.valueOf(map.get("email"));
if (endereco != null) {
Bar bar = new Bar(nome, endereco, telefone, site, email);
bares.add(bar);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
bares.notify();
}
}
dando esse erro:
09-30 16:43:23.632 17412-17412/br.com.tcc.searchdrink E/UncaughtException: java.lang.IllegalMonitorStateException: object not locked by thread before notify()
at java.lang.Object.notify(Native Method)
at br.com.alura.searchdrink.fragment.MapaFragment.pegaBares(MapaFragment.java:198)
at br.com.alura.searchdrink.fragment.MapaFragment.onMapReady(MapaFragment.java:91)
at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:385)
at wl.a(:com.google.android.gms.DynamiteModulesB:82)
at maps.ad.t$5.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5717)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
De outra forma, com AsyncTask, esse não deu erro nenhum porém não sei porque ele não está carregando os estabelecimentos no mapa, parece que ele começa o doInBackgrournd e pula sem terminar o database.addValueEventListener indo pro onPostExecute de uma vez, fiz um log lá com o tamanho da lista e dá 0, estranho , não sei se estou usando incorretamente os atributos, e estou instanciando e dando o execute com ela dentro do MapaFragment mesmo, no método onMapReady:
public class TarefaDownloadLocalizacaoBares extends AsyncTask<String, Void, List<Bar>> {
private final Context context;
private final DatabaseReference database;
private ProgressDialog progresso;
public TarefaDownloadLocalizacaoBares(Context context, DatabaseReference database){
this.context = context;
this.database = database;
}
@Override
protected void onPreExecute() {
Log.i("AsyncTask", "Exibindo ProgressDialog na tela Thread: " + Thread.currentThread().getName());
progresso = ProgressDialog.show(context, "Por favor Aguarde ...",
"Baixando Bares...");
}
@Override
protected List<Bar> doInBackground(String... strings) {
final List<Bar> estabelecimentos = new ArrayList<>();
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Map<String, Object> map = (HashMap<String, Object>) snapshot.getValue();
String nome = String.valueOf(map.get("nome"));
String endereco = String.valueOf(map.get("endereco"));
String telefone = String.valueOf(map.get("telefone"));
String site = String.valueOf(map.get("site"));
String email = String.valueOf(map.get("email"));
if (endereco != null) {
Bar bar = new Bar(nome, endereco, telefone, site, email);
estabelecimentos.add(bar);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return estabelecimentos;
}
@Override
protected void onPostExecute(List<Bar> bares) {
progresso.dismiss();
//adiciona local do bar
for(Bar bar : bares){
Toast.makeText(context, "dentro do for", Toast.LENGTH_LONG).show();
Toast.makeText(context, bar.getNome() + " - " + bar.getEndereco(), Toast.LENGTH_LONG).show();
LatLng coordenada = pegaCoordenadaDoEndereco(bar.getEndereco());
if(coordenada != null) {
MarkerOptions marcador = new MarkerOptions();
marcador.position(coordenada);
marcador.title(bar.getNome());
marcador.snippet(String.valueOf(bar.getTelefone()));
marcador.icon(BitmapDescriptorFactory.fromResource(R.drawable.copocheio));
MapaFragment.mapa.addMarker(marcador);
}
}
}
private LatLng pegaCoordenadaDoEndereco(String endereco) {
try{
Geocoder geocoder = new Geocoder(context);
List<Address> resultados = geocoder.getFromLocationName(endereco, 1);
if(!resultados.isEmpty()){
LatLng posicao = new LatLng(resultados.get(0).getLatitude(),
resultados.get(0).getLongitude());
return posicao;
}
}catch(IOException e){
e.printStackTrace();
}
return null;
}
}
E no MapaFragment no método onMapReady:
@Override
public void onMapReady(GoogleMap googleMap) {
this.mapa = googleMap;
TarefaDownloadLocalizacaoBares downloadLocalizacaoBares = new TarefaDownloadLocalizacaoBares(getContext(), database);
downloadLocalizacaoBares.execute();
new Localizador(getContext(), MapaFragment.this);
}