Logo Gaby Becker

WordPress App zum Blogartikel schreiben von unterwegs
IMDb Kino App für die Kinovorschau
Google Currents Feedreader für Android
Locus Maps App - Offline Maps + Geocaching
Play Music - App - der Musicplayer für unterwegs

Push-Notifications von Drupal 7 an registrierte Android-Smartphones senden

Bild des Benutzers android_oma

Add a Service part 1Unsere Webgrrls Events App ist seit Anfang Mai im Playstore verfügbar. Ursprünglich war sie so konzipiert, dass der User selbst den Refresh-Button betätigt, um die Events herunterzuladen. Dadurch wollten wir verhindern, dass die App durch das Ablaufen von Webservices im Hintergrund langsamer wird bzw. ein Prozeß wegen fehlender Internetverbindung abgebrochen werden muss. 

Das Aktualisieren hier aber komplett dem User zu überlassen, ist auch nicht so schön. Schließlich muss er immer wieder selbst daran denken, sich die neuesten Events herunterzuladen. Um ihm das zu ersparen, kamen wir auf die Idee, den GCM [Google Cloud Messaging] - Service zu nutzen. Der Google Cloud Messaging Service ermöglicht es, Nachrichten an die jeweils registrierten Geräte als Push-Nachricht zu versenden. Auslöser einer solchen Nachricht wäre in unserem Fall die Einstellung eines neuen Events oder die Änderung eines vorhandenen.
 
Drupal mit Android zu verheiraten, ist aber schon tricky. Nach diversen Tests sind wir dann
folgendermaßen vorgegangen:
 
3 Module installieren
  • 1. Services (unverzichtbar, weil es den REST-Server zur Verfügung stellt)

               install services module

  • 2. Push Notifications (um die RegistrationsIds der Android-Geräte in der Datenbank zu speichern)

              install module push-notifications

  • 3. GCM [Google Cloud Messaging] (um über die Rules das Versenden von Nachrichten zu steuern)

               install gcm module

 
Module einrichten
 
  • 1.1 Services aktivieren 
  • 1.2 REST-Server aktivieren
  • 1.3 Endpoints einrichten

               add a service part 1

              add a service part 2

              add a service part 3

              add a service part 4

              add a service part 5

              add a service part 6

              add a service part 7

              configure push notifications module part 1

              configure push notifications module part 2

              configure push notifications module part 3

  • 2.1 zusätzlich müssen die Benutzerrechte für Push Notifications eingerichtet werden, damit auch Gäste Notifications schicken können - ist zum Speichern der Geräte - RegistrationIDs
  • 3. GCM einrichten

              configure gcm module

  • 3.1 Rules einstellen
  • 3.1.1 Rule für das Versenden von Nachrichten

              create rule for registration part 1

              create rule for registration part 2

              create rule for registration part 3

              create rule for registration part 4

  • 3.1.2 Rule für das Benachrichtigen, wenn Registrations Ids nicht mehr aktiv sind, damit diese in der Datenbank gelöscht werden können.

              create rule for unregistration

              create rule for unregistration part 2

 
Damit wäre dann auf der Drupal-Seite auch schon alles getan. Bleibt nur noch, den GCM auf der Android-App-Seite einzurichten. Hierzu jedoch später mehr.
Beim GCM-Modul gab es noch einen kleinen Bug, den ich über Drupal.org und über Twitter an den Entwickler gemeldet hatte. Er hat super schnell reagiert, sofort gefixt und eine neue Version zur Verfügung gestellt.
Um die RegistrationIds [hier Tokensfeld] aus der Datenbanktabelle des Push-Notifications-Moduls zu holen, hatte ich zunächst die Idee, den Code vom gcm-Modul zu ändern. Nativ sieht das gcm-Modul nämlich vor, dass die IDs hineinkopiert werden - Komma getrennt.
Shushu Inbar - der Entwickler vom gcm-modul - schrieb mir dann jedoch, dass ich einfach php-Code im Textfeld der Tokens nutzen kann. Bis zu dieser E-Mail war mir gar nicht bewußt, dass ich bei Aktivierung von "PHP Code" in den Textformaten [natürlich ausschließlich für Administratoren] dies in jedem x-beliebigen Textfeld nutzen kann. Bei den Rules hatte ich schon eine Aktion "Execute Custom PHP Code" gesehen. Die konnte ich aber nicht nutzen, weil das GCM-Modul dies nicht vorsah.
So war es dann aber entschieden einfacher. 
Hier mal der PHP-Code im Tokens-Feld der Aktion
 
