小优机器人WIFI+SSDP入网具体实现

Posted canbot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小优机器人WIFI+SSDP入网具体实现相关的知识,希望对你有一定的参考价值。

小优入网实现

1. 小优响应设备查询服务
当小优连接网络时,开启一个SSDP后台服务后,除了向局域网广播通知自己存在,还创建了一个广播监听线程,当收到智能网关发来的设备查询服务广播时,如下:
SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: “ssdp:discover”
MX: 120
ST: ssdp:all
广播监听线程会立刻响应查询服务,发送小优存在广告通知,信息内容跟入网时发的一样,如下:
NOTIFY * HTTP/1.1
Host: 239.255.255.250:1900
NT: urn:schemas-upnp-org:device:CanbotRobot:1
NTS: ssdp:alive
USN:uuid:Upnp-KL-U03S-1_0-04e67647e222::urn:schemas-upnp-org:device:CanbotRobot
Cache-Control: max-age = 1800
通过收到的设备查询服务广播,小优可以获取智能网关的ip地址,为接下来的通信提供目标地址,最后当网络断开时,会停止SSDP后台服务,再次连接网络时再启动。
2. 小优端声控指令转字符串
小优端获取到声音指令后,转化为字符串,对字符串做判断比较,是否符合本地指令,符合的就本地处理,不符合的字符串,就把它发送到智能网关处理。
这里写图片描述
小优端核心代码如下:
LanSend类主要实现ssdp加入多播组、监听发现服务并单播响应信息

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;

import android.content.Context;
import android.util.Log;

public class LanSend {

     /**
      * @param args
      * @throws Exception 
      */

     //广播地址
     private static final String BROADCAST_IP = SSDPUtils.ADDRESS;//广播IP
        private static final int BROADCAST_INT_PORT = SSDPUtils.PORT;   // 不同的port对应不同的socket发送端和接收端

        MulticastSocket broadSocket ;//用于接收广播信息
        public static boolean work=false;//循环监听因子
        InetAddress broadAddress ;//广播地址
        //DatagramSocket数据报Socket
         DatagramSocket sender ;//数据流套接字 相当于码头,用于发送信息
        private Context context;
//      private InetSocketAddress mMulticastGroup;
     public LanSend(Context contex) {
      try {
          this.context=contex;
      //初始化
       broadSocket=new MulticastSocket(BROADCAST_INT_PORT); //多播Socket
//     mMulticastGroup = new InetSocketAddress(SSDPUtils.ADDRESS, SSDPUtils.PORT);
       broadAddress = InetAddress.getByName(BROADCAST_IP);//获取网络多播地址
       sender = new DatagramSocket();
      } catch (Exception e) {
       // TODO: handle exception
       System.out.println("*****lanSend初始化失败*****"+e.toString());
      }
     }

    public void join() { 
      try{
          Log.e("LanSend", "join");
       broadSocket.joinGroup(broadAddress); //把套接字socket加入到组播地址,这样就能接收到组播信息
       new Thread(new GetPacket()).start(); //新建一个线程,用于循环侦听端口信息
      }catch (Exception e) {
       // TODO: handle exception
       System.out.println("*****加入组播失败*****");
      }

     }


     //广播发送查找在线用户
     void sendGetUserMsg() {
            byte[] b=new byte[1024];
            DatagramPacket packet;  //数据包,相当于集装箱,封装信息
            try{
             b = SSDPUtils.buildSSDPSearchString().getBytes();  
             packet = new DatagramPacket(b, b.length, broadAddress, BROADCAST_INT_PORT); //广播信息到指定端口
             sender.send(packet);//单播信息会给目标主机
             System.out.println("*****已发送请求*****");       
            }catch (Exception e) {
       System.out.println("*****查找出错*****");
      }
        }


