-2

I'm trying to play sounds (they are in the raw folder) when clicking a button, I have most of the things set up.

checkarchivo = nomarchivo;
        Log.d("resultado","start player");
        Log.d("archivo ",nomarchivo);
        soundId = getResources().getIdentifier(nomarchivo, "raw", getPackageName());
        Log.d("id:",""+soundId);
        /*String mediaPath = "android.resource://" + getPackageName() + "/" +soundId;
        Log.d("ruta",mediaPath);
        prueba.setAudioStreamType(AudioManager.STREAM_MUSIC);
        prueba.setDataSource(mediaPath);
        prueba.prepare();
        prueba.start();*/

I have commented the last lines until I fixed the issue (at first it didn't throw an error), variable nomarchivo comes from a parameter and is not null since the log is working throwing the contents of the variable.

The exact error is this one:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

The error throws to the getResources() line, and I have no clue why it doesn't work, of course, if I can't get the id of that file, I can't make a path for the mediaplayer so I can't play the sound.

I tried to initialize a variable res = getResources(); inside the oncreate, and then using it, but with no success, same error as before

Mainactivity class:

package com.werta600.frasesmuzska;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ListView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity implements AsyncResponse 
{

ListView listView;
ArrayList<String> stringArray = new ArrayList<String>();
ArrayList<String> sArray = new ArrayList<String>();
Boolean isplaying = false;
static MediaPlayer prueba = new MediaPlayer();
String checkarchivo = "";
int soundId;


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


    testraw();
    prueba.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            completionPlayer();
        }
    });
}

public void testraw(){
    Field[] fields=R.raw.class.getFields();

    int c = 1;
    for(int count=2; count < fields.length; count++){
        sArray.add(fields[count].getName());
        c++;
    }

    MySimpleArrayAdapter sonidoadapter = new MySimpleArrayAdapter(this, sArray);
    listView = (ListView) findViewById(R.id.listaprincipal);
    listView.setAdapter(sonidoadapter);
}

