歌曲完成后,Cleveroad WaveInApp会显示错误

时间:2017-12-26 13:19:25

标签: android

我试图在我的应用程序中使用Cleveroad WaveInApp https://github.com/Cleveroad/WaveInApp一切正常,但是当Song完成时,它也会停止mediaPlayer.setOnCompletionListener(当我删除此代码时,它可以正常工作)。

当我尝试更改歌曲时,它会崩溃。 错误: -

  

java.lang.NullPointerException:尝试调用接口方法' void com.cleveroad.audiovisualization.InnerAudioVisualization.stopRendering()'在null对象引用上                                                                        在com.cleveroad.audiovisualization.DbmHandler.stopRendering(DbmHandler.java:61)                                                                        在com.cleveroad.audiovisualization.DbmHandler $ 2.onCalmedDown(DbmHandler.java:82)                                                                        在com.cleveroad.audiovisualization.GLAudioVisualizationView $ 1.onCalmedDown(GLAudioVisualizationView.java:49)                                                                        在com.cleveroad.audiovisualization.GLRenderer.onDrawFrame(GLRenderer.java:87)                                                                        在android.opengl.GLSurfaceView $ GLThread.guardedRun(GLSurfaceView.java:1608)                                                                        在android.opengl.GLSurfaceView $ GLThread.run(GLSurfaceView.java:1299)

MainContainer.class

