mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-31 14:15:14 +00:00
Implemented current/total time and progress slider in MPRIS plugin
CCMAIL: zelitomas@gmail.com.
This commit is contained in:
committed by
Albert Vaca
parent
edff3a86bc
commit
8e23ff5cf6
@@ -88,6 +88,39 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:id="@+id/progress_textview"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="8dip"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/positionSeek"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:id="@+id/time_textview"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="8dip"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
package org.kde.kdeconnect.Plugins.MprisPlugin;
|
package org.kde.kdeconnect.Plugins.MprisPlugin;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -52,6 +51,9 @@ public class MprisActivity extends ActionBarActivity {
|
|||||||
//TODO 2: Add a message when no players are detected after loading completes
|
//TODO 2: Add a message when no players are detected after loading completes
|
||||||
|
|
||||||
private String deviceId;
|
private String deviceId;
|
||||||
|
private final Handler positionSeekUpdateHandler = new Handler();
|
||||||
|
private Runnable positionSeekUpdateRunnable;
|
||||||
|
private boolean positionSeekUpdateScheduled = false;
|
||||||
|
|
||||||
protected void connectToPlugin() {
|
protected void connectToPlugin() {
|
||||||
|
|
||||||
@@ -77,12 +79,31 @@ public class MprisActivity extends ActionBarActivity {
|
|||||||
String s = mpris.getCurrentSong();
|
String s = mpris.getCurrentSong();
|
||||||
((TextView) findViewById(R.id.now_playing_textview)).setText(s);
|
((TextView) findViewById(R.id.now_playing_textview)).setText(s);
|
||||||
|
|
||||||
|
|
||||||
|
String text = mpris.getLength() / 60000000 + ":";
|
||||||
|
int seconds = (mpris.getLength() % 60000000) / 1000000;
|
||||||
|
// needed to show length properly (eg 4:05 instead of 4:5)
|
||||||
|
if(seconds < 10) text = text + "0";
|
||||||
|
text = text + seconds;
|
||||||
|
|
||||||
|
SeekBar positionSeek = (SeekBar)findViewById(R.id.positionSeek);
|
||||||
|
positionSeek.setMax(mpris.getLength());
|
||||||
|
positionSeek.setProgress(mpris.getPosition());
|
||||||
|
|
||||||
int volume = mpris.getVolume();
|
int volume = mpris.getVolume();
|
||||||
|
((TextView) findViewById(R.id.time_textview)).setText(text);
|
||||||
|
|
||||||
|
|
||||||
((SeekBar) findViewById(R.id.volume_seek)).setProgress(volume);
|
((SeekBar) findViewById(R.id.volume_seek)).setProgress(volume);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
boolean isPlaying = mpris.isPlaying();
|
boolean isPlaying = mpris.isPlaying();
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_pause);
|
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_pause);
|
||||||
|
if(!positionSeekUpdateScheduled) {
|
||||||
|
positionSeekUpdateRunnable.run();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_play);
|
((ImageButton) findViewById(R.id.play_button)).setImageResource(android.R.drawable.ic_media_play);
|
||||||
}
|
}
|
||||||
@@ -118,14 +139,17 @@ public class MprisActivity extends ActionBarActivity {
|
|||||||
String player = playerList.get(pos);
|
String player = playerList.get(pos);
|
||||||
mpris.setPlayer(player);
|
mpris.setPlayer(player);
|
||||||
//Spotify doesn't support changing the volume yet...
|
//Spotify doesn't support changing the volume yet...
|
||||||
|
//Also doesn't support seeking and telling actual position...
|
||||||
if (player.equals("Spotify")) {
|
if (player.equals("Spotify")) {
|
||||||
findViewById(R.id.volume_layout).setVisibility(View.INVISIBLE);
|
findViewById(R.id.volume_layout).setVisibility(View.INVISIBLE);
|
||||||
findViewById(R.id.rew_button).setVisibility(View.GONE);
|
findViewById(R.id.rew_button).setVisibility(View.GONE);
|
||||||
findViewById(R.id.ff_button).setVisibility(View.GONE);
|
findViewById(R.id.ff_button).setVisibility(View.GONE);
|
||||||
|
findViewById(R.id.positionSeek).setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
findViewById(R.id.volume_layout).setVisibility(View.VISIBLE);
|
findViewById(R.id.volume_layout).setVisibility(View.VISIBLE);
|
||||||
findViewById(R.id.rew_button).setVisibility(View.VISIBLE);
|
findViewById(R.id.rew_button).setVisibility(View.VISIBLE);
|
||||||
findViewById(R.id.ff_button).setVisibility(View.VISIBLE);
|
findViewById(R.id.ff_button).setVisibility(View.VISIBLE);
|
||||||
|
findViewById(R.id.positionSeek).setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +372,68 @@ public class MprisActivity extends ActionBarActivity {
|
|||||||
MprisPlugin mpris = (MprisPlugin) device.getPlugin("plugin_mpris");
|
MprisPlugin mpris = (MprisPlugin) device.getPlugin("plugin_mpris");
|
||||||
if (mpris == null) return;
|
if (mpris == null) return;
|
||||||
mpris.setVolume(seekBar.getProgress());
|
mpris.setVolume(seekBar.getProgress());
|
||||||
|
positionSeekUpdateRunnable.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
positionSeekUpdateRunnable = new Runnable() {
|
||||||
|
|
||||||
|
private long lastTime;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final SeekBar positionSeek = (SeekBar)findViewById(R.id.positionSeek);
|
||||||
|
final Runnable thisRunnable = this;
|
||||||
|
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
|
||||||
|
@Override
|
||||||
|
public void onServiceStart(BackgroundService service) {
|
||||||
|
positionSeekUpdateScheduled = false;
|
||||||
|
Device device = service.getDevice(deviceId);
|
||||||
|
MprisPlugin mpris = (MprisPlugin) device.getPlugin("plugin_mpris");
|
||||||
|
if (mpris == null) return;
|
||||||
|
positionSeek.setProgress(mpris.getPosition());
|
||||||
|
if(!mpris.isPlaying()) return;
|
||||||
|
positionSeekUpdateHandler.postDelayed(thisRunnable, 1000);
|
||||||
|
positionSeekUpdateScheduled = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
((SeekBar)findViewById(R.id.positionSeek)).setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean byUser) {
|
||||||
|
String text = progress / 60000000 + ":";
|
||||||
|
int seconds = (progress % 60000000) / 1000000;
|
||||||
|
if(seconds < 10) text = text + "0";
|
||||||
|
text = text + seconds;
|
||||||
|
((TextView)findViewById(R.id.progress_textview)).setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
|
positionSeekUpdateHandler.removeCallbacks(positionSeekUpdateRunnable);
|
||||||
|
positionSeekUpdateScheduled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(final SeekBar seekBar) {
|
||||||
|
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
|
||||||
|
@Override
|
||||||
|
public void onServiceStart(BackgroundService service) {
|
||||||
|
Device device = service.getDevice(deviceId);
|
||||||
|
MprisPlugin mpris = (MprisPlugin) device.getPlugin("plugin_mpris");
|
||||||
|
if (mpris == null) return;
|
||||||
|
mpris.setPosition(seekBar.getProgress());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,9 @@ public class MprisPlugin extends Plugin {
|
|||||||
|
|
||||||
private String currentSong = "";
|
private String currentSong = "";
|
||||||
private int volume = 50;
|
private int volume = 50;
|
||||||
|
private int length = 0;
|
||||||
|
private int lastPosition;
|
||||||
|
private long lastPositionTime;
|
||||||
private Handler playerStatusUpdated = null;
|
private Handler playerStatusUpdated = null;
|
||||||
|
|
||||||
private ArrayList<String> playerList = new ArrayList<String>();
|
private ArrayList<String> playerList = new ArrayList<String>();
|
||||||
@@ -50,6 +53,8 @@ public class MprisPlugin extends Plugin {
|
|||||||
private String player = "";
|
private String player = "";
|
||||||
private boolean playing = false;
|
private boolean playing = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPluginName() {
|
public String getPluginName() {
|
||||||
return "plugin_mpris";
|
return "plugin_mpris";
|
||||||
@@ -83,6 +88,7 @@ public class MprisPlugin extends Plugin {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
requestPlayerList();
|
requestPlayerList();
|
||||||
|
lastPositionTime = System.currentTimeMillis();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +103,6 @@ public class MprisPlugin extends Plugin {
|
|||||||
np.set("action",s);
|
np.set("action",s);
|
||||||
device.sendPackage(np);
|
device.sendPackage(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVolume(int volume) {
|
public void setVolume(int volume) {
|
||||||
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
||||||
np.set("player",player);
|
np.set("player",player);
|
||||||
@@ -105,6 +110,15 @@ public class MprisPlugin extends Plugin {
|
|||||||
device.sendPackage(np);
|
device.sendPackage(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPosition(int position) {
|
||||||
|
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
||||||
|
np.set("player",player);
|
||||||
|
np.set("SetPosition", position);
|
||||||
|
device.sendPackage(np);
|
||||||
|
this.lastPosition = position;
|
||||||
|
this.lastPositionTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
public void Seek(int offset) {
|
public void Seek(int offset) {
|
||||||
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
||||||
np.set("player",player);
|
np.set("player",player);
|
||||||
@@ -116,10 +130,15 @@ public class MprisPlugin extends Plugin {
|
|||||||
public boolean onPackageReceived(NetworkPackage np) {
|
public boolean onPackageReceived(NetworkPackage np) {
|
||||||
if (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_MPRIS)) return false;
|
if (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_MPRIS)) return false;
|
||||||
|
|
||||||
if (np.has("nowPlaying") || np.has("volume") || np.has("isPlaying")) {
|
if (np.has("nowPlaying") || np.has("volume") || np.has("isPlaying") || np.has("length") || np.has("pos")) {
|
||||||
if (np.getString("player").equals(player)) {
|
if (np.getString("player").equals(player)) {
|
||||||
currentSong = np.getString("nowPlaying", currentSong);
|
currentSong = np.getString("nowPlaying", currentSong);
|
||||||
volume = np.getInt("volume", volume);
|
volume = np.getInt("volume", volume);
|
||||||
|
length = np.getInt("length", length);
|
||||||
|
if(np.has("pos")){
|
||||||
|
lastPosition = np.getInt("pos", lastPosition);
|
||||||
|
lastPositionTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
playing = np.getBoolean("isPlaying", playing);
|
playing = np.getBoolean("isPlaying", playing);
|
||||||
if (playerStatusUpdated != null) {
|
if (playerStatusUpdated != null) {
|
||||||
try {
|
try {
|
||||||
@@ -208,10 +227,20 @@ public class MprisPlugin extends Plugin {
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLength(){ return length; }
|
||||||
|
|
||||||
public boolean isPlaying() {
|
public boolean isPlaying() {
|
||||||
return playing;
|
return playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPosition(){
|
||||||
|
|
||||||
|
if(playing)
|
||||||
|
return lastPosition + (int)(System.currentTimeMillis() - lastPositionTime)*1000;
|
||||||
|
else
|
||||||
|
return lastPosition;
|
||||||
|
}
|
||||||
|
|
||||||
private void requestPlayerList() {
|
private void requestPlayerList() {
|
||||||
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
|
||||||
np.set("requestPlayerList",true);
|
np.set("requestPlayerList",true);
|
||||||
|
Reference in New Issue
Block a user