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();}@Overridepublic 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();elsereturn;}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;//总线对象,总线附件等连接到总线上的实现函数,创建的是serviceprivate 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 portstatus=mBus.bindSessionPort(contactPort,sessionOpts,new SessionPortListener(){@Overridepublic 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 flagsstatus = 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;}elseToast.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;@BusMethodString 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() {}@Overridepublic 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;@Overridepublic 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(){@Overridepublic 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 addmApplication.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;}//找到指定名称的busAttachmentstatus = mBus.findAdvertisedName("com.test.well.known.name");if (status != Status.OK) {Log.i(TAG,"client findAdvertisedName failed.");System.exit(0);return;}elseToast.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上总线对象在总线附件上注册的路径。

AllJoyn+Android开发案例-android跨设备调用方法相关推荐

  1. 《Android开发案例驱动教程》

    <Android开发案例驱动教程> 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式展开讲解知识点,即介绍案例->案例涉及技术->展开 ...

  2. 关于android开发中startActivityForResult废弃的替换方法调用

    关于android开发中startActivityForResult废弃的替换方法调用 在最近一段时间中,能在开发时看到在android studio中,startActivityForResult方 ...

  3. Android开发——RecyclerView特性以及基本使用方法(二)

    0.  前言 随着Android的发展,虽然ListView依旧重要,但RecyclerView确实越来越多的被大家使用.但显然并不能说RecyclerView就一定优于ListView,而是应该根据 ...

  4. android自定义省略号,Android开发自定义TextView省略号样式的方法

    本文实例讲述了Android开发自定义TextView省略号样式的方法.分享给大家供大家参考,具体如下: 在布局xml中设置textView的字段 android:maxLines="2&q ...

  5. 【Android开发】Android入门安装与使用教程——以Android Studio3.6.1为例

    [Android开发]Android入门教程--以Android Studio3.6.1为例 1.为什么要学习Android 2.学习资源 3.安装Android Studio 3.1 下载安装包 3 ...

  6. 【Android开发】Android Studio中进行简单的WebView构建浏览器开发1

    [Android开发]Android Studio中进行简单的WebView构建浏览器开发 第一步:新建一个Android Project 第二步:修改AndroidMainfest.xml文件 第三 ...

  7. 【Android开发】Android Studio中进行简单的WebView构建浏览器开发2

    [[Android开发]Android Studio中进行简单的WebView构建浏览器开发2 第1步:在上一篇博客的基础上,修改activity_main.xml 第2步:在MainActivity ...

  8. <Android开发> Android vold - 第一篇 vold前言简介

    本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android ...

  9. Android开发环境搭建及常见问题解决方法

    Android开发环境搭建及常见问题解决方法 参考文章: (1)Android开发环境搭建及常见问题解决方法 (2)https://www.cnblogs.com/rwxwsblog/p/476978 ...

  10. 文件管理器android实现,Android开发之简单文件管理器实现方法

    易采站长站为您分析Android开发之简单文件管理器实现方法,简单实现了Android的文件目录查看,文件重命名,打开,删除等功能,需要的朋友可以参考下 本文实例讲述了Android开发之简单文件管理 ...

最新文章

  1. 在okhttp3,WebView中忽略HTTPS证书校验
  2. Spring Boot Admin 2.1.4,Spring Boot 应用的 Admin UI
  3. 用python画烟花-过年了,用Python放一场浪漫烟花秀!
  4. 网络1711c语言第0次作业总结
  5. CodeForces - 1355C Count Triangles(数学)
  6. iis同时运行asp和php,服务器IIS同时支持ASP和PHP
  7. android 知识点大全,Android基础知识总结(一)
  8. Flutter基础—手势处理
  9. haproxy配置代理tomcat和nginx_Nginx负载均衡配置实例
  10. 电磁仿真原理——4. 矩量法(Moment Methods)
  11. Ubuntu20.04安装Nvidia显卡驱动
  12. Python基础教程,Python入门教程(超详细)
  13. 【RT-Thread 作品秀】空气质量监测系统
  14. 树莓派开启 wifi 热点
  15. 1.React 简介
  16. MySQL 是如何保证一致性、原子性和持久性的!
  17. 增量学习简介(incremental learning)
  18. 请问什么叫纹波?怎样测量纹波?
  19. okhttp3发送https请求
  20. 编程课程与数学的关系

热门文章

  1. 针对我国——国产数据库进行分析
  2. 直播系统开发需要注意的事项
  3. Kali linux 全部版本镜像下载
  4. 如何更改IDEA的主题(背景黑色还是白色)
  5. 斐讯盒子T1_【YYF固件】夏杰语音实用版刷机固件及教程分享
  6. 高等数学中▽符号的作用
  7. php商品详情显示页面代码,ecshop源码程序在购物车页面显示出商品的描述
  8. c语言宿舍管理系统程序,C语言——学生宿舍管理系统
  9. 蓝桥杯题目练习 水题 [蓝桥杯2019初赛]质数
  10. 美赛只用matlab够,美赛思路