多くの Android デバイスを OSC クライアントとして、コンピューターを OSC サーバーとして使用するプロジェクトにOSCP5 を使用しました。放送サンプルから始めることをお勧めします。サーバーがポート 32000 の任意の IP からの「/server/connect」メッセージをリッスンしていることに注意してください。この方法では、Android デバイスの IP をサーバーにハードコードする必要はありませんが、この段階では、まだ IP をハードコードすることになります。サーバーをクライアント Android デバイスに接続します。
この制限を回避する方法は、「/server/connect」メッセージをリッスンする全員 (「255.255.255.255」) に送信することでした。サーバーがIPに接続すると、クライアントにメッセージが返されます。その後、クライアントはそのメッセージから IP アドレスを取得するため、後続のすべてのメッセージを「255.255.255.255」に送信する必要はありません。
Android デバイスでは Android SDK を使用し、コンピューターでは Processing を使用したため、構文が異なって見えますが、OSC の部分は理解できるはずです。ここに簡略化されたバージョンがあります:
package com.hirschandmann.updclient.network;
import netP5.NetAddress;
import oscP5.OscArgument;
import oscP5.OscEventListener;
import oscP5.OscMessage;
import oscP5.OscP5;
import oscP5.OscStatus;
import android.util.Log;
public class NetMan implements OscEventListener {
public static final int PORT_IN = 12000;
public static final int PORT_OUT = 32000;
public static NetAddress SERVER;
public static NetAddress EVERYTHING = new NetAddress("255.255.255.255",PORT_OUT);
private static final String TAG = "NetMan";
private OscP5 osc;
public NetMan(){
osc = new OscP5(this, PORT_IN);
}
public void oscEvent(OscMessage m) {
String pattern = m.addrPattern();
if(SERVER == null) {
SERVER = new NetAddress(m.address().replace("/", ""), PORT_OUT);
System.out.println(SERVER);
}
}
public void connect(){
Log.d("NetMan","connect");
new ConnectTask().execute();
}
public void disconnect(){
new DisconnectTask().execute();
}
@Override
public void oscStatus(OscStatus status) {
System.out.println(status);
}
}
および ConnectTask:
package com.hirschandmann.udpclient.network;
import netP5.NetAddress;
import oscP5.OscMessage;
import oscP5.OscP5;
import android.os.AsyncTask;
public class ConnectTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
System.out.println("sending connect message: " + NetMan.PORT_OUT);
OscMessage m = new OscMessage("/server/connect",new Object[0]);
try{
OscP5.flush(m,NetMan.SERVER != null ? NetMan.SERVER : NetMan.EVERYTHING);
}catch(NullPointerException e) {
System.err.println(e.getMessage());
}
if(NetMan.SERVER != null) System.out.println("NetMan.SERVER: " + NetMan.SERVER);
return null;
}
}
そのため、コンピューターでブロードキャスト サンプルを試してみてください。
import netP5.*;
import apwidgets.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
PWidgetContainer widgetContainer;
PEditText textField;
PButton button1;
PImage fondo;
boolean ValidIP = false;
String ipAddress = "255.255.255.255";
void setup() {
size(480,800);
smooth();
fondo = loadImage("fondoAnd.jpg");
widgetContainer = new PWidgetContainer(this);
textField = new PEditText(10,40,380,120);
button1 = new PButton(10,190,200,100,"Conectar");
widgetContainer.addWidget(textField);
widgetContainer.addWidget(button1);
oscP5 = new OscP5(this,12000);
myRemoteLocation = new NetAddress(ipAddress,12000);
}
void draw() {
if (ValidIP == true){
widgetContainer.hide();
myRemoteLocation = new NetAddress(ipAddress,12000);
background(fondo);
}
else if (ValidIP == false){
background(0);
textSize(20);
text("Ingrese un IP válido",10,30);
widgetContainer.show();
}
}
void mousePressed(){
OscMessage myMessage = new OscMessage("/server/connect");
myMessage.add(8);
oscP5.send(myMessage, myRemoteLocation);
println("enviomensaje"); //I print this in the console to know if it sends a message
}
void onClickWidget(PWidget widget){
if(widget == button1){
ipAddress = textField.getText();
myRemoteLocation = new NetAddress(ipAddress,12000);
ValidIP = true;
}
}
void oscEvent(OscMessage m) {
String pattern = m.addrPattern();
if(ipAddress.equals("255.255.255.255")) {
ipAddress = m.address().replace("/", "");
System.out.println("server is at: " + ipAddress);
}
}
上記のコードはテストされていませんが、役立つはずです。
UDP モードで OSC を使用したことに注意してください。TCPモードもあります。UDP を使用すると、複数の IP にブロードキャストできますが、メッセージが届く保証はなく、各メッセージは最大 64K のデータに制限されます。UDP パケットには確認がないため、TCP よりわずかに高速です。TCP を使用すると、すべてのパケットが相手側に到達することが保証されますが、速度が低下し、ブロードキャスト機能が不足します。また、64K 以上のデータを送信できます。私のアプリケーションでは、9MP と 12MP の画像を送信する必要があったため、UDP と TCP の両方を使用しました。
- サーバーのアドレスを取得し、最小限のデータで高速メッセージを送信する UDP
- ファイルを転送する TCP: tcp ソケットを開いてデータを送信し、転送の完了時に閉じました。
私が遭遇したもう 1 つの問題は、Android の Wi-Fi の速度でした。Wi-Fi は、Android デバイスとコンピューターでは異なる方法で処理されます。OS は可能な限りバッテリーを節約しようとしますが、これは、デバイスのアクティビティがほとんどない場合、Wifi が低遅延モードになることも意味します。バッテリーは節約されますが、接続が非常に遅くなります。 OSC を介した高速応答 これは問題です。Wi-Fiをロックして電源を常にオンにする以外に、問題の適切な解決策を見つけられませんでした.Wifiの応答性のためにバッテリー寿命を犠牲にしています. この問題の解決策を知りたいです。提案があれば共有してください。
HTH