当前位置: 首页 > 知识库问答 >
问题:

如何从Android连接到OSC服务器?

农飞尘
2023-03-14

我正在尝试编写一个非常基本的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编程还不熟悉,试图利用我以前在处理中使用过的东西,这可能不是Android上的最佳选择。

共有1个答案

孟沛
2023-03-14

我对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();
    }

这可以写得更好,子类化任务,但它说明了这一点。

 类似资料:
  • 日志: 我被困在这里,真的不知道问题是什么。有帮手吗?

  • 我想连接到树莓Pi节点。我从网络外部设置的js服务器。 我的路由器声称端口是开放的。我尝试在127.0.0.0、0.0.0.0和我的公共IP地址运行服务器。 我曾尝试使用ngrok打开端口8080,服务器在其中托管一个简单的网页,但尝试访问myIP:8080不起作用。 有人能帮我吗?

  • 我可以在Android emulator中做些什么来将其连接到我位于或? 我已经尝试过了,但是模拟器仍然像谷歌搜索一样接受我的请求localhost或者更糟的是,它说在我的网络服务器正常运行时没有找到这个页面。

  • 我无法使用某些连接字符串从C#.NET代码连接到远程PostgreSQL服务器。(我的连接字符串包含基本信息,如主机地址,端口,用户名,密码,数据库名)。 我的连接字符串: 注意:我使用的是.NET程序集 我得到的错误是:

  • (**)我创建了一个 ASP.NET Web 服务器,托管 SignalR 中心。我遵循了本教程。它有效。然后我创建了一个Xamarin.Android客户端(*)。问题是我无法连接到服务器。我想,由于我的主机地址中的“本地主机”,我无法连接。例外是相当大的。 如果我的怀疑是正确的,我该如何解决?如何使本地主机看起来像普通服务器? (*) -我也试过Xamarin。一般形式。 (**) - 请看问

  • 我使用Sabre DAV在PHP中实现了一个webdav目录,用于我的网站(Application Server Webinterface)。 对于这个网站,我现在使用C#编写了一个TCP套接字,它运行在另一个服务器上(实际上它在同一个数据中心,但从理论上讲,它在另一个半球上)。 我想连接我的网络Dav到我的套接字的FTP服务器,这意味着文件监听,下载,上传。用户只能连接到一个服务。想象一下,我的