public class MainContainer extends AppCompatActivity
        implements
        NavigationView.OnNavigationItemSelectedListener,
        SeekBar.OnSeekBarChangeListener {

    private static final String LOGTAG = "Friday";
    public static final String isPlay = "isPlay";
    public static final String NOTIFICATION_ACTION = "Notification_Action";
    private static final String VOLUME_BUTTON = "android.media.VOLUME_CHANGED_ACTION";
    SlidingUpPanelLayout slideLayout;
    MusicService mService;
    boolean mBound = false;
    Timer t = new Timer();
    SeekBar seekBar;
    ImageView albumArt;
    ImageView panelAlbumart;
    TextView songname;
    TextView singername;
    TextView seekCurrentDuration;
    TextView seekTotalDuration;
    TextView panelSongname;
    TextView panelSingername;
    ImageView playBtn;
    IntentFilter mIntentFilter;
    RelativeLayout panelHead;
    SeekBar volumeControl;
    AudioManager audioManager;
    AudioVisualization audioVisualization;
    VisualizerDbmHandler vizualizerHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_container);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        setVolumeControlStream(AudioManager.STREAM_MUSIC); //best practice to set volume control
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        ViewPager vp_pages = findViewById(R.id.vp_pages);
        PagerAdapter pagerAdapter = new FragmentAdapter(getSupportFragmentManager());
        vp_pages.setAdapter(pagerAdapter);

        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(isPlay);
        mIntentFilter.addAction(VOLUME_BUTTON);
        mIntentFilter.addAction(NOTIFICATION_ACTION);
        TabLayout tbl_pages = findViewById(R.id.tbl_pages);
        tbl_pages.setupWithViewPager(vp_pages);
        seekBar = findViewById(R.id.seek_bar_red);
        seekBar.setOnSeekBarChangeListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_container, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService
        Intent intent = new Intent(this, MusicService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unbindService(mConnection);
        mBound = false;
    }

    //    control Volume by Seekbar
    private void volumeControl() {
        volumeControl = findViewById(devil.jarvis.friday.R.id.volume_control);
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        if (audioManager != null) {
            volumeControl.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
            volumeControl.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
        }
        volumeControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, i, 0);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }


    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(mReceiver, mIntentFilter);
        init();
        //todo add this when song is played
        audioVisualization.onResume();
        updateUI();
        volumeControl();
    }

    @Override
    public void onPause() {
        audioVisualization.onPause();
        unregisterReceiver(mReceiver);
        super.onPause();

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private void init() {
        albumArt = findViewById(R.id.musicArt);
        panelAlbumart = findViewById(R.id.slidePanelArt);
        songname = findViewById(R.id.song_name);
        singername = findViewById(R.id.singer_name);
        panelSingername = findViewById(R.id.singer_name_head);
        panelSongname = findViewById(R.id.song_name_head);
        seekCurrentDuration = findViewById(R.id.current_time);
        seekTotalDuration = findViewById(R.id.song_duration);
        playBtn = findViewById(R.id.play);
        panelHead = findViewById(R.id.header);
        slideLayout = findViewById(R.id.sliding_layout);
        audioVisualization = findViewById(R.id.visualizer_view);
    }

    public void updateUI() {
        //Update UI
        t.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (mBound) {
                    try {
                        setupMusicUI(mService.getCurrentDuration(), mService.getDuration());
                    } catch (Exception e) {
                        //
                    }
                }
            }
        }, 0, 1000);

    }

    private void setupMusicUI(int currentDuration, int duration) {
        seekBar.setMax(duration);
        seekBar.setProgress(currentDuration);
    }

    //    code for update song details
    private void updateTextInfo() {
        if (mBound) {
            int pos = mService.getPosition();
            panelSongname.setText(arrayList.get(pos));
            panelSingername.setText(artistName.get(pos));
            songname.setText(arrayList.get(pos));
            singername.setText(artistName.get(pos));
            //update album art with text also
            updateAlbumArt();
            changePlayBtn();
            startEqualiser();
//            try{
//                startEqualiser();
//            }catch (Exception e){
//                //
//            }
        }
    }

    private void setSeekbarTime(int position, int duration) {
        int curr_time_seconds = (position / 1000) % 60;
        int curr_time_minutes = (position / 1000) / 60;
        int dur_time_seconds = (duration / 1000) % 60;
        int dur_time_minutes = (duration / 1000) / 60;
        String current_zero_minutes = "0";
        String current_zero_seconds = "0";
        String duration_zero_minues = "0";
        String duration_zero_seconds = "0";
        if (curr_time_minutes > 9)
            current_zero_minutes = "";
        if (curr_time_seconds > 9)
            current_zero_seconds = "";
        if (dur_time_minutes > 9)
            duration_zero_minues = "";
        if (dur_time_seconds > 9)
            duration_zero_seconds = "";
        seekCurrentDuration.setText(current_zero_minutes + curr_time_minutes + ":" + current_zero_seconds + curr_time_seconds);
        seekTotalDuration.setText(duration_zero_minues + dur_time_minutes + ":" + duration_zero_seconds + dur_time_seconds);
    }


    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(VOLUME_BUTTON)) {
                volumeControl();
            }

            if (intent.getAction().equals(isPlay)) {
                boolean show = intent.getBooleanExtra("showPanel", false);
                if (show) {
                    //show Panel here
                    slideLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
                    updateTextInfo();
                }
            } else if (intent.getAction().equals(NOTIFICATION_ACTION)) {
                int action = intent.getIntExtra("action", 0);
                switch (action) {
                    case 1:
                        changePlayBtn();
                        break;
                    case 2:
                        updateTextInfo();
                        break;
                    case 3:
                        updateTextInfo();
                        break;
                    case 4:
                        audioVisualization.release();
                        break;
                    default:
                        break;
                }
            }
        }
    };

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    /**
     * Defines callbacks for service binding, passed to bindService()
     */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            MusicService.LocalBinder binder = (MusicService.LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };


    public void playBtn(View view) {
        if (mBound) {
            mService.play();
            changePlayBtn();
        }
    }

    private void changePlayBtn() {
        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                playBtn.setImageResource(R.drawable.ic_pause_button);
            } else {
                playBtn.setImageResource(R.drawable.ic_play_arrow);
            }
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        setSeekbarTime(i, mediaPlayer.getDuration());
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        mService.changeSeekTo(seekBar.getProgress());
    }

    public void previousBtn(View view) {
        if (mBound) {
            mService.previous();
            updateTextInfo();
        }
    }

    public void nextBtn(View view) {
        if (mBound) {
            mService.next();
            updateTextInfo();
        }
    }

    public void startEqualiser() {
        try {
            vizualizerHandler = VisualizerDbmHandler.Factory.newVisualizerHandler(getApplicationContext(), mediaPlayer);
            audioVisualization.linkTo(vizualizerHandler);

        } catch (Exception e) {
//            TODO change it to snackbar message
            Toast.makeText(mService, "Please Give Mic Permission", Toast.LENGTH_SHORT).show();
        }
    }


    public void updateAlbumArt() {

        Glide
                .with(getApplicationContext())
                .load(songThumb.get(musicPosition))
                .placeholder(R.drawable.ic_default_icon)
                .into(panelAlbumart);
        Glide
                .with(getApplicationContext())
                .load(songThumb.get(musicPosition))
                .placeholder(R.drawable.ic_default_icon)
                .into(albumArt);
    }
}

