Android附近:如何集成Android和Android的东西

本文将探讨如何使用Android Nearby,展示如何集成Android和Android Things。我们可以使用几种策略来集成Android和Android Things。Android Nearby技术就是其中之一。Android提供了一组API,可以简化两个不同设备之间的数据交换。一个有趣的方面是Android Nearby也支持iOS操作系统。

• Android Nearby是一项支持三种不同策略来集成Android设备的技术:

• Android Nearby Messages:这使用发布者/订阅者范例在两个不同的Android设备之间交换简单的有效负载。
• Android Nearby Connections:它是一个点对点网络,使应用程序能够在设备之间发现,连接和交换数据。这种策略支持高带宽,它可以在多种场景中使用(游戏,文件共享等)
Android附近通知:此技术使用户可以使用应用或网站接收周围的通知
本文介绍了如何使用Android Nearby Connections集成Android和Android Things设备。主要目标是展示如何将数据从Android智能手机发送到Android Things设备,并使用连接到Android Things的LCD显示屏显示此信息。

Android Nearby简介
Android Nearby连接是一个点对点网络。该网络有两个主要角色:

• 通告自己等待传入连接的广告商
• 寻找要连接的广告商的Discoverer
一旦Discoverer找到了广告商,他们就可以建立连接并交换数据。在Android引擎盖下,Android Nearby API使用一组技术来建立不同设备之间的连接。它可以是蓝牙或Wi-Fi。API利用每种技术的优势来保证可靠的连接。开发人员和用户不必担心它,它是完全透明的。

在本教程中,Android Things设备扮演等待传入Discoverer的广告商角色。Android设备是Discoverer,用于查找要连接的广告商。为了完成本教程,有必要实现两个不同的应用程序:

Android Things应用程序,用于接收数据并处理LCD显示
将数据发送到Android Things的Android应用
此外,Android Nearby连接支持不同的发现和广告策略。一般来说,这两种策略是:

• P2P_Cluster:支持M-to-N网络拓扑,其中每个设备都可以接受传入连接并启动与其他设备的新连接
• P2P_STAR:这是一个经典的起始拓扑网络,其中一个设备作为广告商播放,其他设备是发现的
在这个Android Things教程中,我们将使用P2P_STAR拓扑。让我们开始实施广告客户。


使用Android Things的Android附近广告商


第一步是使用Android Thing设备实施广告商。在这种情况下,我们将使用Raspberry Pi 3,但您可以使用与Android Things兼容的其他原型板。

要实施Android Nearby Advertiser,我们必须遵循以下三个不同的步骤:

开始做广告
接受传入的连接
收听传入的有效负载
第四步是可选的,它正在管理连接到Android Things的LCD显示器,以便Android Things应用程序将在LCD显示器上显示有效载荷内容。


使用Android Things开始广告


第一件事是创建一个新类来处理所有Nearby连接细节。让我们称这个班 NearbyAdvManager。在构造函数中,Android Thing应用程序开始广告:

私有 ConnectionsClient  客户端 ;
..
客户 =  附近。getConnectionsClient(ctx);
客户。startAdvertising(“ AndroidThings ”,
        SERVICE_ID,
        connectionLifeCycleCB,
        新 AdvertisingOptions(战略。P2P_STAR))
         。addOnSuccessListener(
           new  OnSuccessListener < Void >(){
              @覆盖
              public  void  onSuccess(Void  aVoid){
                记录。我(TAG,“OnSuccess ......”);
              }
           }
        )
        。addOnFailureListener(new  OnFailureListener(){
            @覆盖
            public  void  onFailure(@NonNull  Exception  e){
               记录。e(TAG,“OnFailure 1”);
               e。printStackTrace();
            }
      });
}

"Android Things"是昵称,而SERVICE_ID我们的服务ID。通常,SERVICE_ID是我们的应用程序的包名称。另一个参数connectionLifeCycleCB, 是回调类。

请注意,Android Nearby有一组新的API。当我们创建广告商时,我们不再需要使用它 GoogleApiClient了。

是时候实现连接回调,以便Android Things应用程序获得有关连接的通知。为此,我们将此代码添加到管理器:

