AllJoyn+Android开发案例-android跨设备调用方法
2016-04-18 17:11
736 查看
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代码实现,走一遍流程,加深理解和记忆。参考地址/article/7709405.html。
官网参考地址(很重要):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上代码如下。
注意:静态初始化块中的loadlibrary不能少掉。上面的例子参照的是chat源码。
接口代码:
注意:格式必须按照这种格式来,上面接口的name属性后面的值很重要client要对应。
client代码如下:
同时client端app也需要知道总线接口,但是要通过代理对象获得方法的具体实现,也要包含接口类,同server接口类。
总结:有4个client和server需要统一的地方。1.advertise的那个name,客户端是根据这个名称找server。2.接口类,server和client都要知道,server提供实现,client不知道具体实现。3.session设置的端口号,client的session port要和server统一。4.client要知道,server上总线对象在总线附件上注册的路径。
项目需要涉及AllJoyn开源物联网框架。前面主要了解了一些AllJoyn基本的概念,像总线,总线附件,总线对象,总线接口这样的概念,以及之间的关系和跨设备、平台的调用功能。项目最终的目的实现是,跨平台的方法调用如:windows调用android,以及对于设备事件的订阅功能。
入手的步骤:
1.实现android端的跨设备方法(自定义)调用案例-java
2.实现windows端的跨设备方法(自定义)调用案例-c++
3.实现windows端和android端的跨设备方法调用案例-(window用C++,android用java)
4.结合实际项目实现跨平台、跨设备的方法调用和订阅功能
现阶段我们来尝试实现android端的跨设备方法(自定义)调用案例-java
上面一篇关于博客--AllJoyn+Android开发的一般步骤,主要概念上描述了如何实现调用,这篇文章我们结合android代码实现,走一遍流程,加深理解和记忆。参考地址/article/7709405.html。
官网参考地址(很重要):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上总线对象在总线附件上注册的路径。
相关文章推荐
- Android M 动态权限获取
- Android插件化框架研究-DroidPlugin
- Android Studio 如何打JAR包
- Android中程序与Service交互的方式——交互方式
- Android Bitmap与DrawAble与byte[]与InputStream之间的转换工具类
- Android从启动到程序运行发生的事情
- Android中程序与Service交互的方式——综述
- Android将应用log信息保存文件
- Android Studio开发可以使用的一些框架
- Android动画之TranslateAnimation使用
- Android媒体播放---Media playback
- android开发 AutoCompleteTextView自定义适配器
- android6.0(M)新特性
- android 各种开源控件,框架
- Android 线层池解析
- android 事件分发机制一
- Android Studio 获取SH1和MD5的方法
- Android实现搜索功能并本地保存搜索历史记录
- Android基础控件 -- EditText
- android webview使用html5<input id="input" type="file"/> 上传相册、拍照照片