这是我的MusicService.class

public class MusicService extends MediaBrowserServiceCompat implements
        MediaPlayer.OnCompletionListener,
        AudioManager.OnAudioFocusChangeListener {

    private static final String LOGTAG = "Friday";
    public static int musicPosition;
    public static MediaPlayer mediaPlayer;
    Uri u;
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    Notification status;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null && intent.getExtras() != null && intent.getExtras().containsKey("pos")) {
            musicPosition = intent.getIntExtra("pos", 0);
            if (mediaPlayer != null) {
                mediaPlayer.stop();
                mediaPlayer.reset();
                mediaPlayer.release();

            }
            if (arrayList != null) {
                u = Uri.parse(songPath.get(musicPosition));
                mediaPlayer = MediaPlayer.create(getApplicationContext(), u);
            }
            try {
                playSong();
            } catch (Exception e) {
                next();
            }
        }
        if (intent.getAction() != null) {
            if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
                previous();
            } else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
                play();
                sendAction(1);
            } else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
                next();
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void playSong() {
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.start();
        showNotification();
    }

    private void sendAction(int action){
        /* 1 for play or pause
         * 2 for next
         * 3 for previous
         */
        Intent intent = new Intent();
        intent.setAction(MainContainer.NOTIFICATION_ACTION);
        intent.putExtra("action",action);
        sendBroadcast(intent);
    }
    public int getPosition() {
        return musicPosition;
    }

    public int getCurrentDuration() {
        return mediaPlayer.getCurrentPosition();
    }

    public int getDuration() {
        return mediaPlayer.getDuration();
    }

    public void changeSeekTo(int progress) {
        mediaPlayer.seekTo(progress);
    }

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        public MusicService getService() {
            // Return this instance of LocalService so clients can call public methods
            return MusicService.this;
        }
    }


    public void next() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            musicPosition = (musicPosition + 1) % songPath.size();
            u = Uri.parse(songPath.get(musicPosition));
            mediaPlayer = MediaPlayer.create(getApplicationContext(), u);
            playSong();
            sendAction(2);
        }
    }

    public void previous() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            musicPosition = (musicPosition - 1 < 0) ? songPath.size() - 1 : musicPosition - 1;
            u = Uri.parse(songPath.get(musicPosition));
            mediaPlayer = MediaPlayer.create(getApplicationContext(), u);
            playSong();
            sendAction(3);
        }
    }

    public void play() {
        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                showNotification();
            } else {
                mediaPlayer.start();
                showNotification();
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onAudioFocusChange(int i) {
        mediaPlayer.stop();
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        sendAction(4);
        next();
    }

    @Nullable
    @Override
    public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) {
        return null;
    }

    @Override
    public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {

    }
.
.
.
}

我不知道发生了什么。 任何人都可以知道它。

1 个答案:

答案 0 :(得分:0)

    VisualizerDbmHandler中已经有了mediaPlayer.setOnCompleteListener。因此,要在其他地方使用它,您应该使用setInnerOnCompletionListener方法将自己的完整侦听器添加到VisualizerDbmHandler
    尝试不重新创建mediaPlayer,但要为其设置新的来源
    **我的结论是**:正如您在MediaPlayer的源代码中看到的那样 - 如果出现未处理的错误,它将调用onCompletion)。因此,我认为,由于及时重新创建了mediaPlayer,当你调用startEqualizer(重新创建visualizerHandler并将其链接到visualizer视图)时,方法linkTo - 库调用释放到之前的visualizerHandler并将setup变量设置为null,这样就可以调用stopRendering如果在MediaPlayer的重置/停止/释放期间发生某些错误时onCompletion调用,则为null引用。