private  ConnectionLifecycleCallback  connectionLifeCycleCB  = 
   新的 ConnectionLifecycleCallback(){
     @覆盖
     public  void  onConnectionInitiated(String  s,
                   ConnectionInfo  connectionInfo){
       记录。我(标签,“连接发起。结束[” + s + “]”);
       //让我们接受这种联系
     }
     @覆盖
     public  void  onConnectionResult(String  s,
            ConnectionResolution  connectionResolution){
            记录。i(标签,“连接结果。结束[” + s + “]”);
      }
      @覆盖
      public  void  onDisconnected(String  s){
          记录。我(TAG,“Disconnected.Endpont [” + s + “]”);
      };
    };

接受Android Things App中的传入连接


一旦Android Things应用程序开始广告,就必须处理传入的连接。正如我们之前看到的,在连接回调接口中,我们有更改来处理连接。在onConnectionInitiated被称为当发现者要开始对广告客户的新连接。在此方法中,添加以下行:

附近。getConnectionsClient(ctx)
          。acceptConnection(s,payloadCallback);

使用此代码,Android Things应用程序可以接受所有传入连接,而无需使用身份验证机制。可以对客户端进行身份验证,以便我们可以应用某些安全策略。

最后一步是传入,payloadCallback因此应用程序可以处理传入的有效负载。


处理Android附近的有效负载


这是Android Nearby Advertiser的最后一步。Android Things应用程序必须实现PayloadCallback接口以读取传入的有效负载。

private  PayloadCallback  payloadCallback  =  new  PayloadCallback(){
    @覆盖
    public  void  onPayloadReceived(String  s,Payload  payload){
        记录。我(TAG,“收到有效负载”);
        byte [] b  =  有效载荷。asBytes();
        String  content  =  new  String(b);
        记录。我(标签,“内容[” + 内容+ “]”);
    }
    @覆盖
    public  void  onPayloadTransferUpdate(String  s,
           PayloadTransferUpdate  payloadTransferUpdate){
       记录。d(TAG,“有效载荷转移更新[” + s + “]”);
      }
};

在onPayloadReceived,我们将处理LCD显示屏以显示有效载荷内容。


实现附近的Android事物应用程序


经理准备好后,是时候实施Android Things Nearby应用了。让我们创建MainActivity课程:

@覆盖
protected  void  onCreate(Bundle  savedInstanceState){
  超。onCreate(savedInstanceState);
  记录。我(标签,“启动Android Things应用......”);
  NearbyAdvManager  advManager  =  new  NearbyAdvManager(this);
}

稍后,我们将处理连接到Android Things的LCD显示器,以便它可以显示有效载荷内容。

在销毁应用程序时,不要忘记关闭连接并停止广告

最后,我们可以要求权限了 AndroidManifest.xml

< uses-permission  android:name = “android.permission.BLUETOOTH”  />
< uses-permission  android:name = “android.permission.BLUETOOTH_ADMIN”  />
< uses-permission  android:name = “android.permission.ACCESS_WIFI_STATE”  />
< uses-permission  android:name = “android.permission.CHANGE_WIFI_STATE”  />
< uses-permission  android:name = “android.permission.ACCESS_COARSE_LOCATION”  />

您已准备好启动该应用。为此,您可以使用兼容的Android Things设备。在本教程中,我们将使用运行Android Things 1.0.3的Raspberry Pi 3。

启动Android Things应用程序时,请确保这是第一个应用程序,否则您可能会遇到一些错误

使用Nearby实现Android应用程序

在本段中,我们将介绍如何实现播放Discoverer角色并将数据发送到Android Things应用的Android应用。实现此应用程序的步骤与之前用于实现Android Things Nearyby应用程序的步骤几乎相同。让我们从创建一个名为的类开始NearbyDsvManager。本课程将管理所有详细信息,以便与Android Things应用程序一起发现,连接和交换数据。

将此构造函数添加到此类:

public  NearbyDsvManager(Context  ctx,final  EventListener  listener){
    这个。listener  =  listener ;
    这个。ctx  =  ctx ;
    记录。我(TAG,“NearbyDsvManager”);
    附近。getConnectionsClient(ctx)
         。startDiscovery(SERVICE_ID,
            endpointDiscoveryCB,
            新 DiscoveryOptions(战略。P2P_STAR))
            。addOnSuccessListener(
                 new  OnSuccessListener < Void >(){
                    @覆盖
                    public  void  onSuccess(Void  aVoid){
                        记录。我(TAG,“OnSuccess ......”);
                         听众。startDiscovering();
                     }
                 }
            )
           。addOnFailureListener(new  OnFailureListener(){
               @覆盖
               public  void  onFailure(@NonNull  Exception  e){
                  记录。e(TAG,“OnFailure”,e);
                  e。printStackTrace();
               }
       });
}

这个类几乎与前面描述的相同。它开始发现试图找到准备交换数据的广告商。此外,在此类中,定义了一个回调接口,用于在发现和连接过程中通知调用者(MainActivity)有关事件的信息。此回调接口是:

public  interface  EventListener {
   public  void  onDiscovered();
   public  void  startDiscovering();
   public  void  onConnected();
}

此外,Nearby API使用另一个回调接口来通知调用者有关发现状态的信息。在上面的代码中,列表是endpointDiscoveryCB:

private  EndpointDiscoveryCallback  endpointDiscoveryCB  =  new  EndpointDiscoveryCallback(){
    @覆盖
    public  void  onEndpointFound(String  s,DiscoveredEndpointInfo  discoveredEndpointInfo){
       记录。我(TAG,“Endpoint found [” + s + “]。Connecting ....”);
       听众。onDiscovered();
       getConnection(s);
     }
    @覆盖
    public  void  onEndpointLost(String  s){
       记录。e(TAG,“终点丢失[” + s + “]”);
    }
 };

将附

近的Discoverer连接到附近的广告商

Discoverer找到有效端点(由广告商提供)后,Discoverer会尝试启动连接getConnection(s),其中s是发现的端点:

private  void  getConnection(String  endpointId){
   附近。getConnectionsClient(ctx)
       。requestConnection(endpointId,endpointId,connectionLifecycleCallback)
        。addOnSuccessListener(new  OnSuccessListener < Void >(){
            @覆盖
            public  void  onSuccess(Void  aVoid){
               记录。d(TAG,“请求连接......”);
            }
        })
       。addOnFailureListener(new  OnFailureListener(){
            @覆盖
            public  void  onFailure(@NonNull  Exception  e){
               记录。e(TAG,“请求连接时出错”,e);
         }
  });
}

在此方法中,Discoverer使用endpointId 上一步中发现的连接请求新连接 。此外,它还添加了一个新的回调接口,以了解何时建立连接或出现错误。

private  ConnectionLifecycleCallback  connectionLifecycleCallback  = 
  新的 ConnectionLifecycleCallback(){
    @覆盖
    public  void  onConnectionInitiated(String  s,ConnectionInfo  connectionInfo){
       记录。i(标签,“连接到端点[” + s + “]”);
       NearbyDsvManager。这个。currentEndpoint  =  s ;
       附近。getConnectionsClient(ctx)。acceptConnection(s,payloadCallback);
   }
   @覆盖
   public  void  onConnectionResult(String  s,ConnectionResolution  connectionResolution){
     开关(connectionResolution。的getStatus()。getStatusCode()){
          大小写 ConnectionsStatusCodes。STATUS_OK:
             听众。onConnected();
             打破 ;
          大小写 ConnectionsStatusCodes。STATUS_CONNECTION_REJECTED:
             记录。我(标签,“拒绝连接”);
             打破 ;
          大小写 ConnectionsStatusCodes。STATUS_ERROR:
              记录。我(标签,“连接错误”);
               打破 ;
       }
   }
   @覆盖
   public  void  onDisconnected(String  s){}
};

建立连接并且双方都接受了连接后,该过程结束并且应用程序已准备好发送数据。这是将有效负载从Android应用程序发送到Android Things应用程序的方法:

public  void  sendData(String  data){
   记录。i(TAG,“发送数据[” + 数据+ “]”);
   记录。i(TAG,“Current endpoint [” + currentEndpoint + “]”);
   if(currentEndpoint  !=  null){
      记录。d(TAG,“将数据发送到[” + data + “]”);
      有效 负载 =  有效负载。fromBytes(数据。的getBytes());
      附近。getConnectionsClient(ctx)。sendPayload(currentEndpoint,payload);
    }
}

