无法实例化服务,没有零参数构造函数

时间:2020-04-26 12:36:57

标签: java android android-service android-notifications android-intentservice

搜索:

几天来,我一直在研究如何控制MediaPlayer中运行的Service。 基本上,ForegroundService / NotificationCompat

中的媒体控件

我读了一个答案https://stackoverflow.com/questions/11270898/how-to-execute-a-method-by-clicking-a-notification,说在同一个类中使用IntentService

我做了什么:

Service开始时,MediaPlayer已经在播放歌曲。因此,意味着MediaPlayer.isPlaying()将返回true

然后我在音乐播放服务中实现了IntentService,并在IntentService中注册了AndroidManifest.xml

我创建了两个Action,分别是暂停恢复。因此,默认情况下,该通知的暂停按钮Action,当用户单击该通知时,它将使用Intent(MusicService.this, MusicNotificationService.class).setAction("test.pause")

发送PendingIntent

问题:

我可以连续播放歌曲,没有任何问题。另外,还会显示暂停按钮

但是,每当我点击暂停按钮时,我都会收到以下错误消息。

我的代码:

public class MusicService extends Service {

    private ArrayList<String> nameList, artistList, urlList;
    private int position;

    private MediaPlayer mediaPlayer;

    private NotificationCompat.Builder builder;
    private NotificationManager manager;

    private PendingIntent pendingMain;

    private NotificationCompat.Action actionPause, actionResume;
    private static final String channelId = "Test", subtext = "Now Playing";
    private static final String[] actions = {"test.pause", "test.resume"},
                                  actionTitles = {"pause", "resume"};

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        nameList = intent.getStringArrayListExtra("names");
        artistList = intent.getStringArrayListExtra("artists");
        urlList = intent.getStringArrayListExtra("urls");
        position = intent.getIntExtra("position", 0);

        builder = new NotificationCompat.Builder(this, channelId)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.ic_music_note)
                .setContentTitle(nameList.get(position))
                .setContentText(artistList.get(position))
                .setSubText(subtext)
                .setContentIntent(pendingMain)
                .addAction(actionPause)
                .setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
                            .setShowActionsInCompactView(0)
                            .setShowCancelButton(true));

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel();
            startForeground(99, builder.build());
        } else {
            startForeground(99, builder.build());
        }

        play(urlList.get(position));

        return START_NOT_STICKY;
    }

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

        manager = getSystemService(NotificationManager.class);

        Intent mainIntent = new Intent(this, MainActivity.class);
        pendingMain = PendingIntent.getActivity(this, 3, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Intent pause = new Intent(this, MusicNotificationService.class).setAction(actions[0]);
        PendingIntent pendingPause = PendingIntent.getService(this, 4, pause, PendingIntent.FLAG_ONE_SHOT);

        Intent resume = new Intent(this, MusicNotificationService.class).setAction(actions[1]);
        PendingIntent pendingResume = PendingIntent.getService(this, 5, resume, PendingIntent.FLAG_ONE_SHOT);

        actionPause = new NotificationCompat.Action(R.drawable.ic_pause, actionTitles[0], pendingPause);
        actionResume = new NotificationCompat.Action(R.drawable.ic_play, actionTitles[1], pendingResume);

        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }

        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.start();
            }
        });

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                if (position + 1 < urlList.size()) {
                    position += 1;
                    builder.setContentTitle(nameList.get(position));
                    builder.setContentText(artistList.get(position));
                    manager.notify(99, builder.build());
                    play(urlList.get(position));
                } else {
                    mp.stop();
                }
            }
        });
    }

    public class MusicNotificationService extends IntentService {

        public MusicNotificationService() {
            super(MusicNotificationService.class.getSimpleName());
        }

        @SuppressLint("RestrictedApi")
        @Override
        protected void onHandleIntent(@Nullable Intent intent) {
            String action = Objects.requireNonNull(intent).getAction();
            if (action != null) {
                if (mediaPlayer.isPlaying()) {
                    if (action.equalsIgnoreCase(actions[0])) {
                        mediaPlayer.pause();
                        builder.mActions.set(0, actionResume);
                        manager.notify(99, builder.build());
                    }
                } else if (action.equalsIgnoreCase(actions[1])) {
                    mediaPlayer.start();
                    builder.mActions.set(0, actionPause);
                    manager.notify(99, builder.build());
                }
            }
        }
    }
}

错误:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: test.music, PID: 20335
java.lang.RuntimeException: Unable to instantiate service test.music.MusicService$MusicNotificationService:
java.lang.InstantiationException: java.lang.Class<test.music.MusicService$MusicNotificationService>
has no zero argument constructor

    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3974)
    at android.app.ActivityThread.access$1600(ActivityThread.java:220)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1899)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:224)
    at android.app.ActivityThread.main(ActivityThread.java:7520)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
 Caused by: java.lang.InstantiationException: java.lang.Class<test.music.MusicService$MusicNotificationService>
            has no zero argument constructor
    at java.lang.Class.newInstance(Native Method)
    at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
    at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:66)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3969)
    at android.app.ActivityThread.access$1600(ActivityThread.java:220) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1899) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:224) 
    at android.app.ActivityThread.main(ActivityThread.java:7520) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

我想要实现的目标:

目前,我希望能够暂停和恢复音乐。

0 个答案:

没有答案