Ionic build cannot find module 错误。如何导入Android插件?

Ionic build cannot find module error. How to import Android plugin?

我正在尝试开发一个 Android 插件以在 Ionic 应用程序中使用。

我使用 Ionic 使用 ionic start myApp tabs 提供的入门项目创建了应用程序。

我还在另一个文件夹中创建了我的插件,其中包含以下文件。

plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="location-plugin" version="0.0.1">
<name>GSLocationManager</name>
<description>Location Plugin</description>
<license>MIT</license>
<keywords>cordova,device,sensors,location</keywords>

<js-module name="LocationManager" src="www/LocationManager.js">
    <clobbers target="LocationManager" />
</js-module>

<engines>
    <engine name="cordova" version=">=3.6.0"></engine>
</engines>

<platform name="android">
  <preference name="GOOGLE_PLAY_SERVICES_VERSION" default="11+"/>
  <preference name="ANDROID_SUPPORT_LIBRARY_VERSION" default="26+"/>
  <preference name="ICON" default="@mipmap/icon" />
  <preference name="SMALL_ICON" default="@mipmap/icon" />
  <preference name="ACCOUNT_NAME" default="@string/app_name" />
  <preference name="ACCOUNT_LABEL" default="@string/app_name" />
  <preference name="ACCOUNT_TYPE" default="$PACKAGE_NAME.account" />
  <preference name="CONTENT_AUTHORITY" default="$PACKAGE_NAME" />

  <framework src="com.google.android.gms:play-services-location:$GOOGLE_PLAY_SERVICES_VERSION" />
  <framework src="com.android.support:support-v4:$ANDROID_SUPPORT_LIBRARY_VERSION" />
  <framework src="com.android.support:appcompat-v7:$ANDROID_SUPPORT_LIBRARY_VERSION" />
  <!-- <framework src="android/dependencies.gradle" custom="true" type="gradleReference"/> -->

  <source-file src="path/to/locationmanager/GSLocationManager.java"
               target-dir="path/to/locationmanager"></source-file>

  <config-file target="AndroidManifest.xml" parent="/manifest">
     <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
     <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.hardware.location" />
  </config-file>

  <config-file target="res/xml/config.xml" parent="/*">
      <feature name="GSLocationManager">
          <param name="android-package" value="android.package.locationmanager.GSLocationManager" />
      </feature>
  </config-file>
</platform>

locationManager.js

var GSLocationManager = {
  getCurrentLocation: function(success, failure) {
    exec(success, failure, 'GSLocationManager', 'getCurrentLocation', []);
  }
}

module.exports = GSLocationManager;

GSLocationManager.java

package android.package.locationmanager;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;

import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;

public class GSLocationManager extends CordovaPlugin {

    private JSONObject data = new JSONObject();

    // at the initialize function, we can configure the tools we want to use later, like the sensors
    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);

    }

    // safety unregistering from the events if the application stops somehow
    @Override
    public void onDestroy() {

    }

    // this is the main part of the plugin, we have to handle all of the actions sent from the js
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("getCurrentLocation".equals(action)) {
            Location location = getCurrentLocation();
            JSONObject json = new JSONObject();
            json.put("latitude", location.getLatitude());
            json.put("longitude", location.getLongitude());
            callbackContext.success(json);
            return true;
        }
        return false;  // Returning false results in a "MethodNotFound" error.
    }

    @SuppressLint("MissingPermission")
    private Location getCurrentLocation() {
        LocationManager locationManager = (LocationManager) cordova.getActivity().getApplicationContext().getSystemService(Context.LOCATION_SERVICE);

        Location lastKnownGPSLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        return lastKnownGPSLocation;
    }
}

然后我为我的插件创建了一个 package.json plugman 之后,将我的 android 插件添加到我的 Ionic 项目中 ionic cordova plugin add path/to/my/plugin

但我似乎无法使用 import { GSLocationManager } from 'globespinning-location-plugin' 将我的插件导入 app.module.ts 我尝试构建,但 CLI 显示 ERROR in src/app/app.module.ts(12,31): error TS2307: Cannot find module 'globespinning-location-plugin'.

知道错误在哪里吗? 我应该如何导入由我创建并从本地文件夹引用的插件? 我希望能够在我的离子应用程序中调用 GSLocationManager.getCurrentLocation()