     //当局域网内的在线机子收到广播信息时响应并向发送广播的ip地址(此处广播自己的存在来响应)主机发送返还信息,达到交换信息的目的
     void returnUserMsg(String mac){
      byte[] b=new byte[1024];
      DatagramPacket packet;
      try {
       b=SSDPUtils.buildSSDPAliveString(mac).getBytes();
       packet = new DatagramPacket(b,b.length,broadAddress, BROADCAST_INT_PORT);
       sender.send(packet);
       System.out.print("发送信息成功!");
      } catch (Exception e) {
       // TODO: handle exception
       System.out.println("*****发送返还信息失败*****"+e);
      }
     }
     //当局域网内的在线机子收到广播信息时响应并向发送广播的ip地址主机发送返还信息,达到交换信息的目的
     void returnUserMsg(String mac,InetAddress inetaddress,int port){
         byte[] b=new byte[1024];
         DatagramPacket packet;
         try {
             b=SSDPUtils.buildSSDPAliveString(mac).getBytes();
             packet = new DatagramPacket(b,b.length,inetaddress, port);
             sender.send(packet);
             System.out.print("发送信息成功!");
         } catch (Exception e) {
             // TODO: handle exception
             System.out.println("*****发送返还信息失败*****"+e);
         }
     }


     //当局域网某机子下线是需要广播发送下线通知
     void offLine(){
      byte[] b=new byte[1024];
      DatagramPacket packet;
      try {
       b=SSDPUtils.buildSSDPByebyeString().getBytes();
       packet = new DatagramPacket(b,b.length,broadAddress, BROADCAST_INT_PORT);
       sender.send(packet);
       System.out.println("*****已离线*****");
      } catch (Exception e) {
       // TODO: handle exception
       System.out.println("*****离线异常*****");
      }
     }

     class GetPacket implements Runnable {  //新建的线程,用于侦听,packet数据包
      public void run() {
          DatagramPacket inPacket;
          work=true;
       String[] message;

       while(work){
        try {
             Log.e("LanSend", "GetPacket while");
             inPacket=new DatagramPacket(new byte[1024], 1024);
              broadSocket.receive(inPacket);     //接收广播信息并将信息封装到inPacket中
//            inPacket.getData()
//             message=new String(inPacket.getData(),0,inPacket.getLength()).split("@");  //获取信息,并切割头部,判断是何种信息(find--上线,retn--回答,offl--下线)
           String data=new String(inPacket.getData()).trim();

           if (data!=null) {
               String socketAddress=inPacket.getSocketAddress().toString();
               String[] datas=data.split(SSDPUtils.NEWLINE);
               for (int i = 0; i < datas.length; i++) {
                   Log.e("LanSend", "datas["+i+"] =  "+datas[i]);
                   if (datas[i].trim().equalsIgnoreCase("ST: ssdp:all")) {
                        Log.e("ALIVE", "response");
                    String mac=SSDPUtils.getUserId(context);
                    InetAddress sourceip=inPacket.getAddress();
                    int port=inPacket.getPort();
                    returnUserMsg(mac,sourceip,port);
                    break;
                }

            }
               Log.e("LanSend", "收到的数据包的 data :"+data+"    数据包的socketAddress:"+socketAddress);
               System.out.println("收到的数据包的 data :"+data+"    数据包的socketAddress:"+socketAddress);
        }

          } catch (Exception e) {
         // TODO: handle exception
         System.out.println("线程出错 "+e);
        }
       }
      }
     }
    }

SSDPUtils 为SSDP工具类,主要实现小优ssdp信息的生成

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;

/**
 * Created by florent.noel on 6/14/13.
 */
public class SSDPUtils {
    private static String TAG = SSDPUtils.class.getName();

    public static final String ADDRESS = "239.255.255.250";

    public static final int PORT = 1900;

    public static final int MAX_REPLY_TIME = 5;
    public static final int MSG_TIMEOUT = MAX_REPLY_TIME * 1000 + 1000;

    public static final String STRING_MSEARCH = "M-SEARCH * HTTP/1.1";
    public static final String NOTIFY_MSEARCH = "NOTIFY * HTTP/1.1";

//    public static final String STRING_RootDevice = "ST: upnp:rootdevice";
    public static final String STRING_AllDevice = "ST: ssdp:all";

    public static final String NEWLINE = "\\r\\n";
    public static final String MAN = "Man:\\"ssdp:discover\\"";

    public static String LOCATION_TEXT = "LOCATION: http://";

    public static String buildSSDPSearchString(){
        StringBuilder content = new StringBuilder();

        content.append(STRING_MSEARCH).append(NEWLINE);
        content.append("Host: " + ADDRESS + ":" + PORT).append(NEWLINE);
        content.append(MAN).append(NEWLINE);
        content.append("MX: " + MAX_REPLY_TIME).append(NEWLINE);
        content.append(STRING_AllDevice).append(NEWLINE);
        content.append(NEWLINE);

        Log.e(TAG, content.toString());

        return content.toString();
    }

