我正在创建一个Phonegap插件,除其他外,它允许我设置闹钟。我对如何做到这一点的理解如下:
为此,这里是我写的代码:
plugin.xml 文件
<config-file target="res/xml/config.xml" parent="/*">
<feature name="Pall">
<param name="android-package" value="com.example.Plugin"/>
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name="com.example.plugin.ServiceAlarm"
android:enabled="true" android:exported="true" >
<intent-filter>
<action android:name="com.example.plugin.ServiceAlarm" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</config-file>
扩展广播接收器类 - 文件ServiceAlarm.java
import org.apache.cordova.CordovaWebView;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.widget.Toast;
public class ServiceAlarm extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
//in a real world app one would do a whole lot more here
}
}
定义插件 - 文件plugin.java
package com.example.plugin;
//various imports
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import ...
public class Plugin extends CordovaPlugin
{
private Context context;
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView)
{
super.initialize(cordova, webView);
this.context = cordova.getActivity().getApplicationContext();
}
public void makeToast(String msg)
{
Toast.makeText(this.context, msg, Toast.LENGTH_LONG).show();
}
private boolean setAlarm(final CallbackContext cbc,Context ctxt,JSONArray data)
{
try
{
makeToast("Setting alarm");
Intent intent = new Intent(ctxt,ServiceAlarm.class);
intent.setAction("com.example.plugin.ServiceAlarm");
PendingIntent pendingIntent =
PendingIntent.getBroadcast(ctxt,1,intent,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager =
(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 10000,pendingIntent);
makeToast("Alarm Set");
cbc.success("Set!");
return true;
} catch(Exception e)
{
cbc.error("Failed!");
return false;
}
}
跨越JS桥接的Catch方法调用:
@Override
public boolean execute(String action, JSONArray data, CallbackContext cbc)
throws JSONException
{
Context ctxt = this.context;
try
{
switch(action)
{
case "setalarm":return setAlarm(cbc,ctxt,data);
default:cbc.error(action + " is not known");return false;
}
}
catch (Exception e)
{
cbc.error(e.getMessage() + "xx");
return false;
}
}
}
定义Cordova JS桥。文件plugin.js:
var exec = require('cordova/exec');
var plugin =
{
setalarm:function (scbk, ecbk) {exec(scbk, ecbk, "Plugin", "setalarm",
[]);}
};
module.exports = plugin;
完成所有这些后,我使用jquery-mobile-starter模板在Phonegap CLI中创建了一个Phonegap项目:
phonegap create /path/to/project --template jquery-mobile-starter
然后我添加了插件:
phonegap plugin add /path/to/plugin
然后我修改了init
中的app.js
方法:
function init()
{
alert('Init');
try
{
alert('setting alarm');
plugin.setalarm(success,failure);
alert('alarm set');
} catch(e){alert('error' + e.message);}
}
function success(msg){alert(msg);}
function failure(msg){alert('Error ' + msg);}
据我所知,我已完成以下所有工作:
init
方法设置闹钟该应用程序正确遵守,并在启动时启动我编码的所有各种诊断吐司。但是,从不响应实际的警报事件。
显然,我在这里做错了或者误解了系统如何处理警报。对于任何能够让我走上正轨的人,我都是最有责任的。
+++++++++++++
自发布此问题以来,我发现如果我动态注册广播接收器,事情就会按预期工作。
final String SOME_ACTION = "com.example.plugin.ServiceAlarm";
IntentFilter intentFilter = new IntentFilter(SOME_ACTION);
ServiceAlarm mReceiver = new ServiceAlarm(this.context);
ctxt.registerReceiver(mReceiver, intentFilter);
Intent intent = new Intent(SOME_ACTION);
这里的明显区别是,不是将ServiceAlarm 类传递给Intent构造函数,而是传递ServiceAlarm对象本身的实例。
事实上,这是非常令人欣慰的,但它留下了一个问题 - 我遇到了许多以“其他方式”做事的例子,即我原来的方式。它们是错误的还是我的代码中某处出现错误 - 例如config.xml文件中的Receiver声明。
我希望这里有人能够发现这个问题。
答案 0 :(得分:0)
问题必须在plugin.xml中。 接收者必须是应用的孩子。可以通过将接收器移动到 应用程序 父
来分离配置文件来解决此问题:<config-file target="AndroidManifest.xml" parent="/*/application">
<receiver android:name="com.example.plugin.ServiceAlarm" >
<intent-filter>
<action android:name="com.example.plugin.ServiceAlarm" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</config-file>