应用程序显示"停止工作错误"关闭应用程序后

时间:2017-05-14 15:01:39

标签: android

我正在开发音乐应用程序,但每当我关闭应用程序时,它都会显示"不幸的是,音乐应用程序停止了#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();
}}

3 个答案:

答案 0 :(得分:0)

请发布整个logcat错误。
顺便说一句,我想你在onStartCommand()方法中的意图并不需要额外的数据。
例如,在start OnClickListener中,您只传递了STAUS个额外信息,但SONG_NAMESONG_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

onStartCommand

在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方法由您实现:

START_STICKY

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

这样的事情,只是为了让你开始。 希望这可以帮助, 干杯