    /** 
    * 方法描述:获取本地userId方法
    * @param   String app_name
    * @return 
    * @see RobotUtil
    */
    public static String getUserId(Context context) {
        WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (!wifi.isWifiEnabled()) {
            wifi.setWifiEnabled(true);
        }
        WifiInfo info = wifi.getConnectionInfo();
        String mac = info.getMacAddress();
        if(mac==null)
        {
            if (!wifi.isWifiEnabled()) {
                wifi.setWifiEnabled(true);
            }
            long starttime = System.currentTimeMillis();
            while(true&&System.currentTimeMillis()-starttime<5000){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                     info = wifi.getConnectionInfo();
                     mac = info.getMacAddress();
                     if(mac!=null)
                     {
                         break;

                     }
            }
            if (mac==null) {
                Log.e("getUserId","getUserId失败 ");
                return null;
            }

        }
        Log.e("getUserId","getUserId "+mac);
        String str=mac.replace(":", "");
//      StringBuffer a = new StringBuffer(mac);
//      a.deleteCharAt(2).deleteCharAt(4).deleteCharAt(6).deleteCharAt(8)
//              .deleteCharAt(10);
//      mac = a.toString();
        return str;
    }

    /**
     * NOTIFY * HTTP/1.1
        ST: urn: schemas-upnp-org:device: 设备名称:1
        HOST: 239.255.255.250:1900
        EXT:
        CACHE-CONTROL: max-age=1800
        LOCATION: http://127.0.0.1:8008/ssdp/device-desc.xml
        CONFIGID.UPNP.ORG: 7339
        BOOTID.UPNP.ORG: 7339
        USN: uuid: Upnp-设备系列号-设备识别号::urn:schemas-upnp-org:device:设备名称
     */


    public static String buildSSDPAliveString(String mac){
        StringBuilder content = new StringBuilder();

//      content.append("HTTP/1.1 200 OK").append(NEWLINE);
        content.append(NOTIFY_MSEARCH).append(NEWLINE);
        content.append("ST: urn:schemas-upnp-org:device:设备名称:1").append(NEWLINE);
        content.append("Host: " + ADDRESS + ":" + PORT).append(NEWLINE);
        content.append("Cache-Control: max-age=1800").append(NEWLINE);
        content.append("CONFIGID.UPNP.ORG: 7339").append(NEWLINE);
        content.append("BOOTID.UPNP.ORG: 7339").append(NEWLINE);
        content.append("USN: uuid:Upnp-设备系列号-"+mac+"::urn:schemas-upnp-org:device:设备名称").append(NEWLINE);
        content.append(NEWLINE);

    /**
     *  NOTIFY * HTTP/1.1
        ST: urn: schemas-upnp-org:device: 设备名称:1
        HOST: 239.255.255.250:1900
        EXT:
        CACHE-CONTROL: max-age=1800
        LOCATION: http://127.0.0.1:8008/ssdp/device-desc.xml
        CONFIGID.UPNP.ORG: 7339
        BOOTID.UPNP.ORG: 7339
        USN: uuid: Upnp-设备系列号-设备识别号::urn:schemas-upnp-org:device:设备名称
     */

        Log.e(TAG, content.toString());

        return content.toString();
    }

    public static String buildSSDPByebyeString(){
        StringBuilder content = new StringBuilder();

        content.append(NOTIFY_MSEARCH).append(NEWLINE);
        content.append("Host: " + ADDRESS + ":" + PORT).append(NEWLINE);
        content.append("NT: someunique:idscheme3").append(NEWLINE);
        content.append("NTS: ssdp:byebye").append(NEWLINE);
        content.append("USN: someunique:idscheme3").append(NEWLINE);
        content.append(NEWLINE);

        Log.e(TAG, content.toString());

        return content.toString();
    }

    public static String parseIP(String msearchAnswer){
        String ip = "0.0.0.0";

        //find the index of "LOCATION: http://"
        int loactionLinePos = msearchAnswer.indexOf(LOCATION_TEXT);

        if(loactionLinePos != -1){
            //position the index right after "LOCATION: http://"
            loactionLinePos += LOCATION_TEXT.length();

            //find the next semi-colon (would be the one that separate IP from PORT nr)
            int locColon = msearchAnswer.indexOf(":", loactionLinePos);
            //grab IP
            ip = msearchAnswer.substring(loactionLinePos, locColon);
        }
        return ip;
    }
}