如果导入失败,这很可能与您的 tsconfig.json 或 angular 模块 (app.module.ts) 有关。检查文件是否包含在内。

您只发布了您的 Java- 文件。您确定这可以在浏览器上运行吗?

你想继续 运行 ionic cordova plugin add "folder path of your custom plugin" 然后在 .ts 文件中你想在你想要声明以下内容时使用它,declare var myPlugin: any;

声明插件后,您可以继续使用它,如下所示:

myPlugin.myFuntion((data) => {
        console.log(data);
},(err) => {
        console.log(err);
});

因此在您的情况下,您将使用以下内容:

declare var GSLocationManager: any;

....

GSLocationManager.getCurrentLocation().then((data) => {});

除了的回答外,还有一些需要注意的地方。

  • 您需要为您的插件 js 创建一个声明 (.d.ts) 文件,然后才能使用 import * from * syntax。在这种情况下不需要。
  • 检查您是否准确定义了 js 方法的命名空间。你的在这里 <clobbers target="LocationManager" />

因此,下面是如何在您的情况下实施此类操作;

在您希望执行的 .TS 文件中执行函数

// at the top of the file. after all the import statements
import { Component } from '@angular/core';  // i'm using this as an example.
import { Platform } from '@ionic/angular';  // you need the platform

declare var LocationManager;
...
constructor(
private platform: Platform
){
  this.platform.ready().then(() => {
   // we will make use of the plugin here
   console.log('LocationManager: ', LocationManager); // we can check if it exist by logging it out to the console
   if (LocationManager) {
      LocationManager.GSLocationManager.getCurrentLocation(
         success => {
            console.log('LocationManager: Got Location: ', success);
         }, error => {
            console.log('LocationManager: Err Getting Location: ', error);
         }
      );
    }
  });
}

您可以在此处阅读更多内容: , https://cordova.apache.org/docs/en/latest/plugin_ref/spec.html

@Tachyon 和@SeunBincom 的回答很有帮助,但问题出在我的 plugin.xml 文件上。在 Android Studio 的帮助下,我能够调试它并最终让它工作。

xml的结局是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
        id="globespinning-location-plugin" version="0.0.1">
    <name>LocationManager</name>
    <description>Globespinning Location Plugin</description>
    <license>MIT</license>
    <keywords>cordova,device,sensors,location</keywords>

    <js-module name="LocationManager" src="www/locationManager.js">
        <clobbers target="LocationManager" />
    </js-module>

    <platform name="android">
      <preference name="GOOGLE_PLAY_SERVICES_VERSION" default="11+"/>
      <preference name="ANDROID_SUPPORT_LIBRARY_VERSION" default="26+"/>
      <preference name="ICON" default="@mipmap/icon" />
      <preference name="SMALL_ICON" default="@mipmap/icon" />
      <preference name="ACCOUNT_NAME" default="@string/app_name" />
      <preference name="ACCOUNT_LABEL" default="@string/app_name" />
      <preference name="ACCOUNT_TYPE" default="$PACKAGE_NAME.account" />
      <preference name="CONTENT_AUTHORITY" default="$PACKAGE_NAME" />

      <framework src="com.google.android.gms:play-services-location:$GOOGLE_PLAY_SERVICES_VERSION" />
      <framework src="com.android.support:support-v4:$ANDROID_SUPPORT_LIBRARY_VERSION" />
      <framework src="com.android.support:appcompat-v7:$ANDROID_SUPPORT_LIBRARY_VERSION" />
      <framework src="src/android/dependencies.gradle" custom="true" type="gradleReference"/>

      <source-file src="src/android/com/globespinning/ionic/locationmanager/GSLocationManager.java"
                   target-dir="src/com/globespinning/ionic/locationmanager"></source-file>

      <config-file target="AndroidManifest.xml" parent="/manifest">
         <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
         <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
         <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
         <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
         <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
         <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
         <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
         <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
         <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
         <uses-permission android:name="android.permission.INTERNET" />
         <uses-permission android:name="android.permission.WAKE_LOCK" />
         <uses-permission android:name="android.hardware.location" />
      </config-file>

      <config-file target="res/xml/config.xml" parent="/*">
          <feature name="LocationManager">
              <param name="android-package" value="com.globespinning.ionic.locationmanager.GSLocationManager" />
          </feature>
      </config-file>
    </platform>
</plugin>