如何在ionic 3中使用cordova插件蓝牙?

Posted

技术标签:

【中文标题】如何在ionic 3中使用cordova插件蓝牙?【英文标题】:How to use the cordova plugin bluetoothle in ionic 3? 【发布时间】:2018-06-06 05:24:07 【问题描述】:

其他信息:

我知道常用的 way 来访问cordova 插件:

(<any>window).plugins.myPlugin 

or

declare var yourGloballyAccessablePlugin: any;

但插件 bluetoothle 不同(ionic 3 支持的原生蓝牙插件不够好,因为它们不提供蓝牙外设功能,例如广告)

解决方案尝试:

I found a related question on the ionic forums and asked how they achieved this,到目前为止我未能复制该过程,并且到目前为止没有人回答我的问题,这就是为什么这个问题被打开了。

显然蓝牙公开了一个全局可访问的变量。

如上所述,我将declaration.d.ts 文件添加到我的src 文件夹中 内容如下:

declare module 'cordova-plugin-bluetoothle';
import 'cordova-plugin-bluetoothle';
declare var cordova: any;

然后我尝试像这样访问插件(在我的手机上测试过):

import  bluetoothle  from 'cordova-plugin-bluetoothle';

...

(<any>window).bluetoothle

问题:

但蓝牙对我来说总是未定义。由于我是cordova、ionic和TypeScript的新手,我猜我使用declarations.d.ts的方式有问题

那么有人知道我在做什么错吗,如何在ionic 3中使用cordova原生插件蓝牙?

更新,解决方案尝试 2

因此,我尝试按照@Webruster 的建议,使用蓝牙documentation 中的初始化参数在初始项目结构app.component.ts 中运行此代码:

(这里唯一的目的就是看插件是否有效)

进口...

declare var cordova: any;

@Component、类开始和属性...

  constructor(private translate: TranslateService, platform: Platform, settings: Settings, private config: Config, private statusBar: StatusBar, private splashScreen: SplashScreen) 
    platform.ready().then(() => 
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      console.log("I'm ready");
      // your bluetothle methods can be accessed after
      //cordova.plugins.bluetoothle
      // for brevity i added a sample method from repo , it can be changed
      //based on your need
      let initializeResult: object;
      let params: object = 
        "request": true,
        "statusReceiver": false,
        "restoreKey": "bluetoothleplugin"
      ;
      cordova.plugins.bluetoothle.initialize(initializeResult, params);

      console.log(JSON.stringify(initializeResult));

      this.statusBar.styleDefault();
      this.splashScreen.hide();
    );
    this.initTranslate();
  

但是这样应用程序甚至不会加载,当我在没有插件代码的情况下运行应用程序时,它只是超时并输出到服务器的连接不成功。

更新 2:

我用 chrome 调试了应用程序(之前的错误是由 --livereload 选项引起的,原因不明) 这是我得到的错误:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'initialize' of undefined
TypeError: Cannot read property 'initialize' of undefined

检查cordovacordova.pluginscordova.plugins.bluetoothle的类型 与:

  console.log(typeof cordova);
  console.log(typeof cordova.plugins);
  console.log(typeof cordova.plugins.bluetoothle);

我得到以下结果:

object
object
undefined

【问题讨论】:

澄清一下,我不一定需要将应用程序(我为我的学生项目开发的)移植到智能手机上,但因为我可以重用我的大部分代码(因为它是用 angular 5 编写的),这将很高兴有扩展 有几个问题,1.你的离子初始化代码在哪里?你在哪里调用这个方法?在app.component.ts ? 我使用了 Ionic 3 的默认启动应用程序,并尝试在平台准备好后立即访问插件,例如在构造函数中注入平台,然后在构造函数中访问它,如下所示:this.platform.isReady().then((params) => ... 在此处访问插件。是的,我的意思是 app.component.ts 组件. 有人能告诉我为什么我的问题被认为没有用或研究不足吗? 不介意响应.. +1 用于更新进程尝试 【参考方案1】:

经过更多时间的研究,我发现有 4 种方法可以做到这一点(改进我之前的回答):

    如果您不需要包装每个插件方法(很多都缺少),请在此处使用插件包装器:https://github.com/somq/ionic-plugin-bluetoothle

    在代码中的任何位置使用(&lt;any&gt;window).bluetoothle.method name(arguments);。这很好用,但会导致 Ionic View 崩溃。

    在文件顶部使用declare var bluetoothle;,然后您可以通过:bluetoothle.method name(arguments); 访问插件。效果很好,但也会导致 Ionic View 崩溃。

    复制现有的包装器插件,并将其作为提供者添加到您自己的源代码中,然后只需包装您需要使用的其余方法。要复制的文件在这里:https://github.com/somq/ionic-plugin-bluetoothle/blob/master/src/%40ionic-native/plugins/bluetooth-le/index.ts。关于如何包装插件的指南在这里:http://www.damirscorner.com/blog/posts/20170908-WritingAnIonicNativeWrapper.html

4 是最干净的解决方案,如果您像我一样需要比 somq 在他的项目中完成的更多的方法。这个方法会阻止 Ionic View 崩溃,但事实证明该插件无论如何都不支持,所以你仍然不能在 Ionic View 中使用它。

【讨论】:

【参考方案2】:

您可以在此处使用此插件的包装器:https://github.com/somq/ionic-plugin-bluetoothle。

然而,虽然这是使用插件的好方法,但它并没有包装所有方法,因此不能满足我的需要。如果它有你需要的方法,那么我推荐使用它。

我的主要建议是使用 (<any>window).bluetoothle.method name 正如之前的海报所描述的那样。在这里描述的所有技术中,这是唯一对我有用的一种。

希望对阅读本帖的人有所帮助。

【讨论】:

【参考方案3】:

首先安装插件(ionic3):

ionic cordova plugin add cordova-plugin-bluetoothle

然后在平台准备好访问基于ionic forum 上的@dinomight 帖子的通常位置(cordova.plugins)的插件时使用(&lt;any&gt;window).bluetoothle

窗口对象似乎正在加载蓝牙模块。如果我 console.log(window) 我可以在那里看到它的所有内容 职能。问题是如果我尝试通过 “window.bluetoothle”我收到一个新错误

这里是测试代码(只有构造函数,因为我没有修改其他任何东西)提示您激活蓝牙(仅在 android 上支持)并在允许后激活它(代码位于扩展 ionic3 starter 应用的component.app.ts 中):

  constructor(private translate: TranslateService, platform: Platform, settings: Settings, private config: Config, private statusBar: StatusBar, private splashScreen: SplashScreen) 
    platform.ready().then(() => 

      let initializeResult: object;
      let params: object = 
        "request": true,
        "statusReceiver": false,
        "restoreKey": "bluetoothleplugin"
      ;

      (<any>window).bluetoothle.initialize(initializeResult, params);

      let enableSuccess: object;
      let enableError: object;

      (<any>window).bluetoothle.enable(enableSuccess, enableError);

      this.statusBar.styleDefault();
      this.splashScreen.hide();
    );
    this.initTranslate();
  

测试环境:

我在 Nexus 5 上的 Android 7.1.1 (lineageOS) 上对此进行了测试

【讨论】:

它和我定义的一样,而不是cordova,你定义了任何类型的windows对象。任何方式都可以帮助你 我知道,我给了你赏金,因为我得到了我想要的【参考方案4】:

在您希望使用插件消除 IDE 错误的每个页面的顶部添加此行:

声明 var bluetoothle: any;

【讨论】:

【参考方案5】:

就像正常方式一样,您可以使用以下方式安装它:

ionic plugin add cordova-plugin-bluetoothle

在您的导入语句之后包括以下行,如下所示:

declare var cordova:any;

并在平台准备好时使用它:

platform.ready().then(
    () => 
        console.log("I'm ready");
        // your bluetothle methods can be accessed after 
        //cordova.plugins.bluetoothle
        // for brevity i added a sample method from repo , it can be changed 
        //based on your need
        cordova.plugins.bluetoothle.initialize(initializeResult, params);
    
);

【讨论】:

你测试了吗?我以为我试过了(如我在问题下的评论中所述),我稍后会对其进行测试并报告。 @MADforFUNandHappy 我通常运行这样的插件,这些插件不在 ionic native 中,您实现的插件使用的是 MODULAR 模型,所以这是一种 javascript 方法 我不得不使用 ionic cordova plugin add cordova-plugin-bluetoothle,因为我使用的是 ionic3,我尝试了你的示例并添加了 init 参数,但是当应用程序加载到我的nexus 5 ...我将代码添加到我的问题中,也许我做错了什么。 我尝试调试它,不知道我可以用 chrome 做到这一点 @MADforFUNandHappy 尝试获取控制台日志【参考方案6】:

第 1 步: 我们必须导入这个插件

ionic cordova plugin add cordova-plugin-bluetooth-serial
npm install --save @ionic-native/bluetooth-serial

第 2 步: 在提供程序 app.module.ts 页面中添加 BluetoothSerial 第 3 步: 启用蓝牙 您的移动蓝牙会自动开启或征求您的许可。

      unpairedDevices: any;
      pairedDevices: any;
      gettingDevices: Boolean;
    constructor(private bluetoothSerial: BluetoothSerial,
     private alertCtrl: AlertController) 
    bluetoothSerial.enable();
  

第四步:开始扫描

    startScanning() 
    this.pairedDevices = null;
    this.unpairedDevices = null;
    this.gettingDevices = true;
    this.bluetoothSerial.discoverUnpaired().then((success) => 
      this.unpairedDevices = success;
      console.log(success, "hai")
      this.gettingDevices = false;
      success.forEach(element => 
        // alert(element.name);
      );
    ,
      (err) => 
        console.log(err);
      )

    this.bluetoothSerial.list().then((success) => 
      this.pairedDevices = success;
    ,
      (err) => 

      )
  
  success = (data) => alert(data);
  fail = (error) => alert(error);

第 5 步:检测到可用的蓝牙设备后,选择其中任何一个 那些。

 selectDevice(address: any) 

    let alert = this.alertCtrl.create(
      title: 'Connect',
      message: 'Do you want to connect with?',
      buttons: [
        
          text: 'Cancel',
          role: 'cancel',
          handler: () => 
            console.log('Cancel clicked');
          
        ,
        
          text: 'Connect',
          handler: () => 
            this.bluetoothSerial.connect(address).subscribe(this.success, this.fail);
          
        
      ]
    );
    alert.present();

  

第 6 步:断开设备

isconnect() 
let alert = this.alertCtrl.create(
  title: 'Disconnect?',
  message: 'Do you want to Disconnect?',
  buttons: [
    
      text: 'Cancel',
      role: 'cancel',
      handler: () => 
        console.log('Cancel clicked');
      
    ,
    
      text: 'Disconnect',
      handler: () => 
        this.bluetoothSerial.disconnect();
      
    
  ]
);
alert.present();

第 7 步:home.html 页面

    <ion-content padding>

 <ion-list padding>
  <button ion-button block (click)="startScanning()">scan</button>
  <ion-list-header>
    Paired Devices
  </ion-list-header>
  <ion-item *ngFor="let device of pairedDevices">
    device.name
  </ion-item>
  <button ion-button block (click)="disconnect()">Disconnect</button>
  <ion-list-header>
    availlable Devices
  </ion-list-header>
  <ion-item *ngFor='let device of unpairedDevices'>
    <span (click)="selectDevice(device.address)">
      device.name
    </span>
  </ion-item>
  <ion-spinner name="crescent" *ngIf="gettingDevices"></ion-spinner>
</ion-list>

</ion-content>

注意:我希望你会这样。 祝你有美好的一天!。

【讨论】:

我认为这是一个误解,我指的是 Cordova 插件蓝牙,它提供了使用蓝牙适配器作为中心和外围设备的可能性。 ionic native提供的蓝牙插件只支持蓝牙中枢功能。 看看我的问题中的蓝牙链接,它是另一个不受离子原生支持的插件,不能以通常的方式使用,在离子原生中可以访问科尔多瓦插件。

以上是关于如何在ionic 3中使用cordova插件蓝牙?的主要内容,如果未能解决你的问题,请参考以下文章

Ionic - 如何检查蓝牙状态变化

无法从 Objective C 插件返回到 Ionic/Cordova 应用程序时出错

Ionic/Cordova:如何将插件安装到现有项目中?

Ionic2使用第三方cordova插件(非Ionic2官方支持的native cordova插件)

如何在ionic 4项目中导入和使用自定义cordova插件

如何在 Cordova 应用程序中使用 iPhone 上的蓝牙?