mirror of
https://github.com/badaix/snapcast.git
synced 2025-06-02 19:01:47 +02:00
added RemoteControl class
This commit is contained in:
parent
02db46f987
commit
94fe037f52
7 changed files with 245 additions and 97 deletions
|
@ -29,10 +29,6 @@ import com.google.android.gms.appindexing.Action;
|
|||
import com.google.android.gms.appindexing.AppIndex;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -40,9 +36,10 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
|
||||
import de.badaix.snapcast.control.ClientInfo;
|
||||
import de.badaix.snapcast.control.RemoteControl;
|
||||
import de.badaix.snapcast.control.ServerInfo;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener, TcpClient.TcpClientListener, ClientInfoItem.ClientInfoItemListener {
|
||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ClientInfoItem.ClientInfoItemListener, RemoteControl.RemoteControlListener {
|
||||
|
||||
private static final String TAG = "Main";
|
||||
|
||||
|
@ -56,9 +53,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
private NsdManager mNsdManager = null;
|
||||
private String host = "";
|
||||
private int port = 1704;
|
||||
private TcpClient tcpClient;
|
||||
private RemoteControl remoteControl = null;
|
||||
private ClientInfoAdapter clientInfoAdapter;
|
||||
private ServerInfo serverInfo;
|
||||
|
||||
/**
|
||||
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
|
@ -98,8 +94,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
tvInfo.setText("Sample rate: " + rate + ", buffer size: " + size);
|
||||
}
|
||||
|
||||
serverInfo = new ServerInfo();
|
||||
clientInfoAdapter = new ClientInfoAdapter(this, serverInfo, this);
|
||||
clientInfoAdapter = new ClientInfoAdapter(this, this);
|
||||
lvClient.setAdapter(clientInfoAdapter);
|
||||
getSupportActionBar().setSubtitle("Host: no Snapserver found");
|
||||
|
||||
|
@ -144,6 +139,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
editor.apply();
|
||||
clientInfoAdapter.setHideOffline(item.isChecked());
|
||||
return true;
|
||||
} else if (id == R.id.action_refresh) {
|
||||
if ((remoteControl != null) && remoteControl.isConnected())
|
||||
remoteControl.getServerStatus();
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
@ -221,26 +219,21 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
} else if (view == buttonStop) {
|
||||
stop();
|
||||
} else if (view == button) {
|
||||
startTcpClient();
|
||||
// startTcpClient();
|
||||
}
|
||||
}
|
||||
|
||||
private void startTcpClient() {
|
||||
if ((tcpClient == null) || !tcpClient.isConnected()) {
|
||||
if (tcpClient != null)
|
||||
tcpClient.stop();
|
||||
// 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}");
|
||||
}
|
||||
private void startRemoteControl() {
|
||||
if (remoteControl == null)
|
||||
remoteControl = new RemoteControl(this);
|
||||
if (!host.isEmpty())
|
||||
remoteControl.connect(host, port + 1);
|
||||
}
|
||||
|
||||
private void stopTcpClient() {
|
||||
if ((tcpClient != null) && (tcpClient.isConnected()))
|
||||
tcpClient.stop();
|
||||
tcpClient = null;
|
||||
private void stopRemoteControl() {
|
||||
if ((remoteControl != null) && (remoteControl.isConnected()))
|
||||
remoteControl.disconnect();
|
||||
remoteControl = null;
|
||||
}
|
||||
|
||||
public void initializeDiscoveryListener() {
|
||||
|
@ -281,7 +274,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
host = nsdServiceInfo.getHost().getCanonicalHostName();
|
||||
port = nsdServiceInfo.getPort();
|
||||
setStatus(host + ":" + port);
|
||||
startTcpClient();
|
||||
startRemoteControl();
|
||||
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
|
||||
}
|
||||
});
|
||||
|
@ -319,7 +312,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
startTcpClient();
|
||||
startRemoteControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -343,7 +336,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
stopTcpClient();
|
||||
stopRemoteControl();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -367,58 +360,16 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
client.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(TcpClient tcpClient, String message) {
|
||||
Log.d(TAG, "Msg received: " + message);
|
||||
try {
|
||||
boolean needsUpdate = false;
|
||||
JSONObject json = new JSONObject(message);
|
||||
if (json.has("id")) {
|
||||
Log.d(TAG, "ID: " + json.getString("id"));
|
||||
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));
|
||||
needsUpdate = serverInfo.addClient(clientInfo) || needsUpdate;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Notification: " + json.getString("method"));
|
||||
if (json.getString("method").equals("Client.OnUpdate") ||
|
||||
json.getString("method").equals("Client.OnConnect") ||
|
||||
json.getString("method").equals("Client.OnDisconnect")) {
|
||||
final ClientInfo clientInfo = new ClientInfo(json.getJSONObject("params").getJSONObject("data"));
|
||||
needsUpdate = serverInfo.addClient(clientInfo);
|
||||
}
|
||||
}
|
||||
if (needsUpdate)
|
||||
clientInfoAdapter.update();
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(TcpClient tcpClient) {
|
||||
Log.d(TAG, "onConnected");
|
||||
tcpClient.sendMessage("{\"jsonrpc\": \"2.0\", \"method\": \"System.GetStatus\", \"id\": 1}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(TcpClient tcpClient) {
|
||||
Log.d(TAG, "onDisconnected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVolumeChanged(ClientInfoItem clientInfoItem, int percent) {
|
||||
ClientInfo client = clientInfoItem.getClientInfo();
|
||||
tcpClient.sendMessage("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetVolume\", \"params\": {\"client\": \"" + client.getMac() + "\", \"volume\": " + percent + "}, \"id\": 3}");
|
||||
remoteControl.setVolume(client, percent);
|
||||
}
|
||||
|
||||
public void onMute(ClientInfoItem clientInfoItem, boolean mute) {
|
||||
ClientInfo client = clientInfoItem.getClientInfo();
|
||||
tcpClient.sendMessage("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetMute\", \"params\": {\"client\": \"" + client.getMac() + "\", \"mute\": " + mute + "}, \"id\": 3}");
|
||||
remoteControl.setMute(client, mute);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -437,22 +388,53 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
if (requestCode == 1) {
|
||||
ClientInfo clientInfo = data.getParcelableExtra("clientInfo");
|
||||
tcpClient.sendMessage("{\"jsonrpc\": \"2.0\", \"method\": \"Client.SetName\", \"params\": {\"client\": \"" + clientInfo.getMac() + "\", \"name\": \"" + clientInfo.getName() + "\"}, \"id\": 3}");
|
||||
if (serverInfo.addClient(clientInfo))
|
||||
clientInfoAdapter.update();
|
||||
remoteControl.setName(clientInfo, clientInfo.getName());
|
||||
clientInfoAdapter.updateClient(clientInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(RemoteControl remoteControl) {
|
||||
remoteControl.getServerStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(RemoteControl remoteControl) {
|
||||
Log.d(TAG, "onDisconnected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientConnected(RemoteControl remoteControl, ClientInfo clientInfo) {
|
||||
Log.d(TAG, "onClientConnected");
|
||||
clientInfoAdapter.updateClient(clientInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientDisconnected(RemoteControl remoteControl, ClientInfo clientInfo) {
|
||||
Log.d(TAG, "onClientDisconnected");
|
||||
clientInfoAdapter.updateClient(clientInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientUpdated(RemoteControl remoteControl, ClientInfo clientInfo) {
|
||||
Log.d(TAG, "onClientUpdated");
|
||||
clientInfoAdapter.updateClient(clientInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerInfo(RemoteControl remoteControl, ServerInfo serverInfo) {
|
||||
clientInfoAdapter.update(serverInfo);
|
||||
}
|
||||
|
||||
private class ClientInfoAdapter extends ArrayAdapter<ClientInfo> {
|
||||
private Context context;
|
||||
private ClientInfoItem.ClientInfoItemListener listener;
|
||||
private boolean hideOffline = false;
|
||||
private ServerInfo serverInfo;
|
||||
private ServerInfo serverInfo = new ServerInfo();
|
||||
|
||||
public ClientInfoAdapter(Context context, ServerInfo serverInfo, ClientInfoItem.ClientInfoItemListener listener) {
|
||||
public ClientInfoAdapter(Context context, ClientInfoItem.ClientInfoItemListener listener) {
|
||||
super(context, 0);
|
||||
this.context = context;
|
||||
this.serverInfo = serverInfo;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
@ -472,27 +454,20 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
return clientInfoItem;
|
||||
}
|
||||
|
||||
/* public void addClient(ClientInfo clientInfo) {
|
||||
if (clientInfo == null)
|
||||
return;
|
||||
public void updateClient(final ClientInfo clientInfo) {
|
||||
if (serverInfo.addClient(clientInfo))
|
||||
update(null);
|
||||
}
|
||||
|
||||
public void update(final ServerInfo serverInfo) {
|
||||
if (serverInfo != null)
|
||||
ClientInfoAdapter.this.serverInfo = serverInfo;
|
||||
|
||||
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);
|
||||
}
|
||||
*/
|
||||
public void update() {
|
||||
MainActivity.this.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clear();
|
||||
for (ClientInfo clientInfo : serverInfo.getClientInfos()) {
|
||||
for (ClientInfo clientInfo : ClientInfoAdapter.this.serverInfo.getClientInfos()) {
|
||||
if ((clientInfo != null) && (!hideOffline || clientInfo.isConnected()))
|
||||
add(clientInfo);
|
||||
}
|
||||
|
@ -509,7 +484,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
if (this.hideOffline == hideOffline)
|
||||
return;
|
||||
this.hideOffline = hideOffline;
|
||||
update();
|
||||
update(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,8 @@ public class TcpClient {
|
|||
mBufferIn = new BufferedReader(new InputStreamReader(
|
||||
socket.getInputStream()));
|
||||
|
||||
mMessageListener.onConnected(TcpClient.this);
|
||||
if (mMessageListener != null)
|
||||
mMessageListener.onConnected(TcpClient.this);
|
||||
|
||||
// in this while the client listens for the messages sent by the
|
||||
// server
|
||||
|
@ -137,7 +138,8 @@ public class TcpClient {
|
|||
// after it is closed, which means a new socket instance has to
|
||||
// be created.
|
||||
socket.close();
|
||||
mMessageListener.onDisconnected(TcpClient.this);
|
||||
if (mMessageListener != null)
|
||||
mMessageListener.onDisconnected(TcpClient.this);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
package de.badaix.snapcast.control;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.badaix.snapcast.ClientInfoItem;
|
||||
import de.badaix.snapcast.TcpClient;
|
||||
|
||||
/**
|
||||
* Created by johannes on 13.01.16.
|
||||
*/
|
||||
public class RemoteControl implements TcpClient.TcpClientListener {
|
||||
|
||||
private static final String TAG = "RC";
|
||||
|
||||
private TcpClient tcpClient;
|
||||
private long msgId;
|
||||
private RemoteControlListener listener;
|
||||
private ServerInfo serverInfo;
|
||||
|
||||
public interface RemoteControlListener {
|
||||
void onConnected(RemoteControl remoteControl);
|
||||
void onDisconnected(RemoteControl remoteControl);
|
||||
|
||||
void onClientConnected(RemoteControl remoteControl, ClientInfo clientInfo);
|
||||
void onClientDisconnected(RemoteControl remoteControl, ClientInfo clientInfo);
|
||||
void onClientUpdated(RemoteControl remoteControl, ClientInfo clientInfo);
|
||||
|
||||
void onServerInfo(RemoteControl remoteControl, ServerInfo serverInfo);
|
||||
}
|
||||
|
||||
|
||||
public RemoteControl(RemoteControlListener listener) {
|
||||
this.listener = listener;
|
||||
serverInfo = new ServerInfo();
|
||||
msgId = 0;
|
||||
}
|
||||
|
||||
public void connect(final String host, final int port) {
|
||||
if ((tcpClient != null) && tcpClient.isConnected())
|
||||
return;
|
||||
|
||||
tcpClient = new TcpClient(this);
|
||||
tcpClient.start(host, port);
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if ((tcpClient != null) && (tcpClient.isConnected()))
|
||||
tcpClient.stop();
|
||||
tcpClient = null;
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return ((tcpClient != null) && tcpClient.isConnected());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(TcpClient tcpClient, String message) {
|
||||
Log.d(TAG, "Msg received: " + message);
|
||||
try {
|
||||
JSONObject json = new JSONObject(message);
|
||||
if (json.has("id")) {
|
||||
Log.d(TAG, "ID: " + json.getString("id"));
|
||||
if ((json.get("result") instanceof JSONObject) && json.getJSONObject("result").has("clients")) {
|
||||
serverInfo.clear();
|
||||
JSONArray clients = json.getJSONObject("result").getJSONArray("clients");
|
||||
for (int i = 0; i < clients.length(); i++) {
|
||||
final ClientInfo clientInfo = new ClientInfo(clients.getJSONObject(i));
|
||||
serverInfo.addClient(clientInfo);
|
||||
}
|
||||
if (listener != null)
|
||||
listener.onServerInfo(this, serverInfo);
|
||||
}
|
||||
} else {
|
||||
String method = json.getString("method");
|
||||
Log.d(TAG, "Notification: " + method);
|
||||
if (method.contains("Client.On")) {
|
||||
final ClientInfo clientInfo = new ClientInfo(json.getJSONObject("params").getJSONObject("data"));
|
||||
// serverInfo.addClient(clientInfo);
|
||||
if (listener != null) {
|
||||
if (method.equals("Client.OnUpdate"))
|
||||
listener.onClientUpdated(this, clientInfo);
|
||||
else if (method.equals("Client.OnConnect"))
|
||||
listener.onClientConnected(this, clientInfo);
|
||||
else if (method.equals("Client.OnDisconnect"))
|
||||
listener.onClientDisconnected(this, clientInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(TcpClient tcpClient) {
|
||||
Log.d(TAG, "onConnected");
|
||||
if (listener != null)
|
||||
listener.onConnected(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(TcpClient tcpClient) {
|
||||
Log.d(TAG, "onDisconnected");
|
||||
if (listener != null)
|
||||
listener.onDisconnected(this);
|
||||
}
|
||||
|
||||
private JSONObject jsonRequest(String method, JSONObject params) {
|
||||
JSONObject request = new JSONObject();
|
||||
try {
|
||||
request.put("jsonrpc", "2.0");
|
||||
request.put("method", method);
|
||||
request.put("id", msgId);
|
||||
if (params != null)
|
||||
request.put("params", params);
|
||||
msgId++;
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
public void getServerStatus() {
|
||||
JSONObject request = jsonRequest("System.GetStatus", null);
|
||||
tcpClient.sendMessage(request.toString());
|
||||
}
|
||||
|
||||
public void setName(ClientInfo clientInfo, String name) {
|
||||
try {
|
||||
JSONObject request = jsonRequest("Client.SetName", new JSONObject("{\"client\": \"" + clientInfo.getMac() + "\", \"name\": " + name + "}"));
|
||||
tcpClient.sendMessage(request.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVolume(ClientInfo clientInfo, int percent) {
|
||||
try {
|
||||
JSONObject request = jsonRequest("Client.SetVolume", new JSONObject("{\"client\": \"" + clientInfo.getMac() + "\", \"volume\": " + percent + "}"));
|
||||
tcpClient.sendMessage(request.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMute(ClientInfo clientInfo, boolean mute) {
|
||||
try {
|
||||
JSONObject request = jsonRequest("Client.SetMute", new JSONObject("{\"client\": \"" + clientInfo.getMac() + "\", \"mute\": " + mute + "}"));
|
||||
tcpClient.sendMessage(request.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,10 @@ public class ServerInfo {
|
|||
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
clientInfos.clear();
|
||||
}
|
||||
|
||||
public boolean addClient(ClientInfo client) {
|
||||
if (client == null)
|
||||
return false;
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
android:orderInCategory="100"
|
||||
android:title="@string/action_scan"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_refresh"
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/action_refresh"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_hide_offline"
|
||||
android:orderInCategory="100"
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
<string name="client_last_seen">Last seen</string>
|
||||
<string name="client_latency">Latency</string>
|
||||
<string name="title_activity_client_settings">Client settings</string>
|
||||
<string name="action_hide_offline">Hide offline</string>
|
||||
<string name="action_hide_offline">Hide offline clients</string>
|
||||
<string name="online">online</string>
|
||||
<string name="action_refresh">refresh</string>
|
||||
</resources>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue