mirror of
https://github.com/badaix/snapcast.git
synced 2025-04-29 10:17:16 +02:00
configurable volume
This commit is contained in:
parent
506f179ed2
commit
80ea2a37a3
7 changed files with 132 additions and 34 deletions
|
@ -10,17 +10,18 @@ import android.widget.TextView;
|
|||
|
||||
|
||||
import de.badaix.snapcast.control.ClientInfo;
|
||||
import de.badaix.snapcast.control.Volume;
|
||||
|
||||
public class ClientInfoItem extends LinearLayout {
|
||||
public class ClientInfoItem extends LinearLayout implements SeekBar.OnSeekBarChangeListener {
|
||||
|
||||
public static interface OnAppItemChangedListener {
|
||||
abstract void onChanged(ClientInfo clientInfo, boolean enabled);
|
||||
public interface ClientInfoItemListener {
|
||||
void onVolumeChanged(ClientInfoItem clientInfoItem, Volume volume);
|
||||
}
|
||||
|
||||
private TextView title;
|
||||
private TextView summary;
|
||||
private SeekBar volumeSeekBar;
|
||||
private ClientInfo clientInfo;
|
||||
private ClientInfoItemListener listener = null;
|
||||
|
||||
public ClientInfoItem(Context context, ClientInfo clientInfo) {
|
||||
super(context);
|
||||
|
@ -28,10 +29,10 @@ public class ClientInfoItem extends LinearLayout {
|
|||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
vi.inflate(R.layout.client_info, this);
|
||||
title = (TextView) findViewById(R.id.title);
|
||||
summary = (TextView) findViewById(R.id.summary);
|
||||
volumeSeekBar = (SeekBar) findViewById(R.id.volumeSeekBar);
|
||||
volumeSeekBar.setMax(100);
|
||||
setClientInfo(clientInfo);
|
||||
volumeSeekBar.setOnSeekBarChangeListener(this);
|
||||
}
|
||||
|
||||
public void setClientInfo(final ClientInfo clientInfo) {
|
||||
|
@ -40,7 +41,6 @@ public class ClientInfoItem extends LinearLayout {
|
|||
title.setText(clientInfo.getName());
|
||||
else
|
||||
title.setText(clientInfo.getHost());
|
||||
summary.setText(clientInfo.getMac());
|
||||
volumeSeekBar.setProgress(clientInfo.getVolume().getPercent());
|
||||
}
|
||||
|
||||
|
@ -48,4 +48,27 @@ public class ClientInfoItem extends LinearLayout {
|
|||
return clientInfo;
|
||||
}
|
||||
|
||||
public void setListener(ClientInfoItemListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser && (listener != null)) {
|
||||
Volume volume = new Volume(progress, false);
|
||||
clientInfo.setVolume(volume);
|
||||
listener.onVolumeChanged(this, volume);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,8 +38,9 @@ import java.io.OutputStream;
|
|||
|
||||
import de.badaix.snapcast.control.ClientInfo;
|
||||
import de.badaix.snapcast.control.ServerInfo;
|
||||
import de.badaix.snapcast.control.Volume;
|
||||
|
||||
public class MainActivity extends ActionBarActivity implements View.OnClickListener, TcpClient.TcpClientListener {
|
||||
public class MainActivity extends ActionBarActivity implements View.OnClickListener, TcpClient.TcpClientListener, ClientInfoItem.ClientInfoItemListener {
|
||||
|
||||
private static final String TAG = "Main";
|
||||
|
||||
|
@ -101,7 +102,7 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
}
|
||||
|
||||
serverInfo = new ServerInfo();
|
||||
clientInfoAdapter = new ClientInfoAdapter(this, 0);
|
||||
clientInfoAdapter = new ClientInfoAdapter(this, this);
|
||||
lvClient.setAdapter(clientInfoAdapter);
|
||||
|
||||
copyAssets();
|
||||
|
@ -113,12 +114,15 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
|
||||
private class ClientInfoAdapter extends ArrayAdapter<ClientInfo> {
|
||||
private Context context;
|
||||
private ClientInfoItem.ClientInfoItemListener listener;
|
||||
|
||||
public ClientInfoAdapter(Context context, int textViewResourceId) {
|
||||
super(context, textViewResourceId);
|
||||
public ClientInfoAdapter(Context context, ClientInfoItem.ClientInfoItemListener listener) {
|
||||
super(context, 0);
|
||||
this.context = context;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ClientInfo clientInfo = getItem(position);
|
||||
|
@ -130,11 +134,32 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
} else {
|
||||
clientInfoItem = new ClientInfoItem(context, clientInfo);
|
||||
}
|
||||
|
||||
clientInfoItem.setListener(listener);
|
||||
return clientInfoItem;
|
||||
}
|
||||
|
||||
public void addClient(ClientInfo clientInfo) {
|
||||
if (clientInfo == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
ClientInfo client = getItem(i);
|
||||
if (client.getMac().equals(clientInfo.getMac())) {
|
||||
insert(clientInfo, i);
|
||||
remove(client);
|
||||
return;
|
||||
}
|
||||
}
|
||||
add(clientInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if ((tcpClient != null) && (tcpClient.isConnected()))
|
||||
tcpClient.stop();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
private void copyAssets() {
|
||||
AssetManager assetManager = getAssets();
|
||||
|
@ -211,9 +236,13 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
Toast.makeText(this, "Scan", Toast.LENGTH_SHORT).show();
|
||||
initializeDiscoveryListener();
|
||||
} else if (view == button) {
|
||||
if ((tcpClient == null) || !tcpClient.isConnected()) {
|
||||
Toast.makeText(this, "Connecting", Toast.LENGTH_SHORT).show();
|
||||
tcpClient = new TcpClient(this);
|
||||
tcpClient.start(host, port + 1);
|
||||
} else {
|
||||
tcpClient.sendMessage("{\"jsonrpc\": \"2.0\", \"method\": \"System.GetStatus\", \"id\": 1}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +365,7 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
JSONObject json = new JSONObject(message);
|
||||
if (json.has("id")) {
|
||||
Log.d(TAG, "ID: " + json.getString("id"));
|
||||
if (json.getJSONObject("result").has("clients")) {
|
||||
if ((json.get("result") instanceof JSONObject) && json.getJSONObject("result").has("clients")) {
|
||||
JSONArray clients = json.getJSONObject("result").getJSONArray("clients");
|
||||
for (int i = 0; i < clients.length(); i++) {
|
||||
final ClientInfo clientInfo = new ClientInfo(clients.getJSONObject(i));
|
||||
|
@ -346,14 +375,14 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
@Override
|
||||
public void run() {
|
||||
if (clientInfo.isConnected())
|
||||
clientInfoAdapter.add(clientInfo);
|
||||
clientInfoAdapter.addClient(clientInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Notification: " + json.getString("method"));
|
||||
if (json.getString("method").equals("Client.OnUpdate")) {
|
||||
if (json.getString("method").equals("Client.OnUpdate") || json.getString("method").equals("Client.OnConnect")) {
|
||||
final ClientInfo clientInfo = new ClientInfo(json.getJSONObject("params").getJSONObject("data"));
|
||||
Log.d(TAG, "ClientInfo: " + clientInfo);
|
||||
Log.d(TAG, "Changed: " + serverInfo.addClient(clientInfo));
|
||||
|
@ -362,7 +391,7 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
@Override
|
||||
public void run() {
|
||||
if (clientInfo.isConnected())
|
||||
clientInfoAdapter.add(clientInfo);
|
||||
clientInfoAdapter.addClient(clientInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -382,5 +411,13 @@ public class MainActivity extends ActionBarActivity implements View.OnClickListe
|
|||
public void onDisconnected(TcpClient tcpClient) {
|
||||
Log.d(TAG, "onDisconnected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVolumeChanged(ClientInfoItem clientInfoItem, Volume volume) {
|
||||
ClientInfo client = clientInfoItem.getClientInfo();
|
||||
tcpClient.sendMessage("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetVolume\", \"params\": {\"client\": \"" + client.getMac() + "\", \"volume\": " + client.getVolume().getPercent() + "}, \"id\": 3}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ public class TcpClient {
|
|||
// class at on asynckTask doInBackground
|
||||
public interface TcpClientListener {
|
||||
void onMessageReceived(TcpClient tcpClient, String message);
|
||||
|
||||
void onConnected(TcpClient tcpClient);
|
||||
|
||||
void onDisconnected(TcpClient tcpClient);
|
||||
}
|
||||
|
||||
|
@ -36,6 +38,7 @@ public class TcpClient {
|
|||
// used to read messages from the server
|
||||
private BufferedReader mBufferIn;
|
||||
private Thread worker = null;
|
||||
private Socket socket = null;
|
||||
|
||||
private String uid;
|
||||
|
||||
|
@ -47,6 +50,12 @@ public class TcpClient {
|
|||
mMessageListener = listener;
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
if (socket == null)
|
||||
return false;
|
||||
return socket.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the message entered by client to the server
|
||||
*
|
||||
|
@ -90,7 +99,7 @@ public class TcpClient {
|
|||
Log.d(TAG, "Connecting to " + serverAddr.getCanonicalHostName() + ":" + port);
|
||||
|
||||
// create a socket to make the connection with the server
|
||||
Socket socket = new Socket(serverAddr, port);
|
||||
socket = new Socket(serverAddr, port);
|
||||
|
||||
try {
|
||||
|
||||
|
|
33
android/Snapcast/src/main/res/drawable/big_card.xml
Normal file
33
android/Snapcast/src/main/res/drawable/big_card.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle" >
|
||||
<solid android:color="@color/second_grey" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="10dp"
|
||||
android:left="10dp"
|
||||
android:right="10dp"
|
||||
android:top="10dp">
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="3dp" />
|
||||
|
||||
<solid android:color="@color/card_shadow" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="12dp"
|
||||
android:left="10dp"
|
||||
android:right="10dp"
|
||||
android:top="10dp">
|
||||
<shape android:shape="rectangle" >
|
||||
<corners android:radius="3dp" />
|
||||
|
||||
<solid android:color="@color/card_white" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
|
||||
</layer-list>
|
|
@ -2,11 +2,12 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingRight="?android:attr/scrollbarSize"
|
||||
android:orientation="vertical">
|
||||
<!-- android:background="@drawable/big_card"-->
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -28,18 +29,7 @@
|
|||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:text="Title"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/title"
|
||||
android:layout_below="@id/title"
|
||||
android:maxLines="4"
|
||||
android:text="Summary"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<SeekBar
|
||||
android:layout_width="match_parent"
|
||||
|
|
6
android/Snapcast/src/main/res/values/colors.xml
Normal file
6
android/Snapcast/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="second_grey">#ff999999</color>
|
||||
<color name="card_white">#ffffffff</color>
|
||||
<color name="card_shadow">#8c666666</color>
|
||||
</resources>
|
|
@ -49,8 +49,8 @@ doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetMute\", \"params\": {\
|
|||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetMute\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"mute\": false}, \"id\": 9}\r\n")
|
||||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetMute\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"mute\": true}, \"id\": 9}\r\n")
|
||||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetMute\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"mute\": false}, \"id\": 9}\r\n")
|
||||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetLatency\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"latency\": 10}, \"id\": 7}\r\n")
|
||||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetName\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"name\": \"living room\"}, \"id\": 8}\r\n")
|
||||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetLatency\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"latency\": 0}, \"id\": 7}\r\n")
|
||||
doRequest("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetName\", \"params\": {\"client\": \"80:1f:02:ed:fd:e0\", \"name\": \"T400\"}, \"id\": 8}\r\n")
|
||||
#invalid json
|
||||
doRequest("some message to test invalid requests\r\n")
|
||||
#missing id
|
||||
|
|
Loading…
Add table
Reference in a new issue