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后例如以下图所看到的:

project视图下,加入的路径和目录名称。没有目录则建立相应名称的目录。然后将jar加入作库。
step3:
实现流程大致画一个示意图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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





AllJoyn+Android开发案例-android跨设备调用方法的更多相关文章

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

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

  2. CSharp程序员学Android开发---3.Android内部元素不填充BUG

    最近公司组织项目组成员开发一个Android项目的Demo,之前没有人有Andoid方面的开发经验,都是开发C#的. 虽说项目要求并不是很高,但是对于没有这方面经验的人来说,第一步是最困难的. 项目历 ...

  3. Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能. 下面是一个效果图 ...

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

    )关于点击事件,没有像ListView那样现成的API,但是自己封装起来也不难,而且我们使用ListView时,如果item中有可点击组件,那么点击事件的冲突也是一个问题,而在RecyclerView ...

  5. ThinkPHP跨控制器调用方法

    跨控制器调用方法 1. 先造对象,再调用里面的方法 $sc=new \Home\Controller\IndexController();  用绝对路径找echo $sc->ShuChu(); ...

  6. JS访问或设置cookie的方法+跨域调用方法

    无意中从163网站获取的JS访问或设置cookie的方法,Log到日志上以防遗忘 //COOKIE功能检查function fCheckCookie(){    if(!navigator.cooki ...

  7. Android 开发 获取Android设备的屏幕高宽

    获得屏幕的宽度和高度有很多种方法: //1.通过WindowManager获取 DisplayMetrics dm = new DisplayMetrics(); heigth = dm.height ...

  8. Android开发笔记(8)——调用子Activity

     转载请注明:http://www.cnblogs.com/igoslly/p/6853730.html  调用子Activity 需要子Activity返回值 MainActivity使用start ...

  9. Android开发案例 - 欢迎界面

    本文详细描述了如何实现如下图中的微信启动界面. 该类启动界面的特点是在整个Application的生命周期里, 它只会出现在第一次进入应用时, 即便按回退键到桌面之后. 使用该类启动界面的应用还有: ...

随机推荐

  1. hdu4122

    题目很长,有点恶心,但实际上是个单调队列 没搞出来,题解 https://blog.csdn.net/lvshubao1314/article/details/46910271 #include< ...

  2. 步步为营-57-JQuery练习题

    01 点谁谁哭 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head&g ...

  3. 通过生成支付二维码来实现微信支付的解决方案 - EasyWechat版(转)

    上一篇我们讲了在微信浏览器内实现微信支付的功能,它特别适合于一些基于微信公众号的h5站点等,支付流程也相当流畅,但是... 还有一种情况,比如现在北哥兄弟连PC版,是生成了一个二维码,这个二维码是专属 ...

  4. Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分

    PO:持久对象 (persistent object),po(persistent object)就是在Object/Relation Mapping框架中的Entity,po的每个属性基本上都对应数 ...

  5. mac电脑对ntfs格式硬盘进行写操作(简单说就是向ntfs硬盘拷贝东西)

    使用mac电脑的童鞋应该都会遇到一个问题: 对ntfs格式的优盘或硬盘(移动硬盘默认ntfs)只能读不能写,也就是只能拷贝出数据,却没法拷贝数据到移动硬盘中. 下面是参考自网上的一种方法,无需第三方软 ...

  6. python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)

    python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...

  7. TensorFlow 常用的函数

    TensorFlow 中维护的集合列表 在一个计算图中,可以通过集合(collection)来管理不同类别的资源.比如通过 tf.add_to_collection 函数可以将资源加入一个或多个集合中 ...

  8. 细说java中的类

    前言 最近在学习<java编程思想> 学到了内部类 类不就是class吗 天天用 还能讲出花来了不成... 其实不然,在java中,类的种类和使用方式多种多样,花样繁多.其中主要有 普通类 ...

  9. IntelliJ IDEA关于logger的live template配置

    1.安装 log support2插件 2.配置log support2 由于项目中的日志框架是公司自己封装的,所以还需要自己手动改一下 log support2插件生成的live template ...

  10. 算法进阶面试题04——平衡二叉搜索树、AVL/红黑/SB树、删除和调整平衡的方法、输出大楼轮廓、累加和等于num的最长数组、滴滴Xor

    接着第三课的内容和讲了第四课的部分内容 1.介绍二叉搜索树 在二叉树上,何为一个节点的后继节点? 何为搜索二叉树? 如何实现搜索二叉树的查找?插入?删除? 二叉树的概念上衍生出的. 任何一个节点,左比 ...