有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android Studio在警报准备就绪时启动Mediaplayer

你好,我有2个活动,2个应用程序,每个都有它们的类(总共大约10个类),我想把它们结合起来。我有一个功能性闹钟和一个功能性媒体播放器。我想在闹钟响的时候启动mediaplayer。问题是我的应用程序在响的时候崩溃了。 媒体播放器类:

package com.never.mediaalarmplayer;

import 安卓.content.ComponentName;
import 安卓.content.ContentResolver;
import 安卓.content.Context;
import 安卓.content.Intent;
import 安卓.content.ServiceConnection;
import 安卓.database.Cursor;
import 安卓.net.Uri;
import 安卓.os.Bundle;
import 安卓.os.IBinder;
import 安卓.support.v7.app.AppCompatActivity;
import 安卓.view.MenuItem;
import 安卓.view.View;
import 安卓.widget.Button;
import 安卓.widget.ListView;
import 安卓.widget.MediaController;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * Created by Never on 5/14/2017.
 */

public class MediaPlayer extends AppCompatActivity implements MediaController.MediaPlayerControl {
    private ArrayList<Song> songList;
    private ListView songView;
    private MusicService musicSrv;
    private Intent playIntent;
    private boolean musicBound=false;
    private MusicController controller;
    private boolean paused=false, playbackPaused=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mediaplayer);
        songView = (ListView)findViewById(R.id.song_list);
        songList = new ArrayList<>();
        getSongList();
        Collections.sort(songList, new Comparator<Song>(){
            public int compare(Song a, Song b){
                return a.getTitle().compareTo(b.getTitle());
            }
        });
        SongAdapter songAdt = new SongAdapter(this, songList);
        songView.setAdapter(songAdt);
        setController();
        Button btn = (Button)findViewById(R.id.open_alarm);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MediaPlayer.this, Alarm.class));
            }
        });
    }
    //connect to the service
    private ServiceConnection musicConnection = new ServiceConnection(){

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MusicService.MusicBinder binder = (MusicService.MusicBinder)service;
            //get service
            musicSrv = binder.getService();
            //pass list
            musicSrv.setList(songList);
            musicBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            musicBound = false;
        }
    };
    @Override
    protected void onStart() {
        super.onStart();
        if(playIntent==null){
            playIntent = new Intent(this, MusicService.class);
            bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
            startService(playIntent);
        }
    }
    @Override
    protected void onPause(){
        super.onPause();
        paused=true;
    }
    @Override
    protected void onResume(){
        super.onResume();
        if(paused){
            setController();
            paused=false;
        }
    }
    @Override
    protected void onStop(){
        controller.hide();
        super.onStop();
    }
    public void songPicked(View view){
        musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
        musicSrv.playSong();
        if(playbackPaused){
            setController();
            playbackPaused=false;
        }
        controller.show(0);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //menu item selected
        switch (item.getItemId()) {
            case R.id.action_shuffle:
                //shuffle
                musicSrv.setShuffle();
                break;
            case R.id.action_end:
                stopService(playIntent);
                musicSrv=null;
                System.exit(0);
                break;
        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onDestroy() {
        stopService(playIntent);
        musicSrv=null;
        super.onDestroy();
    }
    public void getSongList() {
        //retrieve song info
        ContentResolver musicResolver = getContentResolver();
        Uri musicUri = 安卓.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
        if(musicCursor!=null && musicCursor.moveToFirst()){
            //get columns
            int titleColumn = musicCursor.getColumnIndex
                    (安卓.provider.MediaStore.Audio.Media.TITLE);
            int idColumn = musicCursor.getColumnIndex
                    (安卓.provider.MediaStore.Audio.Media._ID);
            int artistColumn = musicCursor.getColumnIndex
                    (安卓.provider.MediaStore.Audio.Media.ARTIST);
            //add songs to list
            do {
                long thisId = musicCursor.getLong(idColumn);
                String thisTitle = musicCursor.getString(titleColumn);
                String thisArtist = musicCursor.getString(artistColumn);
                songList.add(new Song(thisId, thisTitle, thisArtist));
            }
            while (musicCursor.moveToNext());
        }
    }
    private void setController(){
        //set the controller up
        controller = new MusicController(this);
        controller.setPrevNextListeners(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playNext();
            }
        }, new View.OnClickListener(){
            @Override
            public void onClick(View v){
                playPrev();
            }
        });
        controller.setMediaPlayer(this);
        controller.setAnchorView(findViewById(R.id.song_list));
        controller.setEnabled(true);
    }
    //play next
    private void playNext(){
            musicSrv.playNext();
        if(playbackPaused){
            setController();
            playbackPaused=false;
        }
            controller.show(0);
        }
        //play prev
    private void playPrev(){
        musicSrv.playPrev();
        if(playbackPaused) {
            setController();
            playbackPaused = false;
        }
        controller.show(0);
    }

    @Override
    public void start() {
        musicSrv.go();
    }

    @Override
    public void pause() {
        playbackPaused=true;
        musicSrv.pausePlayer();;
    }

    @Override
    public int getDuration() {
        if(musicSrv!=null &&musicBound&&musicSrv.isPng())
            return musicSrv.getDur();
        else
        return 0;
    }

    @Override
    public int getCurrentPosition() {
        if(musicSrv!=null&&musicBound&&musicSrv.isPng())
            return musicSrv.getPosn();
        else
        return 0;
    }

    @Override
    public void seekTo(int pos) {
        musicSrv.seek(pos);
    }

    @Override
    public boolean isPlaying() {
        if(musicSrv!=null&&musicBound)
            return musicSrv.isPng();
        else
        return false;
    }

    @Override
    public int getBufferPercentage() {
        return 0;
    }

    @Override
    public boolean canPause() {
        return true;
    }

    @Override
    public boolean canSeekBackward() {
        return true;
    }

    @Override
    public boolean canSeekForward() {
        return true;
    }

    @Override
    public int getAudioSessionId() {
        return 0;
    }

}

