How do you run the getCidade() method with asynctask, and return the value of the city string to use in another method?

Asked

Viewed 58 times

1

public class CadAnuncio extends AppCompatActivity {

     LocationManager locationManager;

     private Button btnSalvar;
     private DatabaseReference databaseAnuncio, databaseUsuario;
     private String uid, url, url02, url03, url04, url05, url06, nome, idade, sexo, etnia,cabelo, atendo, viagem, tFisico, valor, fone, descricao, cidade;
     private ImageView imgPrincipal, foto02, foto03, foto04, foto05, foto06;
     private FirebaseAuth mAuth;
     private Uri resultUri, resultUri02, resultUri03, resultUri04, resultUri05, resultUri06;
     private Spinner spIdade, spSexo, spEtnia, spCabelo, spAtendo, spViagem, spFisico;
     private EditText txtDescricao, txtFone, txtNome, txtValor;
     private TextView latitudea, longitudea;
     Double latiatual, longatual;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_cad_anuncio);

       getCidade();


    //      Solicitar permissão de acesso à galeria e à localização
    String[] permissoes = new String[]{
            android.Manifest.permission.READ_EXTERNAL_STORAGE,
            android.Manifest.permission.ACCESS_COARSE_LOCATION,
            android.Manifest.permission.ACCESS_FINE_LOCATION,
    };
    Permissoes.validate(this, 0, permissoes);


    txtNome = findViewById(R.id.txtNome);
    txtValor = findViewById(R.id.txtValor);
    txtFone = findViewById(R.id.txtFone);
    txtDescricao = findViewById(R.id.txtDescricao);
    spIdade = findViewById(R.id.spIdade);
    spSexo = findViewById(R.id.spSexo);
    spEtnia = findViewById(R.id.spEtnia);
    spCabelo = findViewById(R.id.spCabelo);
    spAtendo = findViewById(R.id.spAtendo);
    spViagem = findViewById(R.id.spViagem);
    spFisico = findViewById(R.id.spFisico);

    imgPrincipal = findViewById(R.id.imgPrincipalAnuncio);
    foto02 = findViewById(R.id.foto02);
    foto03 = findViewById(R.id.foto03);
    foto04 = findViewById(R.id.foto04);
    foto05 = findViewById(R.id.foto05);
    foto06= findViewById(R.id.foto06);
    btnSalvar = findViewById(R.id.btnSalvar);
    mAuth = FirebaseAuth.getInstance();
    uid = mAuth.getCurrentUser().getUid();

    databaseUsuario = FirebaseDatabase.getInstance().getReference("Usuarios").child("Anunciantes").child(uid);
    databaseAnuncio = FirebaseDatabase.getInstance().getReference("Anuncios").child(cidade).child(uid);
    btnSalvar.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            salvaDadosAnuncio();
            goMeuPerfil();
            finish();
        }
    });
    getDadosAnuncio();
    imgPrincipal.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent("android.intent.action.PICK");
            intent.setType("image/*");
            startActivityForResult(intent, 1910);
        }
    });
    foto02.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent("android.intent.action.PICK");
            intent.setType("image/*");
            startActivityForResult(intent, 2);
        }
    });
    foto03.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent("android.intent.action.PICK");
            intent.setType("image/*");
            startActivityForResult(intent, 3);
        }
    });
    foto04.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent("android.intent.action.PICK");
            intent.setType("image/*");
            startActivityForResult(intent, 4);
        }
    });
    foto05.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent("android.intent.action.PICK");
            intent.setType("image/*");
            startActivityForResult(intent, 5);
        }
    });
    foto06.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent("android.intent.action.PICK");
            intent.setType("image/*");
            startActivityForResult(intent, 6);
        }
    });
}

private void getCidade(){
    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    @SuppressLint("MissingPermission")
    Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    latiatual = location.getLatitude();
    longatual = location.getLongitude();
    Verso.getInstance().setup(CadAnuncio.this);
    GeoInfo geoInfo = Verso.getInstance().getGeoInfo(latiatual, longatual);
    cidade = geoInfo.getCityName();
}



private void salvaDadosAnuncio() {...}

public void onActivityResult(int requestCode, int resultCode, Intent data) {...}

private void goMeuPerfil() {...}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {...}

