This commit is contained in:
Tobias Fella 2022-04-18 20:10:18 +02:00
parent 0292888774
commit 27d5311171
3 changed files with 83 additions and 130 deletions

View File

@ -74,6 +74,7 @@ add_definitions(-DQT_NO_CAST_FROM_ASCII
-DQT_DISABLE_DEPRECATED_BEFORE=0x050d00 -DQT_DISABLE_DEPRECATED_BEFORE=0x050d00
) )
ki18n_install(po)
install(PROGRAMS org.kde.kasts.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(PROGRAMS org.kde.kasts.desktop DESTINATION ${KDE_INSTALL_APPDIR})
install(FILES org.kde.kasts.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES org.kde.kasts.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})

View File

@ -25,7 +25,6 @@ import androidx.media.app.NotificationCompat.MediaStyle;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
@ -33,98 +32,61 @@ public class KastsActivity extends QtActivity
{ {
private static final String TAG = "org.kde.kasts.mediasession"; private static final String TAG = "org.kde.kasts.mediasession";
class MediaData {
public String title = "Unknown Media";
public String author = "Unknown Artist";
public String album = "Unknown Album";
public long position = 0;
public long duration = 0;
public float playbackSpeed = 1;
public int state = 2;
// add more variables here
}
static MediaData mediaData;
static MediaSessionCompat mSession;
private static PlaybackStateCompat.Builder mPBuilder;
private static KastsActivity activity; private static KastsActivity activity;
void updateNotification() { private static MediaData mediaData;
private static MediaSessionCompat mediaSession;
private static PlaybackStateCompat.Builder mediaPlayback;
// TODO: Change all of these variables to the values in mediaData private static NotificatiooCompat.Builder notification;
// add other required values
MediaMetadataCompat.Builder metadata = new MediaMetadataCompat.Builder(); private static NotificationCompat.Action.Builder play;
private static NotificationCompat.Action.Builder pause;
switch(mediaData.state) private static NotificationCompat.Action.Builder next;
{ private static MediaStyle mediaStyle;
case 0: private static NotificationManager notificationManager;
mPBuilder.setState(PlaybackStateCompat.STATE_PLAYING, mediaData.position, mediaData.playbackSpeed);
case 1:
mPBuilder.setState(PlaybackStateCompat.STATE_PAUSED, mediaData.position, mediaData.playbackSpeed);
case 2:
mPBuilder.setState(PlaybackStateCompat.STATE_STOPPED, mediaData.position, mediaData.playbackSpeed);
}
metadata.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mediaData.title);
metadata.putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, mediaData.author);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mediaData.author);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, mediaData.album);
metadata.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mediaData.duration);
//TODO Image
mSession.setMetadata(metadata.build());
void initNotification() {
Intent iPlay = new Intent(this, Receiver.class); Intent iPlay = new Intent(this, Receiver.class);
iPlay.setAction("ACTION_PLAY"); iPlay.setAction("ACTION_PLAY");
PendingIntent piPlay = PendingIntent.getBroadcast(this, 0, iPlay, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent piPlay = PendingIntent.getBroadcast(this, 0, iPlay, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aPlay = new NotificationCompat.Action.Builder( play = new NotificationCompat.Action.Builder(R.drawable.ic_play_white, "Play", piPlay);
R.drawable.ic_play_white, "Play", piPlay);
Intent iPause = new Intent(this, Receiver.class); Intent iPause = new Intent(this, Receiver.class);
iPause.setAction("ACTION_PAUSE"); iPause.setAction("ACTION_PAUSE");
PendingIntent piPause = PendingIntent.getBroadcast(this, 0, iPause, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent piPause = PendingIntent.getBroadcast(this, 0, iPause, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aPause = new NotificationCompat.Action.Builder( pause = new NotificationCompat.Action.Builder(R.drawable.ic_pause_white, "Pause", piPause);
R.drawable.ic_pause_white, "Pause", piPause);
Intent iNext = new Intent(this, Receiver.class); Intent iNext = new Intent(this, Receiver.class);
iNext.setAction("ACTION_NEXT"); iNext.setAction("ACTION_NEXT");
PendingIntent piNext = PendingIntent.getBroadcast(this, 0, iNext, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent piNext = PendingIntent.getBroadcast(this, 0, iNext, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aNext = new NotificationCompat.Action.Builder( next = new NotificationCompat.Action.Builder(R.drawable.ic_next_white, "Next", piNext);
R.drawable.ic_next_white, "Next", piNext);
Intent iOpenActivity = new Intent(this, KastsActivity.class); Intent iOpenActivity = new Intent(activity, KastsActivity.class);
notification = new NotificationCompat.Builder(activity, "media_control");
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, "media_control"); notification.setAutoCancel(false)
notification
.setAutoCancel(false)
.setShowWhen(false) .setShowWhen(false)
.setVisibility(androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC) .setVisibility(androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC)
.setSubText(mediaData.author)
.setContentTitle(mediaData.title)
.setSmallIcon(this.getApplicationInfo().icon) .setSmallIcon(this.getApplicationInfo().icon)
.setChannelId("org.kde.kasts.channel") .setChannelId("org.kde.kasts.channel")
.setContentText("Unknown") .setContentText("Unknown")
.setContentIntent(PendingIntent.getActivity(this, 0, iOpenActivity, 0)); .setContentIntent(PendingIntent.getActivity(this, 0, iOpenActivity, 0));
if(mediaData.state == 0) mediaStyle = new MediaStyle();
notification.addAction(aPause.build()); mediaStyle.setMediaSession(mediaSession.getSessionToken());
else
notification.addAction(aPlay.build());
notification.addAction(aNext.build());
mSession.setPlaybackState(mPBuilder.build());
MediaStyle mediaStyle = new MediaStyle();
mediaStyle.setMediaSession(mSession.getSessionToken());
mediaStyle.setShowActionsInCompactView(0, 1, 2); mediaStyle.setShowActionsInCompactView(0, 1, 2);
notification.setStyle(mediaStyle); notification.setStyle(mediaStyle);
mediaSession.setActive(true);
notification.setGroup("MprisMediaSession"); notification.setGroup("MprisMediaSession");
mSession.setActive(true);
NotificationManager nm = ContextCompat.getSystemService(this, NotificationManager.class); NotificationManager nm = ContextCompat.getSystemService(this, NotificationManager.class);
NotificationChannel channel = new NotificationChannel("org.kde.kasts.channel", "KastsChannel", NotificationManager.IMPORTANCE_HIGH); NotificationChannel channel = new NotificationChannel("org.kde.kasts.channel", "KastsChannel", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("No Media Loaded"); channel.setDescription("No Media Loaded");
channel.enableLights(false); channel.enableLights(false);
channel.enableVibration(false); channel.enableVibration(false);
nm.createNotificationChannel(channel); notificationManager.createNotificationChannel(channel);
}
void updateNotification() {
nm.notify(0x487671, notification.build()); nm.notify(0x487671, notification.build());
} }
@ -132,24 +94,24 @@ public class KastsActivity extends QtActivity
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mSession = new MediaSessionCompat(this, TAG); mediaSession = new MediaSessionCompat(this, TAG);
mSession.setFlags( mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS | MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mSession.setCallback(new MediaSessionCallback(this)); mediaSession.setCallback(new MediaSessionCallback(this));
mPBuilder = new PlaybackStateCompat.Builder(); mediaPlayback = new PlaybackStateCompat.Builder();
activity = this; activity = this;
mediaData = new MediaData(); mediaData = new MediaData();
updateNotification(); initNotification();
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
mSession.release(); mediaSession.release();
} }
private final class MediaSessionCallback extends MediaSessionCompat.Callback { private final class MediaSessionCallback extends MediaSessionCompat.Callback {
@ -165,8 +127,8 @@ public class KastsActivity extends QtActivity
public void onPlay() { public void onPlay() {
super.onPlay(); super.onPlay();
if (!mSession.isActive()) { if (!mediaSession.isActive()) {
mSession.setActive(true); mediaSession.setActive(true);
} }
} }
@ -175,7 +137,7 @@ public class KastsActivity extends QtActivity
super.onPause(); super.onPause();
//JNI to audiomanager pause //JNI to audiomanager pause
//setPlaybackState for mSession //setPlaybackState for mediaSession
} }
@Override @Override
@ -183,7 +145,7 @@ public class KastsActivity extends QtActivity
super.onStop(); super.onStop();
//JNI call to audiomanager stop //JNI call to audiomanager stop
mSession.setActive(false); mediaSession.setActive(false);
} }
@Override @Override
@ -194,53 +156,45 @@ public class KastsActivity extends QtActivity
} }
} }
/* public static void setSessionState(int state, float speed, long position)
* JNI METHODS
*/
public static void setSessionState(int state)
{ {
//TODO: set state in mediadata Log.e(TAG, "Updating session state");
notification.clearActions();
mediaData.state = state; switch(state) {
Log.d(TAG, "JAVA setSessionState called."); case 0:
mediaPlayback.setState(MediaPlaybackCompat.PLAYING, position, playbackSpeed);
notification.addAction(pause.build());
notification.addAction(next.build());
break;
case 1:
mediaPlayback.setState(MediaPlaybackCompat.PAUSED, position, playbackSpeed);
notification.addAction(play.build());
notification.addAction(next.build());
break;
case 2:
mediaPlayback.setState(MediaPlaybackCompat.STOPPED, position, playbackSpeed);
notification.addAction(play.build());
notification.addAction(next.build());
break;
}
mediaSession.setPlaybackState(mediaPlayback.build());
activity.updateNotification(); activity.updateNotification();
} }
public static void setMetadata(String title, String author, String album, long position, long duration, float rate) public static void setMetadata(String title, String author, String album, long position, long duration, float rate)
{ {
Log.d(TAG, "JAVA setMetadata called."); Log.e(TAG, "Handling metadata");
mediaData.title = title;
mediaData.author = author;
mediaData.album = album;
mediaData.position = position;
mediaData.duration = duration;
mediaData.playbackSpeed = rate;
activity.updateNotification(); var metadata = new MediaMetadataCompat.Builder();
} metadata.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title);
metadata.putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, author);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, author);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album);
metadata.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
public static void setPlaybackSpeed(int rate) notification.setSubText(author).setContentTitle(title);
{ mediaSession.setMetadata(metadata.build());
Log.d(TAG, "JAVA setPlaybackSpeed called.");
mediaData.playbackSpeed = rate;
activity.updateNotification();
}
public static void setDuration(long duration)
{
Log.d(TAG, "JAVA setDuration called.");
mediaData.duration = duration;
activity.updateNotification();
}
public static void setPosition(long position)
{
Log.d(TAG, "JAVA setPosition called.");
mediaData.position = position;
activity.updateNotification(); activity.updateNotification();
} }