Dieser, zuerst probierte Code, hat nicht funktioniert, weil über die Funktion GROUP_CONCAT nur bis zu einer bestimmten Anzahl [ich habe Zahlen von 521 bis 1024 gelesen] Zeichen ausgegeben werden können

<?php $result = db_query("SELECT GROUP_CONCAT(token SEPARATOR  ',') FROM {push_notifications_tokens}")->fetchField();  echo $result; ?>  

Aus diesem Grund bin ich auf diesen Code im Feld "Tokens" in der Rule ausgewichen:

<?php
$tokens = "";
$result = db_query("SELECT token FROM {push_notifications_tokens}");
while($row = $result->fetchAssoc()) {
    $tokens .= $row['token'] . ", ";
}
$tokens = substr($tokens, 0, strlen($tokens) - 1);
echo $tokens; 
?>

Damit lese ich alle Tokens in Form einer kommaseparierten Liste aus. Genau das, was in dem Feld erwartet wird.
Das Löschen der nicht mehr aktiven Ids habe ich noch nicht implementiert. Derzeit ist das noch problemlos manuell durch Löschen des Tokens in der Datenbanktabelle machbar.
 
Nun zur Android-Seite. Hier mußte der zuvor erzeugte endpoint, die URL zum endpoint und die Projektnummer übergeben werden, damit die Notifications verarbeitet werden können. Einen Auszug aus dem Code findet Ihr hier:
 
Die Urls und Endpunkte werden zunächst in einer anderen Klasse als Konstanten festgelegt: 
 

public static final String YOUR_URL =http://www.yourwebsite.com/;
public static final String REGISTER_URI=mobile_data/push_notifications;
public static final String UNREGISTER_URI=mobile_data_unregister/push_notifications;

@Override
protected void onRegistered(Context arg0, String regId) {
Log.d("onRegistered", regId);
int statusCode = -1;
try {
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(Constants.YOUR_URL + Constants.REGISTER_URI);
List nameValuePairs = new ArrayList(2);
nameValuePairs.add(new BasicNameValuePair("token", regId));
nameValuePairs.add(new BasicNameValuePair("type", "android"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
HttpResponse response = client.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
statusCode = statusLine.getStatusCode();
Log.d("Webgrrls Events user register, statusCode", statusCode + "");
} catch (Exception e) {
Log.d("Webgrrls Events user register, exception", e.toString());
GCMRegistrar.unregister(arg0);
}
}

In unserem Fall ist "type" fix = android. Das Push-Notifications-Modul ist in der Lage, auch iPhone-Tokens zu speichern. Deshalb hier die Unterscheidung.  
 
Alle weiteren Methoden sind individuell zu entwickeln je nach den Anforderungen. 
Ich bin derzeit im E-Mail-Kontakt mit dem Entwickler des GCM-Moduls. Wir werden voraussichtlich zusammenarbeiten, um das GCM-Modul so zu erweitern, dass es ohne die push-notifications-tabelle auskommt. Damit wäre es dann
möglich, nur mit zwei Modulen das Senden von Nachrichten an Smartphones zu steuern. Das wird aber dauern, bis es soweit ist. Wir würden uns aber freuen, wenn sich noch weitere Drupal-Entwickler finden, die uns dabei unterstützen.
  

Neuen Kommentar schreiben

Bitte geben Sie Ihre E-Mail-Adresse ein. Sie wird nicht angezeigt.
@

Plain text

  • Keine HTML-Tags erlaubt.
  • Internet- und E-Mail-Adressen werden automatisch umgewandelt.
  • HTML - Zeilenumbrüche und Absätze werden automatisch erzeugt.
CAPTCHA
Dieses Captcha ist zur Identifikation, ob Du ein Mensch oder ein Spambot bist.
3 + 10 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.