我正在尝试编写一个非常基本的Android应用程序,它可以连接到OSC服务器并侦听来自该服务器的消息。
到目前为止,我已经基于OSCP5 library和broadcast client example创建了一个简单的应用程序,所以我尝试了以下内容:
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编程的新手,并试图利用我以前在处理过程中使用过的东西,这可能不是Android上的最佳选择。
发布于 2013-06-05 23:37:10
我在StrictMode上做了更多的阅读,发现我的简单应用程序在同一线程中发送/接收网络消息,这是不推荐的。网络应该在单独的线程中处理,因此一个简单的解决方案是使用AsyncTask:
public void connect(){
new AsyncTask<Void, Void, String>(){
@Override
protected String doInBackground(Void... params) {
System.out.println("sending connect message: " + PORT_OUT);
OscMessage m = new OscMessage("/server/connect",new Object[0]);
OscP5.flush(m,new NetAddress("255.255.255.255",PORT_OUT));
return "doing in background";
}
@Override
protected void onPostExecute(String result) {
System.out.println("done in background");
}
}.execute();
}这可以写得更好,子类化任务,但它说明了这一点。
https://stackoverflow.com/questions/16895739
复制相似问题