报警接收器等级:

package com.never.mediaalarmplayer;

import 安卓.content.Context;
import 安卓.content.Intent;
import 安卓.media.Ringtone;
import 安卓.media.RingtoneManager;
import 安卓.net.Uri;
import 安卓.support.v4.content.WakefulBroadcastReceiver;

/**
 * Created by Never on 4/29/2017.
 */

public class AlarmReceiver extends WakefulBroadcastReceiver{
    private static Ringtone ringtone  = null;
    @Override
    public void onReceive(Context context, Intent intent) {
       Alarm.getTextView2().setText("It's time to wake up!");
        Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
          ringtone = RingtoneManager.getRingtone(context, uri);
       // ringtone.play();
        MediaPlayer ms = new MediaPlayer();
        ms.onStart();
    }
    public static void stopRingtone() {
        ringtone.stop();
   }
}

和报警等级:

package com.never.mediaalarmplayer;

import 安卓.annotation.TargetApi;
import 安卓.app.AlarmManager;
import 安卓.app.PendingIntent;
import 安卓.content.Intent;
import 安卓.os.Build;
import 安卓.os.Message;
import 安卓.support.v4.app.FragmentManager;
import 安卓.support.v4.app.FragmentTransaction;
import 安卓.support.v7.app.AppCompatActivity;
import 安卓.os.Bundle;
import 安卓.os.Handler;
import 安卓.view.View;
import 安卓.widget.Button;
import 安卓.widget.TextView;
import 安卓.view.View.OnClickListener;

import java.util.Calendar;

public class Alarm extends AppCompatActivity {

    private static int timeHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
    private static int timeMinute = Calendar.getInstance().get(Calendar.MINUTE);
    TextView textView1;
    private static TextView textView2;
    public static TextView getTextView2(){
        return textView2;
    }
    AlarmManager alarmManager;
    private PendingIntent pendingIntent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setam layoutul pe care ne uitam si pe care lucram
        setContentView(R.layout.activity_alarm);
        // spunem ca textView1 este textviewul cu id-ul msg1
        textView1 = (TextView)findViewById(R.id.msg1);
        // afisam ora curenta
        if(timeHour>9&&timeMinute>9)
        textView1.setText(timeHour + ":" + timeMinute);
        else if(timeHour>9&&timeMinute<=9)
            textView1.setText(timeHour + ":" + "0" + timeMinute);
        else if(timeHour<=9&&timeMinute>9)
            textView1.setText("0" + timeHour + ":" + timeMinute);
        else if(timeHour<=9&&timeMinute<=9)
            textView1.setText("0" + timeHour + ":" + "0" + timeMinute);
        textView2 = (TextView) findViewById(R.id.msg2);
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent myIntent = new Intent (Alarm.this,AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(Alarm.this,0,myIntent,0);
        OnClickListener listener1 = new OnClickListener(){
            @Override
            public void onClick(View v) {
                textView2.setText("");
                Bundle bundle = new Bundle();
                bundle.putInt(MyConstants.HOUR, timeHour);
                bundle.putInt(MyConstants.MINUTE, timeMinute);
                MyDialogFragment fragment = new MyDialogFragment(new MyHandler());
                fragment.setArguments(bundle);
                FragmentManager manager = getSupportFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                transaction.add(fragment, MyConstants.TIME_PICKER);
                transaction.commit();
            }
        };
        Button btn1 = (Button)findViewById(R.id.button1);
        btn1.setOnClickListener(listener1);
        OnClickListener listener2 = new OnClickListener() {
            @Override
            public void onClick(View v) {
                textView2.setText("");
                cancelAlarm();
            }
        };
        Button btn2 = (Button)findViewById(R.id.button2);
        btn2.setOnClickListener(listener2);
        Button btn = (Button)findViewById(R.id.open_mp);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               startActivity(new Intent(Alarm.this, MediaPlayer.class));
            }
        });
    }
    //A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue.
    //There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
    //Practic folosim un handler pentru a afisa ora la care am setat alarma dupa ce am setat-o
    class MyHandler extends Handler
    {
        @Override
        public void handleMessage (Message msg){
            //A mapping from String keys to various Parcelable values.
            //Bundle getBundle (String key)
            //Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
            Bundle bundle = msg.getData();
            //preluam ora si minutul la care am setat alarma
            timeHour=bundle.getInt(MyConstants.HOUR);
            timeMinute = bundle.getInt(MyConstants.MINUTE);
            //afisam ora la care am setat alarma
            if(timeHour>9&&timeMinute>9)
                textView1.setText(timeHour + ":" + timeMinute);
            else if(timeHour>9&&timeMinute<=9)
                textView1.setText(timeHour + ":" + "0" + timeMinute);
            else if(timeHour<=9&&timeMinute>9)
                textView1.setText("0" + timeHour + ":" + timeMinute);
            else if(timeHour<=9&&timeMinute<=9)
                textView1.setText("0" + timeHour + ":" + "0" + timeMinute);
            setAlarm();
        }
    }
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void setAlarm(){
        // getInstance()
        //Gets a calendar using the default time zone and locale.
        Calendar calendar = Calendar.getInstance();
     //  set(int field, int value)
       // Sets the given calendar field to the given value.
        calendar.set(Calendar.HOUR_OF_DAY,timeHour);
        calendar.set(Calendar.MINUTE,timeMinute);
       // setExact(int type, long triggerAtMillis, PendingIntent operation)
       // Schedules the alarm and if there is already an alarm by the intent then previous one will be canceled.
        //RTC_WAKEUP
        //It is used to fire pending intent at specified time forcing the phone to wake up.
        //Practic prin linia asta de cod setam alarma si verificam daca ora curenta este egala cu ora programata pentru trezire si in caz afirmativ trimitem semnalul(pendingintent) ce este legat la intent astfel stim ca trebuie trimis catre AlarmRceiver, in acelasi timp ii spunem sa "trezeasca" telefonul
                alarmManager.setExact(
                        //ii spunem sa "trezeasca telefonul" in cazul in care trebuie sa sune alarma
                        AlarmManager.RTC_WAKEUP,
                        // preluam ora la care setam alarma si retinem totul transformat in milisecunde
                        calendar.getTimeInMillis(),
                        //verificam daca este timpul sa sunam alarma
                        pendingIntent);
    }
    private void cancelAlarm(){
        if(alarmManager!=null){
            alarmManager.cancel(pendingIntent);
           pendingIntent.cancel();
            AlarmReceiver.stopRingtone();
        }
    }

}

