1

I have two classes one its an Activity named OficioActivity and the other its a Service named Player, the OficioActivity starts the Service Player and then it calls the methods playPause(), adiantaAudio() and retrocedeAudio() which uses MediaPlayer class, the problem its if it runs on foreground (when screen is off) theres no problem the Player has a onCompletionListener() that plays the next song, but if I click on a button on OficioActivity to go to next song it crashes with a nullpointException.

OficioActivity

public class OficioActivity extends ActionBarActivity implements View.OnClickListener {

private ImageButton btAdianta,btRetrocede,btPlayPause;
private TextView tvOficio;
private Player player;
private Notificacao notification;
private int NOTIFICACAO_ID =1;
private Intent intentService;


@Override
protected void onCreate(Bundle savedInstanceState) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_oficio);

    btAdianta = (ImageButton) findViewById(R.id.ibtn_adiantar);
    btRetrocede = (ImageButton) findViewById(R.id.ibtn_retroceder);
    btPlayPause = (ImageButton) findViewById(R.id.ibtn_play);
    tvOficio = (TextView) findViewById(R.id.tv_oficio);

    btAdianta.setOnClickListener(this);
    btPlayPause.setOnClickListener(this);
    btRetrocede.setOnClickListener(this);

    intentService = new Intent(OficioActivity.this,Player.class);
    startService(intentService);


}

@Override
protected void onResume() {
    if(player==null)
    player = new Player();
    notification = new Notificacao(OficioActivity.this);
    super.onResume();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_oficio, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**Serve para alterar um TextView em tempo de execução
 *
 * @param  tv TextView
 * @param texto String
 */
public void runOnThread(final TextView tv, final String texto){
    OficioActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            tv.setText(texto);
        }
    });
}

@Override
public void onClick(View v) {
    switch (v.getId()){

        case R.id.ibtn_adiantar:
            runOnThread(tvOficio,player.adianta());
        break;
        case R.id.ibtn_retroceder:
            runOnThread(tvOficio,player.retrocede());
        break;
        case R.id.ibtn_play:
            notification.geraNotificacao(NOTIFICACAO_ID,OficioActivity.this);
            runOnThread(tvOficio, player.playPause());
        break;

    }
}

@Override
protected void onDestroy() {
   // player.paraAudio();
    super.onDestroy();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(event.getKeyCode()==KeyEvent.KEYCODE_BACK){
        player.paraAudio();
        stopService(intentService);
        finish();
        notification.cancelaNotificacao(NOTIFICACAO_ID);
    }

    return super.onKeyDown(keyCode, event);
}

}

