尝试获取原始文件夹中的声音标识符时尝试调用虚拟方法资源

时间:2017-08-19 09:45:13

标签: android nullpointerexception

我点击按钮时尝试播放声音(它们在原始文件夹中),我已经设置了大部分内容。

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();*/

我已经对最后一行进行了评论,直到我解决了这个问题(起初它没有抛出错误),变量nomarchivo来自一个参数而且不是null,因为日志正在工作抛出内容变量。

确切的错误就是这个:

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

错误抛到getResources()行,我不知道为什么它不起作用,当然,如果我无法获取该文件的id,我就不能为媒体播放器制作一条路径,这样我就无法播放声音。

我尝试在oncreate中初始化变量res = getResources();,然后使用它,但没有成功,出现与之前相同的错误

主要活动类:

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();
}
}

适配器:

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;
}
}

2 个答案:

答案 0 :(得分:1)

问题是,您在适配器中实例化了一个新的MainActivity。你不能这样做。您应该使用构造函数中给出的Context

//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);
        }
    });

现在,在reproducir调用中,它将使用正确的MainActivity(Android操作系统实例化的那个,并知道资源的位置)。

答案 1 :(得分:0)

请试试这个: -

  yourplayer.setDataSource(this, Uri.parse("android.resource://com.urPackageName/" + R.raw.your_sound));