【发布时间】: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