我正在开发音乐应用程序,但每当我关闭应用程序时,它都会显示"不幸的是,音乐应用程序停止了#34;错误。我检查了logcat,这是错误的原因:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.getStringExtra(java.lang.String)' on a null object reference
我不明白为什么会出现这个错误,因为我正在关闭应用程序而且这行(我猜错误显示)不应该被执行。
以下是我的java文件。
MainActivity.java:
public class MainActivity extends AppCompatActivity {
ListView lv;
Button start,next,prev;
MyAdapter myAdapter;
String icon;
int SongPosition;
ArrayList<String> songList= new ArrayList<String>();
ArrayList<String> songPath= new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetFiles(getContentResolver());
lv =(ListView)findViewById(R.id.list);
myAdapter = new MyAdapter();
lv.setAdapter(myAdapter);
icon = "resume";
start = (Button)findViewById(R.id.button);
next = (Button)findViewById(R.id.next);
prev = (Button)findViewById(R.id.prev);
//Pause/Resume playing
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//startService(new Intent(getBaseContext(),MyService.class));
// mynotification();
switch (icon) {
case "resume":
Intent iPause = new Intent(MainActivity.this, MyService.class);
iPause.putExtra("STATUS", 2);
startService(iPause);
icon = "pause";
start.setBackgroundResource(android.R.drawable.ic_media_play);
break;
case "pause":
Intent iResume = new Intent(MainActivity.this,MyService.class);
iResume.putExtra("STATUS",3);
startService(iResume);
icon = "resume";
start.setBackgroundResource(android.R.drawable.ic_media_pause);
break;
default:
Toast.makeText(MainActivity.this, "invalid", Toast.LENGTH_SHORT).show();
}
}
});
//next track
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SongPosition =SongPosition+1;
String nextSongName = songList.get(SongPosition);
String nextSongPath = songPath.get(SongPosition);
Intent nextIntent = new Intent(MainActivity.this,MyService.class);
nextIntent.putExtra("SONG_NAME",nextSongName);
nextIntent.putExtra("SONG_PATH",nextSongPath);
nextIntent.putExtra("STATUS",1);
startService(nextIntent);
}
});
//previous track
prev.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//stopService(new Intent(getBaseContext(),MyService.class));
// mynotification();
SongPosition = SongPosition-1;
String prevSongName = songList.get(SongPosition);
String prevSongPath = songPath.get(SongPosition);
Intent nextIntent = new Intent(MainActivity.this,MyService.class);
nextIntent.putExtra("SONG_NAME",prevSongName);
nextIntent.putExtra("SONG_PATH",prevSongPath);
nextIntent.putExtra("STATUS",1);
startService(nextIntent);
}
});
//display all songs
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
String songName = songList.get(position);
SongPosition = position;
String Path = songPath.get(position);
int state = 1;
Intent lvintent = new Intent(MainActivity.this,MyService.class);
lvintent.putExtra("SONG_NAME",songName);
lvintent.putExtra("SONG_PATH",Path);
lvintent.putExtra("STATUS",state);
startService(lvintent);
start.setBackgroundResource(android.R.drawable.ic_media_pause);
}
});
}
public void GetFiles(ContentResolver contentResolver)
{
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = contentResolver.query(musicUri, null, null, null, null);
if(musicCursor!=null && musicCursor.moveToFirst()) {
//get columns
int titleColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int pathColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
//Toast.makeText(this, songPath, Toast.LENGTH_SHORT).show();
while (musicCursor.moveToNext()) {
String title = musicCursor.getString(titleColumn);
String path = musicCursor.getString(pathColumn);
songPath.add(path);
songList.add(title);
}
}
musicCursor.close();
}
public class MyAdapter extends BaseAdapter
{
LayoutInflater mInflater;
public MyAdapter()
{
mInflater = (LayoutInflater)MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return songList.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (convertView==null)
{
v = mInflater.inflate(R.layout.musiclist,null);
}
TextView musicName = (TextView)v.findViewById(R.id.musicName);
musicName.setText(songList.get(position));
return v;
}
}
@Override
protected void onStart() {
Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);
start.setBackgroundResource(android.R.drawable.ic_media_play);
super.onStart();
}}
MyService.java
public class MyService extends Service {
String SongName,SongPath;
int getStatus;
private MediaPlayer player;
private int Songpos;
SharedPreferences settings;
SharedPreferences.Editor editor;
public static final String MyPREFERENCES = "MyPrefs" ;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
super.onCreate();
Songpos=0;
player = new MediaPlayer();
// settings = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
// editor = settings.edit();
//String storedName = settings.getString("name","");
// String storedPath = settings.getString("path","");
}
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
SongName = intent.getStringExtra("SONG_NAME");
SongPath = intent.getStringExtra("SONG_PATH");
getStatus=intent.getIntExtra("STATUS",0);
if (getStatus==1) {
player.reset();
try {
player.setDataSource(SongPath);
player.prepare();
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
else if (getStatus==2)
{
onPause();
}
else if (getStatus==3)
{
onResume();
}
return super.onStartCommand(intent, flags, startId);
}
public void onPause(){
player.pause();
Songpos= player.getCurrentPosition();
}
public void onResume() {
player.seekTo(Songpos);
player.start();
}
@Override
public void onDestroy() {
player.reset();
player.release();
super.onDestroy();
}}
答案 0 :(得分:0)
请发布整个logcat错误。
顺便说一句,我想你在onStartCommand()
方法中的意图并不需要额外的数据。
例如,在start OnClickListener
中,您只传递了STAUS
个额外信息,但SONG_NAME
和SONG_PATH
尚未传递给额外信息。
如果您没有该意图的任何相关数据,则必须使用onStartCommand()
方法处理它。
答案 1 :(得分:0)
因为在onStartCommand()实现结束时,您正在调用super.onStartCommand(),默认情况下返回START_STICKY或START_STICKY_COMPATIBILITY,您的服务可以使用null intent重新调用。因此,您需要检查intent是否为null,然后根据应用的需要处理该情况。
有关详细信息,请参阅以下链接: https://developer.android.com/reference/android/app/Service.html#onStartCommand(android.content.Intent,int,int) https://developer.android.com/reference/android/app/Service.html#START_STICKY
在API级别5中添加 int onStartCommand(Intent intent, int标志, int startId) 每次客户端通过调用startService(Intent)显式启动服务时,由系统调用,提供它提供的参数和表示启动请求的唯一整数标记。不要直接调用此方法。
为了向后兼容,默认实现调用onStart(Intent,int)并返回START_STICKY或START_STICKY_COMPATIBILITY。
如果您需要在API级别5之前的平台版本上运行应用程序,则可以使用以下模型来处理旧的onStart(Intent,int)回调。 handleCommand方法由您实现:
在API级别5中添加 int START_STICKY 从onStartCommand(Intent,int,int)返回的常量:如果此服务的进程在启动时被终止(从onStartCommand(Intent,int,int)返回后),则将其保留在启动状态但不保留此状态交付意图。稍后系统将尝试重新创建服务。因为它处于启动状态,所以它将保证在创建新服务实例后调用onStartCommand(Intent,int,int); 如果没有任何挂起的启动命令要传递给服务,它将使用null intent对象调用,因此您必须注意检查这一点。
此模式适用于将在任意时间段内显式启动和停止运行的内容,例如执行背景音乐播放的服务。
常数值:1(0x00000001)
答案 2 :(得分:-1)
SongName = intent.getStringExtra("SONG_NAME");
SongPath = intent.getStringExtra("SONG_PATH");
这两行中的一行导致错误,因为消息显示“Nullpointer .getStringExtra” 那么这里发生了什么? OBV。当应用关闭时,您的服务会尝试重启(STICKY?)。
很容易避免,只需在getStringExtra
来电中设置默认值并做出反应或只是致电hasExtra
if (intent.hasExtra("SONG_NAME")) {
// do your stuff
} else {
Log.e("INTENT", "No intent extra. Exiting.");
return;
}
这样的事情,只是为了让你开始。 希望这可以帮助, 干杯