HuaweiSmartGateway 类主要实现ServerSocket,并对声控结果指令、智能网关指令信息的处理


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import org.json.JSONException;
import org.json.JSONObject;

import android.R.integer;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import com.unisrobot.rsk.MainApplication;
import com.unisrobot.rsk.R;
import com.unisrobot.rsk.preference.ConstUtils;
import com.unisrobot.rsk.util.Logger;

public class HuaweiSmartGateway {

     //广播地址
     private static final String TAG = "HuaweiSmartGateway";
        public static final String ACTION_HEALTH_MANAGEMENT_DATA="识别string";
        public static final String ACTION_SMARTHOME_CMD="识别string2";
        private static final int BROADCAST_INT_PORT = SSDPUtils.PORT;   // 不同的port对应不同的socket发送端和接收端
        public static String responseMsg;//成功返回智能家居的执行成功结果,小优播放的文本语音(测试用)
        public static String speakresponseMsg=null;//成功返回智能家居的执行成功结果,保存用,小优播放的文本语音(测试用)
        private Context mContext;
        private LanSend lSend;
        private TextToSpeech mTextToSpeech;
        private MyReceiver mReceiverResult;

        private Dialog dialog;
        Handler mHander = new Handler() {

            public void handleMessage(Message msg) {
                switch (msg.what) {
                case 4:
                    Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 5:
//                  Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
                    String str=(String)msg.obj;
                    if (str!=null&&!str.isEmpty()) {
                        createDialog((String)msg.obj);
                    }

                    break;
                case 6:
//                  Toast.makeText(mContext, (String)msg.obj, Toast.LENGTH_SHORT).show();
                    String str2=(String)msg.obj;
                    if (str2!=null&&!str2.isEmpty()) {
                        createDialog((String)msg.obj);
                    }
                    int rs=msg.arg1;
                    if (rs!=0) {
                        playhuaweiVoice2(mContext, rs);
                    }

                    break;


                }

            }
        };


     public HuaweiSmartGateway(Context contex) {
         this.mContext=contex;
     }

