我点击按钮时尝试播放声音(它们在原始文件夹中),我已经设置了大部分内容。
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;
}
}
答案 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));