AllJoyn+Android开发案例-android跨设备调用方法 项目需要涉及AllJoyn开源物联网框架。前面主要了解了一些AllJoyn基本的概念,像总线,总线附件,总线对象,总线接口这样的概念,以及之间的关系和跨设备、平台的调用功能。项目最终的目的实现是,跨平台的方法调用如:windows调用android,以及对于设备事件的订阅功能。 入手的步骤: 1.实现android端的跨设备方法(自定义)调用案例-java 2.实现windows端的跨设备方法(自定义)调用案例-c++ 3.实现windows端和android端的跨设备方法调用案例-(window用C++,android用java) 4.结合实际项目实现跨平台、跨设备的方法调用和订阅功能 现阶段我们来尝试实现android端的跨设备方法(自定义)调用案例-java 上面一篇关于博客--AllJoyn+Android开发的一般步骤,主要概念上描述了如何实现调用,这篇文章我们结合android代码实现,走一遍流程,加深理解和记忆。参考地址http://blog.csdn.net/jsjdtb356/article/details/51084886。 官网参考地址(很重要)https://allseenalliance.org/framework/documentation/develop/api-guide/core/java 开源代码(core API+很多实例-android studio可运行):https://allseenalliance.org/framework/download step1: 新建android studio project,选择file/project structrue 设置好java sdk,android sdk,android ndk的路径。 step2: 添加两个库文件,一个是alljoyn.jar库文件,一个是liballjoyn_java.so库文件,下载地址https://allseenalliance.org/framework/download。版本我下载的是15.04,如下图。
我的.jar的绝对路径:G:\alljoyn\alljoyn-android\core\alljoyn-15.04.00b-rel\java\jar\alljoyn.jar 我的.so的绝对路径:G:\alljoyn\alljoyn-android\core\alljoyn-15.04.00b-rel\java\lib\liballjoyn_java.so
大家根据自己的解压位置去找就好了。 添加到工程后如下图所示:
project视图下,添加的路径和文件夹名称,没有文件夹则建立对应名称的文件夹。然后将jar添加作库。 step3: 实现流程 大致画一个示意图:
server代码实现:一个activity用于交互,button开启一个service;service中具体实现alljoyn代码;一个总线接口,总线对象要实现的接口;service上代码如下。
package com.example.siemens.testgetmethod;import android.app.Service;import android.content.Intent;import android.net.wifi.WifiConfiguration;import android.os.Handler;import android.os.HandlerThread;import android.os.IBinder;import android.os.Looper;import android.os.Message;import android.util.Log;import android.widget.Toast;import org.alljoyn.bus.BusAttachment;import org.alljoyn.bus.BusObject;import org.alljoyn.bus.Mutable;import org.alljoyn.bus.SessionOpts;import org.alljoyn.bus.SessionPortListener;import org.alljoyn.bus.Status;import javax.net.ssl.SSLEngineResult;public class MyService extends Service {    private final String TAG="MyService";    public MyService() {//        super();    }    @Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.//        throw new UnsupportedOperationException("Not yet implemented");        return null;    }    public int onStartCommand(Intent intent, int flags, int startId) {//        Log.i(TAG, "onStartCommand()");        return START_STICKY;    }    public void onDestroy() {//        backgroundHandler.exit();    }    public void onCreate(){        Log.i(TAG,"onCreate method.");        //mbus初始化        mBus=new BusAttachment(getPackageName(),BusAttachment.RemoteMessage.Receive);        startBusThread();        if(backgroundHandler!=null)            backgroundHandler.connect();        else            return;    }    private void startBusThread(){        HandlerThread handlerThread=new HandlerThread("My HandlerThread");        handlerThread.start();        Looper loop=handlerThread.getLooper();        backgroundHandler=new BackgroundHandler(loop);        Log.i(TAG,"startBusThread method.");    }    //请求都在线程中执行    private BackgroundHandler backgroundHandler=null;    private final int CONNECT=2;    //私有内部不可变类    private final class BackgroundHandler extends Handler{        public BackgroundHandler(Looper looper){            super(looper);        }        public void connect(){            Log.i(TAG,"backgroundHandler.connect()");            Message msg=backgroundHandler.obtainMessage(CONNECT);//相当于message.what=2;            backgroundHandler.sendMessage(msg);        }        public void handleMessage(Message msg){            switch(msg.what){                case CONNECT:                    doConnect();                    break;                default:                    break;            }        }    }    //创建总线附件对象,getPackageName()出现NullPointerException异常,先于构造函数执行,此时对象为null,所以放到oncreate里边去//    private BusAttachment mBus=new BusAttachment(getPackageName(),BusAttachment.RemoteMessage.Receive);    private BusAttachment mBus=null;    //创建总线对象    private MyBusObject myBusObject=new MyBusObject();    //总线对象类,实现总线接口和总线对象接口    class MyBusObject implements MyInterface,BusObject{//        public void show(String args){//            Toast.makeText(getApplicationContext(),args,Toast.LENGTH_SHORT).show();     //会调用的远程方法////        }////        public int add(int a,int b){                        //会调用的远程方法//            return a+b;//        }        public String cat(String a,String b){            a=a.replace('H','T');            b=b.replace('W','B');            return a+b;        }    }    //session的端口号    private static final short CONTACT_PORT=42;    //总线对象,总线附件等连接到总线上的实现函数,创建的是service    private void doConnect(){        org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());  //启动守护进程        Status status=mBus.registerBusObject(myBusObject,"/myBusObject");                     //注册总线对象        if (Status.OK != status) {            System.out.println("BusAttachment.registerBusObject() failed: " + status);            System.exit(0);            return;        }        //总线附件连接到总线上        status=mBus.connect();        if (status != Status.OK) {            Log.i(TAG,"BusAttachment connect to bus failed.");            System.exit(0);            return;        }        //通信的session port 设置        Mutable.ShortValue contactPort = new Mutable.ShortValue(CONTACT_PORT);        SessionOpts sessionOpts = new SessionOpts();        sessionOpts.traffic = SessionOpts.TRAFFIC_MESSAGES;        sessionOpts.isMultipoint = false;        sessionOpts.proximity = SessionOpts.PROXIMITY_ANY;        sessionOpts.transports = SessionOpts.TRANSPORT_ANY;        //绑定通信的session port        status=mBus.bindSessionPort(contactPort,sessionOpts,new SessionPortListener(){            @Override            public boolean acceptSessionJoiner(short sessionPort, String joiner, SessionOpts sessionOpts){                if (sessionPort == CONTACT_PORT) {                    return true;                } else {                    return false;                }            }        });        if (status != Status.OK) {            Log.i(TAG,"bind certain session port failed.");            System.exit(0);            return;        }        //向总线请求一个名称        int flags = 0; //do not use any request name flags        status = mBus.requestName("com.test.well.known.name", flags);        if (status != Status.OK) {            Log.i(TAG,"request name from bus failed.");            System.exit(0);            return;        }        //在总线上宣告name的存在        status = mBus.advertiseName("com.test.well.known.name", SessionOpts.TRANSPORT_ANY);        if (status != Status.OK) {            Log.i(TAG,"advertise name on bus failed.");            mBus.releaseName("com.test.well.know.name");            System.exit(0);            return;        }else            Toast.makeText(getApplicationContext(),"advertise name=com.test.well.known.name",Toast.LENGTH_SHORT).show();    }    static{        System.loadLibrary("alljoyn_java");    }}
注意:静态初始化块中的loadlibrary不能少掉。上面的例子参照的是chat源码。 接口代码:
package com.example.siemens.testgetmethod;import org.alljoyn.bus.BusException;import org.alljoyn.bus.annotation.BusInterface;import org.alljoyn.bus.annotation.BusMethod;/** * Created by Siemens on 2016/4/8. */@BusInterface (name = "org.my.interface.name")public interface MyInterface {//    @BusMethod//    void show(String test) throws BusException;//    @BusMethod//    int add(int a,int b) throws BusException;    @BusMethod    String cat(String a,String b) throws BusException;}
注意:格式必须按照这种格式来,上面接口的name属性后面的值很重要client要对应。 client代码如下:
package com.example.siemens.testgetmethodclient;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;import android.widget.Toast;import org.alljoyn.bus.BusAttachment;import org.alljoyn.bus.BusListener;import org.alljoyn.bus.Mutable;import org.alljoyn.bus.ProxyBusObject;import org.alljoyn.bus.SessionListener;import org.alljoyn.bus.SessionOpts;import org.alljoyn.bus.Status;public class MyService extends Service {    private final String TAG="MyClientService";    public MyService() {    }    @Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.//        throw new UnsupportedOperationException("Not yet implemented");        return null;    }    private BusAttachment mBus=null;    private static final short CONTACT_PORT=42;    //代理总线对象;接口对象    private ProxyBusObject mProxyObj;    public MyInterface mInterface;//    public MyInterface getmInterface(){//        return mInterface;//    }    //application对象    private ClientApplication mApplication;    @Override    public void onCreate(){        mApplication=(ClientApplication)getApplication();        //守护进程不能忘        org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());  //启动守护进程        mBus=new BusAttachment(getApplication().getPackageName(),BusAttachment.RemoteMessage.Receive);        //连接两次?//        Status status=mBus.connect();//        if (Status.OK != status) {//            Log.i(TAG,"client busattachment first connect to bus failed.");//            System.exit(0);//            return;//        }        mBus.registerBusListener(new BusListener(){            @Override            public void foundAdvertisedName(String name, short transport,String namePrefix){                mBus.enableConcurrentCallbacks();                short contactPort = CONTACT_PORT;                SessionOpts sessionOpts = new SessionOpts();                sessionOpts.traffic = SessionOpts.TRAFFIC_MESSAGES;                sessionOpts.isMultipoint = false;                sessionOpts.proximity = SessionOpts.PROXIMITY_ANY;                sessionOpts.transports = SessionOpts.TRANSPORT_ANY;                Mutable.IntegerValue sessionId = new Mutable.IntegerValue();                Status status = mBus.joinSession(name,contactPort,sessionId,sessionOpts,new SessionListener());                mProxyObj = mBus.getProxyBusObject("com.test.well.known.name", "/myBusObject", sessionId.value, new Class[]{MyInterface.class});                mInterface=mProxyObj.getInterface(MyInterface.class);                //personal add                mApplication.setTestInterface(mInterface);            }        });        //连接两次??官网API问题???        Status status=mBus.connect();        if (Status.OK != status) {            Log.i(TAG,"client busattachment second connect to bus failed.");            System.exit(0);            return;        }        //找到指定名称的busAttachment        status = mBus.findAdvertisedName("com.test.well.known.name");        if (status != Status.OK) {            Log.i(TAG,"client findAdvertisedName failed.");            System.exit(0);            return;        }        else            Toast.makeText(getApplicationContext(),"find name=com.test.well.known.name success.",Toast.LENGTH_SHORT).show();    }    static{        System.loadLibrary("alljoyn_java");    }}
同时client端app也需要知道总线接口,但是要通过代理对象获得方法的具体实现,也要包含接口类,同server接口类。 总结:有4个client和server需要统一的地方。1.advertise的那个name,客户端是根据这个名称找server。2.接口类,server和client都要知道,server提供实现,client不知道具体实现。3.session设置的端口号,client的session port要和server统一。4.client要知道,server上总线对象在总线附件上注册的路径。



更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. python list.sort()根据多个关键字排序的方法实现
  3. 代码实现Android流量统计
  4. Android(安卓)Window类解析
  5. Android(安卓)创建与解析XML(一)—— 概述
  6. Android(安卓)设备上实现串口的移植
  7. android 连接远程数据库(转)
  8. Unity3D 调用 Android(安卓)jar 包制作方法
  9. Android编程简单实现拨号器功能的方法

随机推荐

  1. 分享:android图片浏览器—类微信朋友圈相
  2. Android退出程序问题综述
  3. 禁用button的方法
  4. TabActivity底部菜单栏
  5. 在intellij idea 中进行android 单元测试
  6. Android(安卓)Studio 快捷方式
  7. Android音频流播放过程
  8. Android(安卓)http get/post传递参数
  9. android中activity栈详解
  10. Android(安卓)大文件上传时,处理上传进度