    public void init() {
        if (mTextToSpeech==null) {
            mTextToSpeech = new TextToSpeech(mContext, new OnInitListener() {

                @Override
                public void onInit(int status) {
                    // TODO Auto-generated method stub

                }
            });
            mTextToSpeech.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {

                @Override
                public void onUtteranceCompleted(String utteranceId) {
                    cancelDialog();
                    // TODO Auto-generated method stub
//                  startvoice();
                }
            });
        }
        //针对华为智能网关
        SSDPNotify();
        initServerSocket();
        registerResult();
    }

    public void destroy(){
//      mHander.removeMessages(6);
        unRegisterBroadcastResult();
    }
    private void registerResult() {
        if (mReceiverResult == null) {
            mReceiverResult = new MyReceiver();
        }
        Logger.d(TAG, "注册---识别结果广播");
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_HEALTH_MANAGEMENT_DATA);
        filter.addAction(ACTION_SMARTHOME_CMD);
        mContext.registerReceiver(mReceiverResult, filter);
    }

    private void unRegisterBroadcastResult() {
        if (mReceiverResult != null) {
            Logger.d(TAG, "反注册---识别结果广播");
            mContext.unregisterReceiver(mReceiverResult);
        }
    }

    /**
     * 创建内容提示框
     * @param tip
     */
    public void createDialog(String tip){
        if (dialog==null) {
            dialog = new Dialog(mContext,R.style.dialog);
            LayoutInflater layoutInflater = LayoutInflater.from(mContext);
            View viewDialog = layoutInflater.inflate(
                    R.layout.dialog_center3, null);
            TextView tv = (TextView)viewDialog.findViewById(R.id.tv_dialogcenter);
            tv.setText(tip);
            dialog.setContentView(viewDialog);
            dialog.setCanceledOnTouchOutside(false);
//          dialog.setCancelable(false);
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            dialog.show();
        }
    }
    /**
     * 取消提示框
     */
    public void cancelDialog(){
        if (dialog!=null) {
            if (dialog.isShowing()) {
                dialog.cancel();
            }
            dialog=null;
        }
    }
    /**
     * 监听ssdp查询服务
     */
    public void SSDPNotify(){
        if (lSend==null) {
            try {
                lSend=new LanSend(mContext);
                lSend.join();     //加入组播,并创建线程侦听
              } catch (Exception e) {
               System.out.println("*****加入组播失败*****");
              }
        }
    }
    /**
     * 初始化小优端ServerSocket
     */
    private ServerSocket mServerSocket;
    private Socket socket;
    public void initServerSocket(){
        if (mServerSocket==null) {
            new Thread() {
                public void run() {
                    try {
                        mServerSocket = new ServerSocket(socket通信端口号);
                        while (true) {
                            Log.e(TAG, "111111111");
                            socket=mServerSocket.accept();
                            handle(socket);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                };
            }.start();
        }

    }


    DataOutputStream out   ;
    private DataInputStream mDataInputStream;
    private MediaPlayer mphw;
    void handle(Socket socket) throws IOException {
        Log.e("myrobotSocket", "new socket");
        try {
             out = new DataOutputStream(socket.getOutputStream());
            mDataInputStream = new DataInputStream(
                    socket.getInputStream());
            while (true) {
                Log.e("myrobotSocket", "true");
            final   String cmd = mDataInputStream.readUTF();
            JSONObject jsonO2 = new JSONObject(cmd) ;
            String type=jsonO2.getString("type");
            String action_cmd=jsonO2.getString("action_cmd");
            Log.e("myrobotSocket", "type : "+type+"  ::: cmd : "+action_cmd);
            if (type!=null&&!type.isEmpty()&&action_cmd!=null&&!action_cmd.isEmpty()) {
                Message msg=new Message();
                msg.what=4;
                msg.obj="type : "+type+"  ::: cmd : "+action_cmd;
                mHander.sendMessage(msg);
            }


            if("001".equals(type)){
                if (action_cmd.contains("0X")) {
                    int action = Integer.valueOf(action_cmd.replace("0X", ""), 16);
                    MainApplication.getInstance().sendActionCmd((byte) action);
                }else if(action_cmd.contains("0x")){
                    int action = Integer.valueOf(action_cmd.replace("0x", ""), 16);
                    MainApplication.getInstance().sendActionCmd((byte) action);
                }

            }else if("002".equals(type)) {//播放插件响应,返回结果
                JSONObject jsonCMD = new JSONObject(action_cmd) ;
                String rsp=jsonCMD.getString("rsp");
                String content=jsonCMD.getString("content");
                if (content!=null&&!content.equals("")&&!content.isEmpty()) {


                    boolean blplay=false;
                    int resid = 0;
//                  Turn on the living room lights.
//                  Turn off the living room lights.
                    if (content.equals("success")&&speakresponseMsg!=null&&!speakresponseMsg.equals("")) {
                        if (speakresponseMsg.contains("turn on")&&speakresponseMsg.contains("living room")
                                &&speakresponseMsg.contains("light")) {
                            blplay=true;
                            resid=R.raw.livingroom_on;
                            content="The living room lights have been turned on.";
                        }else if (speakresponseMsg.contains("turn off")&&speakresponseMsg.contains("living room")
                                &&speakresponseMsg.contains("light")) {
                            blplay=true;
                            resid=R.raw.livingroom_off;
                            content="The living room lights have been turned off.";
                        }else {
                            content=speakresponseMsg;
                        }
                    }
                    else if (content.equals("ALARM_DOOR_OPEN")) {
                        blplay=true;
                        resid=R.raw.door_open2;
//                      content="欢迎光临智慧沃家体验馆!";
//                      createDialog(content);
//                      playhuaweiVoice2(mContext, resid);
//                      continue;
//                      content="Warning! The door is open.";
                    }
                    else if (content.equals("ALARM_DOOR_CLOSE")) {
                        blplay=false;
                        content="";
//                      blplay=true;
//                      resid=R.raw.door_close;
//                      content="The door is closed.";
                    }
                    else if (content.equals("ALARM_FALL")) {//老人看护,有人跌倒
                        blplay=true;
                        resid=R.raw.someone_felldown;
                        content="Warning! Someone fell down.";

                    }
                    if (content!=null&&!content.isEmpty()) {
                        Message msg=new Message();
                        msg.what=4;
                        msg.obj=content;
                        mHander.sendMessage(msg);
                    }

                    if (blplay) {

                        if (content!=null&&!content.isEmpty()) {
                            if (content.equals("ALARM_DOOR_OPEN")) {
                                content="欢迎光临智慧沃家体验馆!";
                                Message msg=new Message();
                                msg.what=6;
                                msg.obj=content;
                                msg.arg1=resid;
                                mHander.sendMessage(msg);
//                              mHander.sendMessageDelayed(msg, 6*1000);
                            }else {
                                Message msg=new Message();
                                msg.what=5;
                                msg.obj=content;
                                mHander.sendMessage(msg);
//                              createDialog(content);
                                if (resid!=0) {
                                    playhuaweiVoice(mContext, resid);
                                }
                            }

                        }


                    }else {
                        if (mTextToSpeech!=null) {
                            if (content!=null&&!content.isEmpty()) {
                                Log.e("myrobotSocket", "type : "+type+"  :mTextToSpeech : "+content);
                                 mTextToSpeech.speak(content, TextToSpeech.QUEUE_FLUSH, null);
                            }

                        }
                    }
                }

                }
            }
//          }


        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "" + e.toString());
            out.close();
            mDataInputStream.close();
            socket.close();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            out.close();
            mDataInputStream.close();
            socket.close();
        }
    }

    /**
     * 播放华为定制的语音2
     * @param mContext
     * @param resid
     */
    public void playhuaweiVoice2(final Context mContext,int resid){

        if (mphw != null) {
            mphw.release();
            mphw = null;
        }
        if (mphw == null) {
            mphw = MediaPlayer.create(mContext, resid);
            mphw.start();
            mphw.setOnCompletionListener(new OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp2) {
                    // TODO Auto-generated method stub
                    if(mphw!=null){
                        mphw.release();
                        mphw=null;
                    }
                    cancelDialog();
//                  String path=Environment.getExternalStorageDirectory()+"/ai/qnqn/myrobot/uushow/action/roundDance.mp3";
//                  File file=new File(path);
//                  if (file.exists()) {
//                      Uri uri=Uri.parse(path);
//                      mphw = MediaPlayer.create(mContext, uri);
//                      if (mphw!=null) {
//                          mphw.start();
//                          mphw.setOnCompletionListener(new OnCompletionListener() {
//                              @Override
//                              public void onCompletion(MediaPlayer mp) {
//                                  // TODO Auto-generated method stub
//                                  if(mphw!=null){
//                                      mphw.release();
//                                      mphw=null;
//                                  }
//                                  cancelDialog();
//                              }
//                          });
//                          int action = Integer.valueOf("2B", 16);
//                          MainApplication.getInstance().sendActionCmd((byte) action);
//                          MainApplication.getInstance().sendActionCmd((byte) action);
//                          
//                      }else {
//                          cancelDialog();
//                      }
//                  }else {
//                      cancelDialog();
//                  }

//                  startvoice();
//                  handler.sendEmptyMessage(rtcode);
                }
            });
        }

    }
    /**
     * 播放华为定制的语音
     * @param mContext
     * @param resid
     */
    public void playhuaweiVoice(Context mContext,int resid){

        if (mphw != null) {
            mphw.release();
            mphw = null;
        }
        if (mphw == null) {
            mphw = MediaPlayer.create(mContext, resid);
            mphw.start();
            mphw.setOnCompletionListener(new OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp2) {
                    // TODO Auto-generated method stub
                    if(mphw!=null){
                        mphw.release();
                        mphw=null;
                    }
                    cancelDialog();
//                  startvoice();
//                  handler.sendEmptyMessage(rtcode);
                }
            });
        }

    }

    class MyReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.e(TAG, "onReceive  " + action);
            if (ACTION_HEALTH_MANAGEMENT_DATA.equals(action)) {//上报健康管理数据
                if (out!=null&&socket!=null) {
                        try{
                            socket.sendUrgentData(0xFF);//发送一个字节判断是否为空,此字节服务端会自动舍弃
                            String  healthData=intent.getStringExtra("health_data");
                            Log.e(TAG, "healthData =  " + healthData);
                            JSONObject datajs=new JSONObject();
                            JSONObject healthjs=new JSONObject(healthData.trim());
                            datajs.put("datatype", "health_data");
                            datajs.put("datacontent", healthjs);
                            String device=healthjs.getString("device").trim();
                            Log.e(TAG, "device =  " + device);
                            if (device.equals("BloodPressure")) {
                                out.writeUTF(datajs.toString());
                                out.flush();
//                              Toast.makeText(mContext, "上传血压数据成功", Toast.LENGTH_SHORT).show();
                            }
                            else if(device.equals("Temperature")){
                                out.writeUTF(datajs.toString());
                                out.flush();
                                Log.e("myrobotSocket", "healthData =  " + healthData);
                                Log.e("myrobotSocket", "datajs =  " + datajs.toString());
//                              Toast.makeText(mContext, "上传体温数据成功", Toast.LENGTH_SHORT).show();
                            }
                            else if(device.equals("Weighting")){
                                out.writeUTF(datajs.toString());
                                out.flush();
                            }

                            return;
                            }catch(Exception ex){
                                Toast.makeText(mContext, "网关不通,上传数据失败", Toast.LENGTH_SHORT).show();
                            return;
                            }
                    }else {
                        Toast.makeText(mContext, "socket=null,上传数据失败", Toast.LENGTH_SHORT).show();
                        return;
                }
            }else if(ACTION_SMARTHOME_CMD.equals(action)) {//智能家居命令上报
                if (out!=null&&socket!=null) {
                    try{
                        socket.sendUrgentData(0xFF);//发送一个字节判断是否为空,此字节服务端会自动舍弃
                        String  smarthomeCMD=intent.getStringExtra("smarthome_cmd");
                        Log.e(TAG, "smarthomeCMD =  " + smarthomeCMD);
                        JSONObject smarthomejs=new JSONObject();
                        smarthomejs.put("datatype", "smarthome_data");
                        smarthomejs.put("datacontent", smarthomeCMD.trim());
                            out.writeUTF(smarthomejs.toString());
                            out.flush();
//                          Toast.makeText(mContext, "上报智能家居指令成功", Toast.LENGTH_SHORT).show();
                            Intent  i= new Intent(ConstUtils.ACTION_SMARTHOME_CMD_HANDLE_EXCEPTION) ;
                            mContext.sendBroadcast(i);
//                          startvoice();
                        return;
                        }catch(Exception ex){
                            ex.printStackTrace();
                            Toast.makeText(mContext, "网关不通,上报智能家居指令失败", Toast.LENGTH_SHORT).show();
                            Intent  i= new Intent(ConstUtils.ACTION_SMARTHOME_CMD_HANDLE_EXCEPTION) ;
                            mContext.sendBroadcast(i);
//                          startvoice();
                        return;
                        }
                }else {
                    Toast.makeText(mContext, "socket=null,上报智能家居指令失败", Toast.LENGTH_SHORT).show();
                    Intent  i= new Intent(ConstUtils.ACTION_SMARTHOME_CMD_HANDLE_EXCEPTION) ;
                    mContext.sendBroadcast(i);
//                  startvoice();
                    return;
                    }
            }

                }

    } ;

    }

