5
respostas

Android - Botões de volume enquanto a tela está bloqueada

Pessoal,

Estou desenvolvendo um app em que eu preciso acionar uma função ao apertar rapidamente duas vezes qualquer um dos dois botões de volume do celular e isso precisa acontecer mesmo quando a tela está bloqueada.

Eu consegui fazer o código, porém apenas quando estou com o aplicativo aberto, se eu saio do app ou eu bloqueio da tela não consigo mais contar os acionamentos dos botões.

Já procurei alguns métodos, porém não consegui implementar nenhum deles. A alternativa em que cheguei mais longe foi com BroadcastReceiver ,que encontra-se neste link:

https://stackoverflow.com/questions/16144259/how-to-get-volume-key-event-when-the-screen-is-locked

Porém como sou novo nesse mundo de desenvolvimento de aplicativos não estou conseguindo faze-lo funcionar.

Abaixo seguem as premissas do que eu preciso fazer: 1 - apertou o botão para aumentar o volume deve mudar o texto escrito na tela para "VOLUME UP".

2 - apertou o botão para diminuir o volume deve mudar o texto escrito na tela para "VOLUME DOWN".

3 - caso o botão seja pressionado DUAS vezes RAPIDAMENTE (até 200 ms), deve mudar o texto na tela para "PEDIDO DE SOCORRO".

4 - este acionamento deve ser possível de ocorrer em qualquer estado que o celular se encontrar: enquanto o app está sendo usado, enquanto outro app está sendo usado e quando a tela está bloqueada.

5 - a programação não deve impedir a variação do som do aplicativo. O volume tem que mudar ao pressionar os botões.

Segue o código:

import android.content.ComponentName;
import android.content.Context;
import android.media.AudioManager;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.TextView;

public class VolumeButtonActivity extends AppCompatActivity {

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

    }

    //inicia os contadores de clicks dos botões
    int countClicksUp = 0;
    int countClicksDown = 0;

    //Verificador de evento (acionamento de chaves)
    public boolean dispatchKeyEvent(KeyEvent event) {
        //recebe a ação e o código da chave
        int action = event.getAction();
        int keyCode = event.getKeyCode();

        //timer para dizer o botão foi apertado rapidamente(rapidamente = até 200 ms) - (duração total, tempo de cada virificação)
        new CountDownTimer(200, 200) {

            //contador em ciclos(não usado agora)
            public void onTick(long millisUntilFinished) {
                //mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
                //here you can have your logic to set text to edittext
            }

            //Ao final do timer verificar se foi acionado duas ou mais vezes qualquer um dos botões de volume
            public void onFinish() {
                if (countClicksDown >= 2 || countClicksUp >= 2){
                    //Dispara o gatilho
                    TextView textViewTeste = (TextView)findViewById(R.id.textoTeste);
                    textViewTeste.setText("Pedido de socorro");
                    //depois de acionado precisa zerar os contadores para não serem acionados novamente
                    countClicksDown = 0;
                    countClicksUp = 0;
                }
                //mTextField.setText("done!");
                //ao final se a pessoa apertou só uma vez o som e depois de um tempo apertou novamente isso não pode acionar
                //dado isso é preciso zerar o contador a cada ciclo para não acionar erradamente
                countClicksDown = 0;
                countClicksUp = 0;
            }

        }.start();


        switch (keyCode) {

            case KeyEvent.KEYCODE_VOLUME_UP:
                if (action == KeyEvent.ACTION_DOWN) {
                    //TODO
                    TextView textViewTeste = (TextView)findViewById(R.id.textoTeste);
                    textViewTeste.setText("Volume UP");
                    countClicksUp = countClicksUp +1;
                }
                return true;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                if (action == KeyEvent.ACTION_DOWN) {
                    //TODO
                    TextView textViewTeste = (TextView)findViewById(R.id.textoTeste);
                    textViewTeste.setText("Volume DOWN");
                    countClicksDown = countClicksDown + 1;

                }
                return true;
            default:
                return super.dispatchKeyEvent(event);
        }
    }
}

Agradeço desde já quem puder me ajudar. Qualquer ajuda será extremamente bem vinda!

5 respostas

Fala ai Rafael, tudo bem ?

Cara acho que o melhor jeito de fazer isso é através de BroadcastReceiver mesmo, o problema disso é que nas novas versões do android, isso não deverá funcionar :(

E tem que tomar um pouco de cuidado que essas formas de clicar o botão pode conflitar com o código fonte do android em alguns celulares.

Matheus,

Tudo sim e com vc?

Vc poderia me explicar o motivo disso não funcionar nas novas versões?

Eu precisaria acionar essa função por qualquer botão que tenha no celular, só os botões de volume dariam problema nas versões novas?

A Alura tem algum curso que aborde BroadcastReceiver?

Obrigado!

Oi Rafael,

Nas versões novas o BroadcastReceiver será removido, na própria versão 8 já foi solicitado que os desenvolvedores não o usem :(

Acho que é visto no curso básico de android, em um dos três modulos.

Poxa, uma pena.

Então para o monitoramento do acionamento de um botão o que vc me recomendaria visando atender as próximas gerações de android?

Tudo que li até o momento fala que não é possível, pois broadcast receiver não funciona com a tela desligada, e a galera dá outras alternativas que são code smells e/ou vão acabar com a bateria do celular rapidamente.