2

Ich bin gerade dabei, ein Phonegap Plugin zu erstellen, mit dem ich unter anderem einen Alarm einstellen kann. Mein Verständnis davon, wie dies getan werden soll, ist wie folgt:Nicht reagierender Android BroadcastReceiver im Phonegap Plugin

  • -Setup eine anhängige Absicht, PI, dass das Betriebssystem verwenden kann, um „dial back“ die App
  • erklärt, dass Absicht in der Datei plugin.xml
  • Alarm anfordern
  • Warten Sie, bis das Betriebssystem die PI verwendet, um die App zurückzurufen.

Zu diesem Zweck hier ist der Code, den ich geschrieben habe:

  • Die plugin.xml Datei

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

Erweitere Rundfunkempfänger Klasse - Datei 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  
    } 
} 

Definieren Sie das Plugin - Datei 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; 
    } 
    } 

Fang Methodenaufrufe in über die JS Brücke kommen:

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

}

die Brücke Cordova JS definieren. Datei-Pluginjs:

var exec = require('cordova/exec'); 
var plugin = 
{ 
setalarm:function (scbk, ecbk) {exec(scbk, ecbk, "Plugin", "setalarm", 
[]);} 
}; 

module.exports = plugin; 

Mit all diesen an Ort und Stelle, habe ich ein Phonegap Projekt in Phonegap CLI die Jquery-mobile-Starter Vorlage:

phonegap create /path/to/project --template jquery-mobile-starter 

Dann habe ich das Plugin:

phonegap plugin add /path/to/plugin 

Und danach habe ich geändert, um die init Methode in 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);} 

Soweit ich an dieser Stelle sagen kann, ich habe alle folgenden getan:

  • Erstellt
  • einen Alarm 10 Sekunden eine Methode aus diesem Plugin Exposed ein Plugin auslösen, nachdem es gewesen ist set
  • einen Rundfunkempfänger Erstellt Alarmereignisse zu handhaben durch das O
  • erklärte die Absicht zu behandeln solche Ereignisse in der App-Manifest-Datei
  • Erstellt eine Anwendung, die dieses Plugin verwendet herabgesandt
  • Vom init Methode für die App den Alarm

Die App entspricht richtig und wenn in Betrieb genommen Brände alle verschiedenen diagnostischen Toasts, die ich in codierter haben. Aber es nie reagiert auf die tatsächlichen Alarm Veranstaltung.

Offensichtlich mache ich hier etwas falsch oder habe missverstanden, wie das System Alarme behandelt. Ich wäre jedem sehr dankbar, der mich auf die richtige Spur bringen könnte.

+++++++++++++

Da diese Frage Entsendung Ich habe festgestellt, dass, wenn ich den Rundfunkempfänger dynamisch Dinge registrieren wie erwartet.

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); 

Der klare hier Unterschied ist, dass statt dem ServiceAlarm Klasse vorbei zum Intent Konstruktor ich selbst eine Instanz des ServiceAlarm Objekts am vorbei.

Die Tatsache, dass dies funktioniert, ist sehr beruhigend, aber es lässt eine Frage - Ich habe in Dutzenden von Beispielen, die Dinge auf die "andere Weise" tun, d. H. Meine ursprüngliche Art und Weise. Also sind sie falsch oder habe ich irgendwo in meinem Code einen Fehler - z. die Receiver-Deklaration in der Datei config.xml.

Ich hoffe, dass jemand hier in der Lage sein könnte, das Problem zu erkennen.

Antwort

0

Das Problem muss in plugin.xml sein. Empfänger müssen ein Kind von Anwendung sein.Das Problem kann durch Bewegen Empfänger befestigt werden trennen config-Datei mit Anwendung parent:

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