public void getDadosAnuncio() {...}

}

1 answer

1


I hope this solves your problem without creating others.

public class CadAnuncio extends AppCompatActivity {
    private static Double latiatual, longatual;
    private static String cidade;
    // ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cad_anuncio);

        // ...

        GetCidade getCidade = new GetCidade(this);
        getCidade.execute();

        // ...
    }

    // ...

    /* Inner classes não estáticas mantêm uma referência da classe do nível 
       de cima. Como esta é uma classe AsyncTask e pelo comportamento de 
       background dela, ela pode acabar sendo executada por mais tempo 
       que a própria activity, mentendo a referêcia à classe em que ela
       está aninhada e, portanto, vazando memória.

       Sendo assim, para evitar esses vazamentos, declaramos esta inner
       class estática.
    */
    private static class GetCidade extends AsyncTask<String, Integer, String> {
        // Não podemos manter uma referência forte da activity
        // pois o contexto pode facilmente se tornar inválido
        // quando a tela for rotacionada, por exemplo
        private WeakReference<Activity> weakActivity;
        private LocationManager locationManager;

        GetCidade(Activity activity) {
            this.weakActivity = new WeakReference<>(activity);
            locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Ótima hora pra mostrar ProgressDialogs
        }

        @Override
        protected String doInBackground(String... strings) {
            if (locationManager == null) {
                return null;
            }
            @SuppressLint("MissingPermission")
            Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

            /* Considere declarar e consumir essas variáveis dentro da AsyncTask
               Por causa do comportamento assíncrono, você "receberá" esses
               valores um tempo depois, e o fluxo da aplicação não 
               parará esperando por eles.               
            */
            latiatual = location.getLatitude();
            longatual = location.getLongitude();
            Verso.getInstance().setup(CadAnuncio.this);
            GeoInfo geoInfo = Verso.getInstance().getGeoInfo(latiatual, longatual);
            return geoInfo.getCityName();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            int progresso = progress[0];
            // Se precisar, use-o para atualizar o 
            // progresso de algum progress widget na UI.
        }

        @Override
        protected void onPostExecute(String resultado) {
            // Recuperar a referência da activity
            Activity activity = weakActivity.get();
            // Verificar se podemos mecher na UI
            if (activity != null && !activity.isFinishing()) {
                // Feche diálogos aqui
                if (resultado != null) {
                    cidade = resultado;
                    // use cidade globalmente                   
                } else {
                    new AlertDialog.Builder(activity)
                            .setIcon(R.drawable.ic_warning)
                            .setTitle("Falhou")
                            .setMessage("Não deu")
                            .show();
                }

            }
            // else: não podemos fazer mais nada :(
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            Toast.makeText(weakActivity.get(), "Cancelado", Toast.LENGTH_SHORT).show();
        }
    }
}

Edit: if you really want to run getCity() in a different thread, get the city value and still keep the flow, you can do something like this:

public class CadAnuncio extends AppCompatActivity {
    private String cidade;
    // ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cad_anuncio);

        // ...

        new Thread(() -> { // Java 8: https://developer.android.com/studio/write/java8-support?hl=pt-br
            cidade = getCidade();
            if (!isFinishing()) {
                runOnUiThread(() -> {
                    // Continue o fluxo aqui, 
                    // faça algo com 'cidade', chame outros métodos etc.
                    // Já estamos de volta da thread principal
                });
            }
        }).start();

    }

    private String getCidade() {
        AtomicReference<String> resultado = new AtomicReference<>();
        AtomicBoolean completo = new AtomicBoolean(false);
        Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

        latiatual = location.getLatitude();
        longatual = location.getLongitude();
        Verso.getInstance().setup(CadAnuncio.this);
        GeoInfo geoInfo = Verso.getInstance().getGeoInfo(latiatual, longatual);
        resultado.set(geoInfo.getCityName());
        completo.set(true);

        while (true) { // Salvo por rodar eu outra thread
            if (completo.get()) {
                return resultado.get();
            }
        }
    }
  • It worked, but it is still very time consuming process, and the app screen keeps getting dark during the search of the logged user’s city, but this is another story... in case I want to use the value of the string city in two different activities which the best way?

  • Which of the methods you used?

  • The first one you suggested.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.