public class Player extends Service implements MediaPlayer.OnCompletionListener {

private final int SALVE_MESA = R.raw.salve_mesa;
private final int AGORA_LABIOS = R.raw.agora_labios_meus;
private final int HUMILDES_OFERECEMOS = R.raw.humildes_oferecemos;
private final int INTRO = R.raw.intro;
private final int ORACAO = R.raw.oracao;
private final int SALVE_RELOGIO = R.raw.salve_relogio;
private final int SALVE_VIRGEM_IMACULADA = R.raw.salve_virgem_imaculada;
private final int SALVE_VIRGEM_TRINDADE = R.raw.salve_virgem_trindade;
private final int SEDE_EM_MEU_FAVOR = R.raw.sede_em_meu_favor;
private final int SALVE_TRONO = R.raw.salve_trono;
private final int SALVE_CIDADE = R.raw.salve_cidade;
private final int ROGAI_A_DEUS = R.raw.rogai_a_deus_vos;

private final int INICIAR_PAUSAR = 0;
private final int ADIANTAR = 1;
private final int RETROCEDER = 2;


private static MediaPlayer media;
private int audioAtual = 1;
private HashMap<Integer, Integer> hashMapAudio, hashMapRetrocede;
private String texto;

private HashMap<Integer, Integer> musicas = new HashMap<>();

public Player() {
    hashMapAudio = new HashMap<>();
    hashMapAudio.put(1, INTRO);
    hashMapAudio.put(2, AGORA_LABIOS);
    hashMapAudio.put(3, ORACAO);
    hashMapAudio.put(4, SEDE_EM_MEU_FAVOR);
    hashMapAudio.put(5, SALVE_MESA);
    hashMapAudio.put(6, ORACAO);
    hashMapAudio.put(7, SEDE_EM_MEU_FAVOR);
    hashMapAudio.put(8, SALVE_TRONO);
    hashMapAudio.put(9, ORACAO);
    hashMapAudio.put(10, SEDE_EM_MEU_FAVOR);
    hashMapAudio.put(11, SALVE_VIRGEM_TRINDADE);
    hashMapAudio.put(12, ORACAO);
    hashMapAudio.put(13, SEDE_EM_MEU_FAVOR);
    hashMapAudio.put(14, SALVE_CIDADE);
    hashMapAudio.put(15, ORACAO);
    hashMapAudio.put(16, SEDE_EM_MEU_FAVOR);
    hashMapAudio.put(17, SALVE_RELOGIO);
    hashMapAudio.put(18, ORACAO);
    hashMapAudio.put(19, ROGAI_A_DEUS);
    hashMapAudio.put(20, SALVE_VIRGEM_IMACULADA);
    hashMapAudio.put(21, ORACAO);
    hashMapAudio.put(22, HUMILDES_OFERECEMOS);

}


/**
 * Retorna o texto equivalente ao audio tocado
 *
 * @return String
 */
private String recuperaTexto() {


    switch (audioAtual) {
        case 1:
            texto = OficioEnum.INTRO.texto;
            break;
        case 2:
            texto = OficioEnum.AGORA_LABIOS_MEUS.texto;
            break;
        case 3:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 4:
            texto = OficioEnum.SEDE_EM_MEU_FAVOR.texto;
            break;
        case 5:
            texto = OficioEnum.MESA.texto;
            break;
        case 6:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 7:
            texto = OficioEnum.SEDE_EM_MEU_FAVOR.texto;
            break;
        case 8:
            texto = OficioEnum.TRONO.texto;
            break;
        case 9:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 10:
            texto = OficioEnum.SEDE_EM_MEU_FAVOR.texto;
            break;
        case 11:
            texto = OficioEnum.VIRGEM_DA_TRINDADE.texto;
            break;
        case 12:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 13:
            texto = OficioEnum.SEDE_EM_MEU_FAVOR.texto;
            break;
        case 14:
            texto = OficioEnum.CIDADE.texto;
            break;
        case 15:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 16:
            texto = OficioEnum.SEDE_EM_MEU_FAVOR.texto;
            break;
        case 17:
            texto = OficioEnum.RELOGIO.texto;
            break;
        case 18:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 19:
            texto = OficioEnum.ROGAI_A_DEUS.texto;
            break;
        case 20:
            texto = OficioEnum.VIRGEM_IMACULADA.texto;
            break;
        case 21:
            texto = OficioEnum.ORACAO.texto;
            break;
        case 22:
            texto = OficioEnum.HUMILDES_OFERECEMOS.texto;
            break;

    }


    return texto;
}


/**
 * Retorna o audio dependendo da acao se a acao for adiantar retorna proximo audio representado por um Integer
 *
 * @param acao
 * @return int
 */
private int verificaMusica(int acao) {

    /*
    * Sequencia do oficio
    * 1 - intro
    * 2 - agora labios meus
    * 3 - oracao
    * 4 - sede em meu favor
    * 5 - salve mesa
    * 6 - oracao
    * 7 - sede em meu favor
    * 8 - salve trono
    * 9 - oracao
    * 10 -sede em meu favor
    * 11 -salve virgem da trindade
    * 12 -oracao
    * 13 -sede em meu favor
    * 14 -salve cidade
    * 15 -oracao
    * 16 -sede em meu favor
    * 17 -salve relogio
    * 18 -oracao
    * 19 -rogai a Deus vos
    * 20 -salve virgem imaculada
    * 21 -oracao
    * 22 -humildes oferecemos
    * */

    if (acao == ADIANTAR) {
        incrementaAudioAtual();
        return hashMapAudio.get(audioAtual);
    } else {
        decrementaAudioAtual();
        return hashMapAudio.get(audioAtual);
    }

}


/**
 * Incrementa o audio com + 1 até 22
 */
private void incrementaAudioAtual() {
    if (audioAtual < 22) {
        audioAtual++;
    }

}

/**
 * DEcrementa o audio com -1 até 1
 */
private void decrementaAudioAtual() {
    if (audioAtual > 1) {
        audioAtual--;
    }

}

public MediaPlayer getMedia() {
    return media;
}

/**
 * Retorna se o audio está tocando
 *
 * @return true ou false
 */
public boolean isPlaying() {
    return media.isPlaying();
}

@Override
public IBinder onBind(Intent intent) {

    return null;
}

@Override
public void onCreate() {

    media = MediaPlayer.create(getApplicationContext(), INTRO);
    media.setOnCompletionListener(this);
    super.onCreate();
}


/**
 * Adianta o audio
 */
public String adianta() {

    if (media != null) {
        media.stop();
        media.release();
        media = MediaPlayer.create(getApplicationContext(), verificaMusica(ADIANTAR));
        media.setOnCompletionListener(this);
        media.start();
    }
    return recuperaTexto();
}

/**
 * Retrocede o audio
 *
 * @return String texto
 */
public String retrocede() {

    if (media != null) {
        media.stop();
        media.release();
        media = MediaPlayer.create(getApplicationContext(), verificaMusica(RETROCEDER));
        media.start();

    }
    return recuperaTexto();
}

/**
 * Para o audio e define a media como null para liberar memoria
 */
public void paraAudio() {
    if (media != null) {
        if (media.isPlaying()) {
            media.stop();
            media.release();
            media = null;

        } else {
            media.release();
            media = null;

        }
    }
}

/**
 * Se o audio não estiver tocando toca, caso contrario pausa a musica
 *
 * @return
 */

public String playPause() {
    if (media == null) {
        media = MediaPlayer.create(getApplicationContext(), verificaMusica(INTRO));
        media.start();
    } else {
        if (media.isPlaying()) {
            media.pause();
        } else {
            media.start();
        }
    }
    return recuperaTexto();
}

@Override
public void onCompletion(MediaPlayer mp) {
    adianta();
}

}

