【问题标题】:Ionic build cannot find module error. How to import Android plugin?离子构建找不到模块错误。如何导入安卓插件?
【发布时间】:2019-02-14 23:32:03
【问题描述】:

我正在尝试开发一个用于 Ionic 应用程序的 Android 插件。

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

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

插件.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'.

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

【问题讨论】:

    标签: android angular cordova ionic-framework ionic4


    【解决方案1】:

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

    一旦您声明了插件,您就可以继续使用它,如下所示:

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

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

    declare var GSLocationManager: any;
    
    ....
    
    GSLocationManager.getCurrentLocation().then((data) => {});
    

    【讨论】:

      【解决方案2】:

      除了@tachyon的回答,还有一些注意事项。

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

      因此,以下是在您的情况下如何实施;

      在.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);
               }
            );
          }
        });
      }
      

      您可以在此处阅读更多内容: How to use a plugin without using ionic-native?, https://cordova.apache.org/docs/en/latest/plugin_ref/spec.html

      【讨论】:

        【解决方案3】:

        @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>
        

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

          • 我只发布了 1 个 java 文件。我发布了我的插件文件。我不确定js文件是否正确。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-22
          • 1970-01-01
          • 2017-07-20
          • 2018-05-25
          • 1970-01-01
          • 2021-11-21
          相关资源
          最近更新 更多