【问题标题】:Android Geofencing in Nativescript. Background Event causes java.lang.RuntimeException: Unable to instantiate receiverNativescript 中的 Android 地理围栏。后台事件导致 java.lang.RuntimeException:无法实例化接收器
【发布时间】:2019-09-24 06:57:06
【问题描述】:

所以我的目标是创建一个 nativescript 插件,允许开发人员在任何地方设置地理围栏,即使用户关闭(刷掉)应用程序也会触发。当应用程序位于前台或应用程序只是隐藏时,我有一个工作示例。 即使应用程序完全关闭,我也成功接收到触发事件,但这会导致以下异常:

n 未捕获的异常发生在“主”线程上。 无法实例化接收器 carTabako.GeofenceBroadcastReceiver:com.tns.NativeScriptException:无法为“carTabako/GeofenceBroadcastReceiver”类创建 JavaScript 扩展包装器

StackTrace:
java.lang.RuntimeException: Unable to instantiate receiver carTabako.GeofenceBroadcastReceiver: com.tns.NativeScriptException: Failed to create JavaScript extend wrapper for class 'carTabako/GeofenceBroadcastReceiver'
    at android.app.ActivityThread.handleReceiver(ActivityThread.java:3489)
        at android.app.ActivityThread.access$1400(ActivityThread.java:207)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1759)
                at android.os.Handler.dispatchMessage(Handler.java:106)
                    at android.os.Looper.loop(Looper.java:193)
                        at android.app.ActivityThread.main(ActivityThread.java:6863)
                            at java.lang.reflect.Method.invoke(Native Method)
                                at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
                                    Caused by: com.tns.NativeScriptException: Failed to create JavaScript extend wrapper for class 'carTabako/GeofenceBroadcastReceiver'
                                        at com.tns.Runtime.createJSInstanceNative(Native Method)
                                            at com.tns.Runtime.createJSInstance(Runtime.java:777)
                                                at com.tns.Runtime.initInstance(Runtime.java:750)
                                                    at carTabako.GeofenceBroadcastReceiver.<init>(GeofenceBroadcastReceiver.java:13)
                                                        at java.lang.Class.newInstance(Native Method)
                                                            at android.app.AppComponentFactory.instantiateReceiver(AppComponentFactory.java:84)
                                                                at androidx.core.app.CoreComponentFactory.instantiateReceiver(CoreComponentFactory.java:56)
                                                                    at android.app.ActivityThread.handleReceiver(ActivityThread.java:3482)
                                                                        ... 8 more

我怀疑两个 AndroidManifest.xml 文件之一存在问题,因为 application-name/App_resources/Android/src/AndroidManifest.xml 下的实际应用程序存在一个问题 然后有一个只用于插件:src/platforms/android/AndroidManifest.xml

这是(演示)应用程序清单的相关部分,我从 nativescript(demo-angular)克隆:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

<application
    android:name="com.tns.NativeScriptApplication"
    android:allowBackup="true"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">

    <activity
        android:name="com.tns.NativeScriptActivity"
        android:label="@string/title_activity_kimera"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode"
        android:theme="@style/LaunchScreenTheme">

        <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name="com.tns.ErrorReportActivity"/>
            <!-- GEOFENCING Receiver    -->
    <receiver
        android:name="carTabako.GeofenceBroadcastReceiver"
        android:enabled="true"
        android:exported="true" />
</application>

这是插件的清单:

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    <application>
           <receiver
            android:name="carTabako.GeofenceBroadcastReceiver"
            android:enabled="true"
            android:exported="true" />
   </application>
</manifest>

如您所见,我已经在玩插件清单了。我注册了两次接收器,这没有任何区别。我仍然不确定最终哪个清单是相关的,因为没有关于它的明确文档。 我很想听听您的想法,我的问题可能来自哪里以及如何解决它。

编辑:这是我的 BroadcastReceiver 的实现: 如果事件在后台触发/关闭时,它有很多日志记录和文件创建系统来跟踪。

module carTabako {

        @JavaProxy("carTabako.GeofenceBroadcastReceiver")
        export class GeofenceBroadcastReceiver extends android.content.BroadcastReceiver {

            public onReceive(context, intent) {

                console.log("INTENT IN Receiver: ", intent);
                let geofencingEvent =  com.google.android.gms.location.GeofencingEvent.fromIntent(intent);
                if (geofencingEvent.hasError()) {
                    console.log("Error with the geofencing Event: "+geofencingEvent.getErrorCode());
                    return;
                }
                const directory = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
                const path1 = path.join(directory.toString(), "Geofences");
                const folder = Folder.fromPath(directory);

                let file = folder.getFile("geofenceFile"+ new Date().toString());
                        file.writeText("some random content;" + intent)
                            .then(result => {
                                file.readText()
                                    .then(res => {
                                        console.log("Successfully saved in " + file.path);
                                        console.log("read file: " + file.readTextSync());
                                    });

                            }).catch(err => {
                                console.log(err);
                            });
                let geofenceTransition = geofencingEvent.getGeofenceTransition();
                dialogs.alert(""+ geofencingEvent).then(()=> {
                    console.log("Dialog closed!");
                });
                if (geofenceTransition == com.google.android.gms.location.Geofence.GEOFENCE_TRANSITION_ENTER) {

                    // Get the geofences that were triggered. A single event can trigger
                    // multiple geofences.
                    let triggeringGeofences = geofencingEvent.getTriggeringGeofences();

                    // Get the transition details as a String.
                    let geofenceTransitionDetails =  triggeringGeofences.toString();

                    console.log("Transition received: ", geofenceTransitionDetails);
                } else {
                    console.log("event with no interest for us received");
                }
            }
        }
}

【问题讨论】:

  • 你能展示你的 GeofenceBroadcastReceiver 实现吗?
  • @Manoj 我更新了问题。仅供参考:一切都在同一个文件 geolocation.android.ts
  • 你是否在 webpack 配置中包含了这个文件 geolocation.android.ts
  • 所以插件代码没有我能找到的 webpack 配置。我没有在主应用程序的 webpack.config 中包含任何内容。我应该将它包含在主应用程序的某个位置吗?
  • 你能展示你的插件源结构吗?你有 Git 仓库吗?要回答有关 webpack 配置的问题,通常您会要求用户在他的 webpack 配置中进行,作为插件设置的一部分。

标签: android geolocation nativescript background-process geofencing


【解决方案1】:

所以我解决了。 非常感谢@Manoj,他用他的提示将它添加到 webpack.config.js 中救了我

对于找到此主题的人: 你必须像这样将它添加到主插件的 webpack.config.js 中:

const appComponents = [
    "tns-core-modules/ui/frame",
    "tns-core-modules/ui/frame/activity",
    "nativescript-geolocation"
];

只是添加 geolocation.android 并没有帮助,因为 nativescript 的插件中有相当多的依赖项。如果文件是完全独立的,那应该没问题。

之后,我在启动应用程序时遇到了 java 空指针异常。这是由于在 geolocation.android.ts 中过早地(在任何功能之外)分配了 pendingIntent,这是地理围栏所必需的。我将它移到首先需要未决意图的函数中,然后 --> 完成 :)

再次感谢@Manoj

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多