智能网关小优驱动插件实现

3. 智能网关插件上报指令信息
智能网关插件收到小优端、手机端、其他智能设备发过来字符串信息,就对其进行语义分析,如果能跟智能网关上的事件信息匹配上,把此事件上报给智能网关处理,否则不上报。
这里写图片描述
核心代码如下(其中部分代码为华为Openlife平台提供):
CanbotDeviceListener 类为小优的设备监听类,起一个循环测试线程,每隔6秒测试一次socket是否通,不通重连,监听到设备端发来的事件信息并作出处理

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import org.json.JSONObject;

import com.huawei.smarthome.api.event.IDeviceEventListener;
import com.huawei.smarthome.driver.IDeviceService;
import com.huawei.smarthome.driver.ip.AbstractSsdpDeviceDriverAdapter;
import com.huawei.smarthome.log.LogService;
import com.huawei.smarthome.log.LogServiceFactory;

/**
 * <div class="English">
 * 设备监听器,当机器人上线时与机器人进行连接
 * </div>
 * 
 * <div class="Chinese">
 * 
 * </div>
 * <br>
 * @author Lixin
 * @since NetOpen 1.0
 * 2015年12月30日
 */
public 以上是关于小优机器人WIFI+SSDP入网具体实现的主要内容,如果未能解决你的问题,请参考以下文章

小优机器人WIFI+SSDP入网具体实现

浅谈智慧家庭小优机器人通过WIFI+SSDP方式接入华为智能网关

浅谈智慧家庭小优机器人通过WIFI+SSDP方式接入华为智能网关

使用WiFi热点抓包产生的SSDP流量分析

实现upnp ssdp来查找局域网内的其他节点

优测干货分享微信测试工程师手把手教你做弱网络模拟测试