设备重启后启动Phonegap插件

10

我正在开发一个混合的Phonegap应用程序,针对Android平台。该应用只使用了一个插件,而我也在同时开发该插件。这个插件具有三个功能:

  • 监听地理位置变化(前台和后台)
  • 设置半小时定时器来执行某些周期性任务
  • 监听推送消息。我使用pushy.me服务,并且所使用的代码遵循他们的文档

我曾经担心实现设备重启时应用程序会出现问题,但是通过在其他SO线程中找到的信息,实现起来非常容易。

package com.example.plugin;

import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaWebView;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.pm.PackageManager;
import android.app.Activity;

import android.content.Intent;

public class Rebooter extends BroadcastReceiver
{
 @Override
 public void onReceive(Context context, Intent intent) 
 {
  Intent i = new Intent(context, MyAppCordovaPlugin.class); 
  i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  context.startActivity(i);  
 }
}

我注册了重启接收器,如下所示:

<receiver android:enabled="true" android:name=".Rebooter" 
 android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
 <intent-filter>
  <action android:name="android.intent.action.BOOT_COMPLETED" />
  <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>
</receiver>

MyAppCordovaPlugin是我的应用程序/插件的入口点 - 它扩展了CordovaPlugin类。 这是我在那里做的

public class MyAppCordovaPlugin extends CordovaPlugin
{
 private Context context;

 public void initialize(CordovaInterface cordova, CordovaWebView webView) 
 {
  super.initialize(cordova, webView);
  this.context = cordova.getActivity().getApplicationContext();
  //setup pushy.me broadcast receiver
  //setup geolocation changes receiver
  //setup broadcast receiver for a half-hourly alarm
 } 

 @Override
 public void onResume(boolean multitasking) 
 {
  super.onResume(multitasking);
  //unregister background location change receiver, if present
  //switch geolocation to foreground mode. i.e. using
  //FusedLocationApi.requestLocationUpdates
 }

 @Override
 public void onPause(boolean multitasking) 
 {
  super.onPause(multitasking);
  //stop request for foreground location updates, if present
  //switch geolocation to background mode, i.e by
  //registering a broadcast receiver that listens for location change 
  //broadcasts
 } 

当我手动在我的Android 4.4.2测试设备上启动应用程序时,一切正常。例如:

  • 地理位置更改被检测到:无论是在前台还是在后台
  • 推送消息被接收。 再次在前/后台都可以
  • 半小时的闹钟起作用

当我检查正在运行的应用程序时,我发现它由一个服务 PushySocketService 和主进程 com.example.app 组成,标记为正在使用中。内存使用量相当可观。

当我重新启动手机时,我仍然会发现相同的服务和“主进程”正在运行。但是,对于主进程报告的内存使用情况要低得多。

最重要的是 - 应用程序无法接收推送消息并且不响应地理位置更改。这只有在我通过 main activity 启动应用程序之后才开始发生。

我肯定遗漏了什么 - 所以重新启动的应用程序不会自动启动其 main activity 吗?如果是这样,那么我的 Rebooter.onReceive 代码肯定有问题?

为了完整起见,我应该提到:

  • 插件.xml文件中仅静态声明了Pushy.me和Rebooter广播接收器。地理位置和闹钟广播接收器是从我的插件代码中动态注册的。
  • 我正在使用Phonegap CLI v6.4.2和JDK 7构建应用程序

显然我在这里做错了什么,非常感谢任何能够指导我正确方向的人。


你有没有尝试使用https://github.com/ToniKorin/cordova-plugin-autostart?它还指出:“将安装到SD卡上将防止应用程序在启动后自动启动。”@DroidOS - daserge
@AkshayTilekar,你能详细说明一下吗?我认为BroadcastReceiver.OnReceive事件是重新启动活动的逻辑位置。你似乎在建议其他事情。 - DroidOS
@daserge - 谢谢你的回复。我不能使用任何第三方插件,但我看了一下他们在那里做的事情。我很可能能够在我的自己的插件中实现类似的代码。 - DroidOS
@DroidOS 你好,你试过了吗?你能实现它吗? - Gandhi
@Gandhi - 我今天稍后会尝试复制那个插件中使用的技术。我会在适当的时候在这里回复。 - DroidOS
显示剩余4条评论
2个回答

3
如果你不想使用第三方插件来实现这个功能,那么你可以从cordova自动启动插件中借鉴逻辑。
你可以查看插件中的BootCompletedReceiver类。它在设备成功重新启动时调用,进而调用AppStarter辅助类来启动相应的应用程序。你也可以在你的插件中实现相同的逻辑。
希望能有所帮助。干杯!

尝试过这个方法 - 甚至尝试了使用插件。但它没有任何效果,而且不幸地导致我的应用在重新启动后无法接收推送消息。除去所有插件代码后,它只是创建一个带有“packageName.mainActivity.class”的意图。这样做是有效的,但似乎在我将应用程序置于前台之前并没有初始化应用程序使用的插件。 - DroidOS
DroidOS将进行检查并返回。 - Gandhi
据我所了解,问题在于 Cordova 插件在 CordovaWebView 创建之前不会初始化,而当应用程序通过引导接收器从 packageName.mainActivity.class 意图重新启动时,似乎并没有发生这种情况。鉴于我在自己的插件初始化代码中调整推送、启动闹钟、监视地理位置等,因此启动的应用程序在我手动将其带到前台之前什么也不做。 - DroidOS
@DroidOS 你好,看起来你的问题的解决方案可以在以下链接中找到 - https://github.com/ToniKorin/cordova-plugin-autostart/issues/15 请查看链接中jorantos的评论...它应该会给你一些线索。希望能帮到你。 - Gandhi
谢谢。我将在几天内发布所有这些问题的完整解决方案,以造福其他遇到这个线程的人。 - DroidOS
@DroidOS,感谢更新。完成后请发布,这样每个人都能受益。干杯 - Gandhi

1

Cordova插件

让我们看一下这段代码:

Intent i = new Intent(context, MyAppCordovaPlugin.class); 
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
  • CordovaPlugin 不是一个 Activity,不能像启动 Activity 一样启动它。
  • Cordova Android 应用程序是一个带有 WebView 的单一 Activity 应用程序,在 WebView 创建后才加载插件。您不需要真正启动应用程序界面来监听 GCM 消息或地理围栏事件。

Pushy.me

Pushy.me 文档 建议在应用程序清单中声明BroadcastReceiver。看起来Pushy也会为您处理引导事件。为什么不使用他们推荐的方法呢?

在启动后在后台运行东西

如上所述,initialize()回调中的代码仅在应用程序活动已启动时运行。但是您希望在引导完成事件之后在后台调用其中的一些代码。

我建议将“开始侦听后台事件”的逻辑移动到IntentService中,您可以从插件的initialize()和引导完成接收器启动该服务。


我正在为您的答案点赞,因为您强调了几个重要问题。显然,传递MyAppCordovaPlugin类是错误的。其次,鉴于我不仅想重新启动推送消息监听,还想重新启动其他一些东西 - 警报、地理位置等等 - 我根本不应该使用PushyMe引导接收器。 - DroidOS
我认为在一个应用程序中有两个BroadcastReceiver处理同一事件并不是问题,因此如何集成pushy.me取决于您的考虑。我更喜欢尽可能少地编写代码。无论如何,将警报、地理位置等的初始化移动到IntentService中应该可以解决您的问题。 - Yoni Gross

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接