例外情况:

07-11 10:43:43.392 1915-1915/com.never.mediaalarmplayer D/Ringtone: Successfully created local player
07-11 10:43:43.397 1915-1915/com.never.mediaalarmplayer D/AndroidRuntime: Shutting down VM
07-11 10:43:43.397 1915-1915/com.never.mediaalarmplayer E/AndroidRuntime: FATAL EXCEPTION: main
                                                                          Process: com.never.mediaalarmplayer, PID: 1915
                                                                          java.lang.RuntimeException: Unable to start receiver com.never.mediaalarmplayer.AlarmReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'void 安卓.app.Application.dispatchActivityStarted(安卓.app.Activity)' on a null object reference
                                                                              at 安卓.app.ActivityThread.handleReceiver(ActivityThread.java:2732)
                                                                              at 安卓.app.ActivityThread.-wrap14(ActivityThread.java)
                                                                              at 安卓.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
                                                                              at 安卓.os.Handler.dispatchMessage(Handler.java:102)
                                                                              at 安卓.os.Looper.loop(Looper.java:148)
                                                                              at 安卓.app.ActivityThread.main(ActivityThread.java:5417)
                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                              at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                              at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                           Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void 安卓.app.Application.dispatchActivityStarted(安卓.app.Activity)' on a null object reference
                                                                              at 安卓.app.Activity.onStart(Activity.java:1146)
                                                                              at 安卓.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:595)
                                                                              at 安卓.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
                                                                              at com.never.mediaalarmplayer.MediaPlayer.onStart(MediaPlayer.java:78)
                                                                              at com.never.mediaalarmplayer.AlarmReceiver.onReceive(AlarmReceiver.java:23)
                                                                              at 安卓.app.ActivityThread.handleReceiver(ActivityThread.java:2725)
                                                                              at 安卓.app.ActivityThread.-wrap14(ActivityThread.java) 
                                                                              at 安卓.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
                                                                              at 安卓.os.Handler.dispatchMessage(Handler.java:102) 
                                                                              at 安卓.os.Looper.loop(Looper.java:148) 
                                                                              at 安卓.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                              at java.lang.reflect.Method.invoke(Native Method) 
                                                                              at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                              at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

这是我第一次发帖,所以如果有任何问题,我会编辑它,也非常感谢你


共 (1) 个答案

  1. # 1 楼答案

    活动不是像在AlarmReceiver类的onReceive中那样启动的,即

    MediaPlayer ms = new MediaPlayer();
    

    它们由Context.startActivity (Intent)开始。android系统负责启动这些活动,因为它管理一堆活动,并为这些活动发布生命周期回调。因为您自己开始活动,所以您错过了最初的生命周期回调,例如onCreate