View File

@ -16,29 +16,29 @@ static void play(JNIEnv *env, jobject thiz)
{ {
Q_UNUSED(env) Q_UNUSED(env)
Q_UNUSED(thiz) Q_UNUSED(thiz)
qDebug() << "JAVA play() working."; qWarning() << "JAVA play() working.";
emit MediaSessionClient::instance()->play(); Q_EMIT MediaSessionClient::instance()->play();
} }
static void pause(JNIEnv *env, jobject thiz) static void pause(JNIEnv *env, jobject thiz)
{ {
Q_UNUSED(env) Q_UNUSED(env)
Q_UNUSED(thiz) Q_UNUSED(thiz)
qDebug() << "JAVA pause() working."; qWarning() << "JAVA pause() working.";
emit MediaSessionClient::instance()->pause(); Q_EMIT MediaSessionClient::instance()->pause();
} }
static void next(JNIEnv *env, jobject thiz) static void next(JNIEnv *env, jobject thiz)
{ {
Q_UNUSED(env) Q_UNUSED(env)
Q_UNUSED(thiz) Q_UNUSED(thiz)
qDebug() << "JAVA next() working."; qWarning() << "JAVA next() working.";
emit MediaSessionClient::instance()->next(); Q_EMIT MediaSessionClient::instance()->next();
} }
static void seek(JNIEnv *env, jobject thiz, jlong position) static void seek(JNIEnv *env, jobject thiz, jlong position)
{ {
Q_UNUSED(env) Q_UNUSED(env)
Q_UNUSED(thiz) Q_UNUSED(thiz)
Q_UNUSED(position) Q_UNUSED(position)
qDebug() << "JAVA seek() working."; qWarning() << "JAVA seek() working.";
} }
static const JNINativeMethod methods[] {{"playerPlay", "()V", reinterpret_cast<void *>(play)}, static const JNINativeMethod methods[] {{"playerPlay", "()V", reinterpret_cast<void *>(play)},
{"playerPause", "()V", reinterpret_cast<void *>(pause)}, {"playerPause", "()V", reinterpret_cast<void *>(pause)},
@ -104,25 +104,23 @@ MediaSessionClient* MediaSessionClient::instance()
void MediaSessionClient::setSessionPlaybackState() void MediaSessionClient::setSessionPlaybackState()
{ {
qDebug() << "MediaSessionClient::setSessionPlaybackState called with state value = " << m_audioPlayer->playbackState(); qWarning() << "MediaSessionClient::setSessionPlaybackState called with state value = " << m_audioPlayer->playbackState();
int status = -1; int status = -1;
switch(m_audioPlayer->playbackState()) { switch(m_audioPlayer->playbackState()) {
case QMediaPlayer::PlayingState : case QMediaPlayer::PlayingState:
status = 0; status = 0;
break; break;
case QMediaPlayer::PausedState : case QMediaPlayer::PausedState:
status = 1; status = 1;
break; break;
case QMediaPlayer::StoppedState : case QMediaPlayer::StoppedState:
status = 2; status = 2;
break; break;
} }
#ifndef Q_OS_ANDROID
Q_UNUSED(status)
#endif
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
QAndroidJniObject::callStaticMethod<void>("org/kde/kasts/KastsActivity", "setSessionState", "(I)V", status); QAndroidJniObject::callStaticMethod<void>("org/kde/kasts/KastsActivity", "setSessionState", "(I)V", status);
#else
Q_UNUSED(status)
#endif #endif
} }