03-17 10:50:12.840: E/AndroidRuntime(1898): FATAL EXCEPTION: main
03-17 10:50:12.840: E/AndroidRuntime(1898): Process: com.renanwillamy.devocionario, PID: 1898
03-17 10:50:12.840: E/AndroidRuntime(1898): java.lang.NullPointerException
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at entidades.Player.adianta(Player.java:260)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at com.renanwillamy.devocionario.OficioActivity.onClick(OficioActivity.java:103)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.view.View.performClick(View.java:4438)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.view.View$PerformClick.run(View.java:18422)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.os.Handler.handleCallback(Handler.java:733)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.os.Handler.dispatchMessage(Handler.java:95)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.os.Looper.loop(Looper.java:136)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at android.app.ActivityThread.main(ActivityThread.java:5017)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at java.lang.reflect.Method.invokeNative(Native Method)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at java.lang.reflect.Method.invoke(Method.java:515)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-17 10:50:12.840: E/AndroidRuntime(1898):     at dalvik.system.NativeStart.main(Native Method)
Squonk
  • 48,735
  • 19
  • 103
  • 135
Renan Willamy
  • 173
  • 1
  • 1
  • 9
  • Your logs from LogCat will tell you which line caused the NullPointerException. In using context, have a look at my answer [here](http://stackoverflow.com/questions/1026973/android-whats-the-difference-between-the-various-methods-to-get-a-context/13945633#13945633). – ChuongPham Mar 17 '15 at 15:12
  • You can't do this...`player = new Player();`. You can't directly create an instance of a `Service` - you have to use `startService(...)` and if you want to access methods in the `Service` you are going to bind to it and access the methods through the `ServiceConnection` and `Binder`. For example, the following won't work unless done through a bound `Service`. – Squonk Mar 17 '15 at 15:23
  • Thanks everyone I use a ServiceConnection and Binder like @Squonk said! – Renan Willamy Mar 17 '15 at 16:09

1 Answers1

0

Thanks everyone I use a ServiceConnection and Binder like @Squonk said! – Renan Willamy

Renan Willamy
  • 173
  • 1
  • 1
  • 9