就这样。

实现Android App UI

最后一步实现Android应用程序UI,以便用户可以插入有效负载并将其发送到Android Things应用程序(Nearyby广告商)。用户界面非常简单:

<?xml  version =“1.0”encoding =“utf-8”?>
< android.support.constraint.ConstraintLayout 
    xmlns:android = “http://schemas.android.com/apk/res/android”
    xmlns:app = “http://schemas.android.com/apk/res-auto”
    xmlns:tools = “http://schemas.android.com/tools”
    android:layout_width = “match_parent”
    android:layout_height = “match_parent”
    tools:context = “。MainActivity” >
    < TextView
        android:layout_width = “wrap_content”
        android:layout_height = “wrap_content”
        android:text = “内容”
        app:layout_constraintLeft_toLeftOf = “parent”
        app:layout_constraintTop_toTopOf = “parent”
        android:layout_marginTop = “8dp”
        android:id = “@ + id / txt” />
    < EditText
        android:layout_width = “wrap_content”
        android:layout_height = “wrap_content”
        android:提示 = “文字在这里”
        android:maxLength = “40”
        android:id = “@ + id / ed”
        app:layout_constraintTop_toBottomOf = “@ id / txt”
        android:layout_marginTop = “8dp” />
    < 按钮
        android:layout_width = “wrap_content”
        android:layout_height = “wrap_content”
        app:layout_constraintBottom_toBottomOf = “parent”
        app:layout_constraintLeft_toRightOf = “parent”
        app:layout_constraintRight_toLeftOf = “parent”
        android:id = “@ + id / btn”
        android:text = “发送” />
</ android.support.constraint.ConstraintLayout >

最后:

@覆盖
protected  void  onCreate(Bundle  savedInstanceState){
   超。onCreate(savedInstanceState);
   的setContentView(ř。布局。activity_main);
   BTN  =  findViewById(ř。ID。BTN);
   等 =(的EditText)findViewById(ř。ID。编);
   btn。setOnClickListener(新 景观。OnClickListener(){
     @覆盖
     public  void  onClick(查看 v){
        String  txt  =  et。getText()。toString();
        记录。d(TAG,“Txt [” + txt + “]”);
        dsvManager。sendData(txt);
      }
   });
}

将LCD显示器连接到Android Things

此步骤是可选的,因为它描述了如何将LCD显示器连接到Android Things以显示从Android应用程序发送的内容有效负载。这个Android Things教程使用了Hd44780 LCD。更多细节,这款LCD基于HD44780芯片和PCF8574。有几个版本具有不同的显示尺寸,这个例子中的一个是20×4。这是一个I2C外设,使用四个不同的引脚连接到Android Things板:

• Vcc(+ 5V)
• GND
• SDA
• CLK
连接架构如下图所示:


0000.png

要管理此LCD,必须导入驱动程序。让我们将此行添加到build.gradle:

实现 'com.leinardi.android.things:driver-hd44780:<version>'

此外,有必要创建一个新类来处理LCD连接细节和显示数据的所有步骤

公共 类 ManageLCD {
私人 Hd44780  mLcd ;
public  void  displayString(data){
   尝试 {
     记录。d(“LCd”,“写作”);
     if(mLCD  ==  null)
       MLCD   =  新 HD44780(“I2C1” ,0×27,HD44780。几何图形。LCD_20X4);
     mLcd。setBacklight(true);
     mLcd。cursorHome();
     mLcd。clearDisplay();
     mLcd。setText(data);
    } catch(例外 e){
      e。printStackTrace();
    }
  }
}

MainActivity当收到新的有效负载时,您必须在Android Things应用程序中调用此类。

摘要

最后,本文展示了如何使用Android Nearby连接不同的Android设备。本教程使用Android Nearby连接Android应用和Android Things应用,以便他们可以交换数据。此外,Android Things使用连接到它的LCD来显示来自Android应用程序的有效负载。希望您获得有关如何使用Android Nearby Advertiser和Discoverer以及如何按照Android Nearby规范连接它们的知识。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容