public void reproducir(View view,String nombrearchivo){
    try {

        if (prueba.isPlaying()){
            stopPlayer(nombrearchivo);
        }else{
            startPlayer(nombrearchivo);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void stopPlayer(String nomarchivo){
    Log.d("resultado","stop player");
    prueba.stop();
    prueba.reset();
    if (!checkarchivo.equals(nomarchivo)){
        startPlayer(nomarchivo);
    }
}

public void startPlayer(String nomarchivo){
    try{
        checkarchivo = nomarchivo;
        Log.d("resultado","start player");
        Log.d("archivo ",nomarchivo);
        soundId = getResources().getIdentifier(nomarchivo, "raw", getPackageName());
        Log.d("id:",""+soundId);
        /*String mediaPath = "android.resource://" + getPackageName() + "/" +soundId;
        Log.d("ruta",mediaPath);
        prueba.setAudioStreamType(AudioManager.STREAM_MUSIC);
        prueba.setDataSource(mediaPath);
        prueba.prepare();
        prueba.start();*/
    }catch (Exception e){
        e.printStackTrace();
    }

}

public void completionPlayer(){
    Log.d("resultado","completed player");
    prueba.stop();
    prueba.reset();
}
}

Adapter:

package com.werta600.frasesmuzska;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MySimpleArrayAdapter extends ArrayAdapter<String> {

//to reference the Activity
private final Activity context;

//array completo
private final ArrayList<String > arraysonido;

public MySimpleArrayAdapter(Activity context, ArrayList<String> arraysonidoParam) {
    super(context,R.layout.lista , arraysonidoParam);
    this.context = context;
    this.arraysonido = arraysonidoParam;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.lista, parent, false);
    TextView nameTextField = (TextView) rowView.findViewById(R.id.nombresonido);
    Button btnreproducir = (Button)rowView.findViewById(R.id.reproducirbtn);

    final String sonidoactual = arraysonido.get(position);
    final String mayus = sonidoactual.substring(0, 1).toUpperCase() + sonidoactual.substring(1);
    final String nombremostrar = mayus.replace("_"," ");
    Log.d("Sonido:",sonidoactual);

    final MainActivity mActivity= new MainActivity();

    nameTextField.setText(nombremostrar);
    btnreproducir.setText("Reproducir");
    btnreproducir.setTag(sonidoactual);
    btnreproducir.setOnClickListener( new View.OnClickListener() {
        String archivo = sonidoactual;
        @Override
        public void onClick(View v) {
            mActivity.reproducir(v,archivo);

        }
    });


    return rowView;
}
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
antoniower
  • 17
  • 1
  • Could you give some more context, like the method and class this is in? – Bart Friederichs Aug 19 '17 at 09:53
  • this is in the mainactivity, inside a void method called startplayer, that only does what you see in the code (inside a try catch block) edit: i have another that is called in the oncreate, which starts the process of populate the listview calling the class and that stuff – antoniower Aug 19 '17 at 09:58
  • Please, show the code. – Bart Friederichs Aug 19 '17 at 09:59
  • @BartFriederichs what code do you want to see – antoniower Aug 19 '17 at 10:00
  • The activity class, the method signatures, the try catch block. Try to make a MCVE: https://stackoverflow.com/help/mcve – Bart Friederichs Aug 19 '17 at 10:01
  • @BartFriederichs there you are, i edited original post – antoniower Aug 19 '17 at 10:17
  • Too bad the question got closed, because the solution is a little more complex. I had an answer, but I cannot post it now. The problem is that you are instantiating `MainActivity` yourself. You cannot do that. – Bart Friederichs Aug 19 '17 at 10:28
  • 2
    Don't do that. Edit your question. I have the solution for you here: https://justpaste.it/1a93a – Bart Friederichs Aug 19 '17 at 10:30
  • @BartFriederichs that did it, thanks, makes sense now its explained to use mainactivity as context in the adapter... now the mediaplayer throws another error (prepare failed), but thats another thing ill fix it soon – antoniower Aug 19 '17 at 10:38
  • 1
    @antoniower: please don't make aggressive assertions about "classic mod behaviour". That you have a Q&A free of charge, which is well tended by unpaid volunteers, is something to be grateful for. Questions _do_ get reopened here, so it is best not to alienate any readers or gold-badge holders who can help you do that. The "triggered" remark qualifies as abusive IMO, so I have flagged that for mods. Please keep it civil! – halfer Aug 19 '17 at 19:37
  • @Bart: if you see a question that was closed in error, you can always ping [SO CVR in chat](https://chat.stackoverflow.com/rooms/41570/so-close-vote-reviewers). – halfer Aug 19 '17 at 19:43
  • 1
    @halfer didn't know that, thanks, I'll keep it in mind. – Bart Friederichs Aug 22 '17 at 06:33

2 Answers2

1

The problem is, you instantiate a new MainActivity in your adapter. You cannot do that. You should use the Context you are given in the constructor.

//to reference the Activity
private final MainActivity context;

[...]

public MySimpleArrayAdapter(Activity context, ArrayList<String> arraysonidoParam) {
    super(context,R.layout.lista , arraysonidoParam);
    this.context = (MainActivity)context;         // cast the context you get to MainActivity, so you can call reproducir later
    this.arraysonido = arraysonidoParam;
}

[...]

btnreproducir.setOnClickListener( new View.OnClickListener() {
        String archivo = sonidoactual;
        @Override
        public void onClick(View v) {
            context.reproducir(v,archivo);
        }
    });

Now, in your reproducir call, it will use the correct MainActivity (the one that the Android OS instantiated and knows where the resources are).

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
0

Please try this:-

  yourplayer.setDataSource(this, Uri.parse("android.resource://com.urPackageName/" + R.raw.your_sound));
Pratik
  • 97
  • 1
  • 11
  • i tried this some days ago but i can't add a variable to "R.raw.[variable here]", it just says "Cannot resolve symbol" – antoniower Aug 19 '17 at 10:18