zoukankan      html  css  js  c++  java
  • AllJoyn+Android开发案例-android跨设备调用方法

    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:alljoynalljoyn-androidcorealljoyn-15.04.00b-reljavajaralljoyn.jar
    我的.so的绝对路径:G:alljoynalljoyn-androidcorealljoyn-15.04.00b-reljavalibliballjoyn_java.so
    大家依据自己的解压位置去找就好了。
    加入到project后例如以下图所看到的:

    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上总线对象在总线附件上注冊的路径。



  • 相关阅读:
    转载+自己心得
    分享
    领域驱动设计系列文章汇总
    ABP集合贴
    MVC学习系列——参考
    MVC学习系列——RazorViewEngine扩展
    MVC学习系列——Model验证扩展
    MVC学习系列——HtmlHelper扩展
    MVC学习系列——ModelBinder扩展
    MacBook强制清除gardle缓存
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7398776.html
Copyright © 2011-2022 走看看