我正在尝试编写一个非常基本的 Android 应用程序,它连接到 OSC 服务器并收听来自它的消息。
到目前为止,我已经制作了一个基于OSCP5 库和广播客户端示例的简单应用程序,所以这是我尝试过的:
package com.hirschandmann.colour.client;
import netP5.NetAddress;
import netP5.NetInfo;
import oscP5.OscArgument;
import oscP5.OscMessage;
import oscP5.OscP5;
import android.app.Activity;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import com.hirschandmann.colour.client.util.SystemUiHider;
//based on Fullscreen Activity template
public class FlatColour extends Activity implements OnClickListener {
private static final String TAG = "FlatColour";
private static final boolean AUTO_HIDE = true;
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
private static final boolean TOGGLE_ON_CLICK = true;
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
private SystemUiHider mSystemUiHider;
private View contentView;
private static final int PORT_IN = 12000;
private static final int PORT_OUT = 32000;
private NetAddress thisLocation;
private OscP5 osc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flat_colour);
contentView = findViewById(R.id.fullscreen_content);
mSystemUiHider = SystemUiHider.getInstance(this, contentView,HIDER_FLAGS);
mSystemUiHider.setup();
contentView.setOnClickListener(this);
osc = new OscP5(this,PORT_IN);
String ip = getIpAddr();
System.out.println(ip);
thisLocation = new NetAddress(ip,PORT_OUT);
try{
connect();
}catch(Exception e){
e.printStackTrace();
}
//NetInfo.print();
}
public void connect(){
OscMessage m = new OscMessage("/server/connect",new Object[0]);
OscP5.flush(m,thisLocation);
}
public void disconnect(){
OscMessage m = new OscMessage("/server/disconnect",new Object[0]);
OscP5.flush(m,thisLocation);
}
public void oscEvent(OscMessage m) {
String pattern = m.addrPattern();
Log.d(TAG, pattern);
if(pattern.equals("/color")){
// int color = Integer.parseInt(m.get(0).stringValue());
OscArgument a = m.get(0);
String s = a.stringValue();
System.out.println(s);
final int color = Integer.parseInt(s);
//cannot update view from non view thread otherwise
runOnUiThread(new Runnable() {
@Override
public void run() {
contentView.setAlpha(0);
contentView.setBackgroundColor(color);
}
});
// contentView.setBackgroundColor(color);
Log.d(TAG, "color: " + a +" view: " + contentView);
}
if(pattern.equals("/animate")){
int duration = m.get(0).intValue();
int delay = m.get(1).intValue();
contentView.animate().alpha(1).setDuration(duration).setStartDelay(delay);
Log.d(TAG, "duration: " + duration + " delay: " + delay);
}
}
@Override
public void onClick(View view) {
if (TOGGLE_ON_CLICK) {
mSystemUiHider.toggle();
} else {
mSystemUiHider.show();
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
delayedHide(100);
}
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) delayedHide(AUTO_HIDE_DELAY_MILLIS);
return false;
}
};
Handler mHideHandler = new Handler();
Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
mSystemUiHider.hide();
}
};
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
}
这是我得到的堆栈跟踪:
06-03 11:15:42.330: W/System.err(4766): android.os.NetworkOnMainThreadException
06-03 11:15:42.340: W/System.err(4766): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1126)
06-03 11:15:42.340: W/System.err(4766): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:175)
06-03 11:15:42.340: W/System.err(4766): at libcore.io.IoBridge.sendto(IoBridge.java:484)
06-03 11:15:42.340: W/System.err(4766): at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
06-03 11:15:42.340: W/System.err(4766): at java.net.DatagramSocket.send(DatagramSocket.java:304)
06-03 11:15:42.340: W/System.err(4766): at oscP5.OscP5.flush(Unknown Source)
06-03 11:15:42.340: W/System.err(4766): at oscP5.OscP5.flush(Unknown Source)
06-03 11:15:42.340: W/System.err(4766): at com.hirschandmann.colour.client.FlatColour.connect(FlatColour.java:62)
06-03 11:15:42.340: W/System.err(4766): at com.hirschandmann.colour.client.FlatColour.onCreate(FlatColour.java:54)
06-03 11:15:42.340: W/System.err(4766): at android.app.Activity.performCreate(Activity.java:5008)
06-03 11:15:42.340: W/System.err(4766): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
06-03 11:15:42.340: W/System.err(4766): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2034)
06-03 11:15:42.350: W/System.err(4766): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2095)
06-03 11:15:42.350: W/System.err(4766): at android.app.ActivityThread.access$600(ActivityThread.java:137)
06-03 11:15:42.350: W/System.err(4766): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
06-03 11:15:42.350: W/System.err(4766): at android.os.Handler.dispatchMessage(Handler.java:99)
06-03 11:15:42.350: W/System.err(4766): at android.os.Looper.loop(Looper.java:213)
06-03 11:15:42.350: W/System.err(4766): at android.app.ActivityThread.main(ActivityThread.java:4791)
06-03 11:15:42.350: W/System.err(4766): at java.lang.reflect.Method.invokeNative(Native Method)
06-03 11:15:42.350: W/System.err(4766): at java.lang.reflect.Method.invoke(Method.java:511)
06-03 11:15:42.350: W/System.err(4766): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
06-03 11:15:42.350: W/System.err(4766): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
06-03 11:15:42.350: W/System.err(4766): at dalvik.system.NativeStart.main(Native Method)
我不知道该怎么做这个错误。
如何从 Android 手机向任何在特定端口上监听 OSC 的设备发送 OSC 消息?推荐的方法是什么?我是 Android 编程的新手,并试图利用我之前在 Processing 中使用过的东西,这可能不是 Android 上的最佳选择。