0

アプリに Android 用のプッシュ プラグイン通知を実装しています。そのため、アプリに Android 用の phonegap プッシュ プラグインを実際に実装する前に、いくつかのチュートリアルに従いました。

ステップ 1 ) サンプルの下の GCM サイトからサンプル コードを取得し、「サンプル APP」を作成しました。それはTomcatサーバーで動作しています。つまり、登録できます>>バックエンドでそれらの登録IDを受信します>>それらをmysqlに保存します>>登録された各IDにメッセージを送信します

ステップ2)次に、「メインアプリ」でAndroid用のphonegapプッシュプラグインを使用しようとしました。アプリを gcm に登録することはできますが (登録 ID を取得します)、バックエンド Tomcat サーバーに接続できません (上記と同じ、同じ送信者 ID を使用)。mysql でサンプル regid を作成してからメッセージをプッシュしようとしても、ステップ1の「サンプルアプリ」はまだTomcatサーバーからメッセージを受信して​​いますが、デバイスでメッセージは受信されません。

メインアプリAndroidManifest.xmlのコードは次のとおりです `

<?xml version="1.0" encoding="utf-8"?>
<!--
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.votesapp.phonegap"
    android:hardwareAccelerated="true"
    android:versionCode="1"
    android:versionName="1.0"
    android:windowSoftInputMode="adjustPan" >

    <supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:resizeable="true"
        android:smallScreens="true"
        android:xlargeScreens="true" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission android:name="com.plugin.gcm.permission.C2D_MESSAGE" android:protectionLevel="signature" />
     <uses-permission android:name="com.plugin.gcm.permission.C2D_MESSAGE" />
    <application
        android:hardwareAccelerated="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name="VotesApp"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Black.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.plugin.gcm.PushHandlerActivity"/>
        <receiver android:name="com.plugin.gcm.CordovaGCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="com.plugin.gcm" />
    </intent-filter>
</receiver>
<service android:name="com.plugin.gcm.GCMIntentService" />
    </application>

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="18" />

</manifest>

`

CordovaGCMBroadCastReceiver.java

 package com.plugin.gcm;

import android.content.Context;

import com.google.android.gcm.GCMBroadcastReceiver;
import static com.google.android.gcm.GCMConstants.DEFAULT_INTENT_SERVICE_CLASS_NAME;

/*
 * Implementation of GCMBroadcastReceiver that hard-wires the intent service to be 
 * com.plugin.gcm.GCMIntentService, instead of your_package.GCMIntentService 
 */
public class CordovaGCMBroadcastReceiver extends GCMBroadcastReceiver {

    @Override
    protected String getGCMIntentServiceClassName(Context context) {
        return "com.plugin.gcm" + DEFAULT_INTENT_SERVICE_CLASS_NAME;
    }

}

GCMIntentService.java

  package com.plugin.gcm;

    import android.content.Context;

    import com.google.android.gcm.GCMBroadcastReceiver;
    import static com.google.android.gcm.GCMConstants.DEFAULT_INTENT_SERVICE_CLASS_NAME;

    /*
     * Implementation of GCMBroadcastReceiver that hard-wires the intent service to be 
     * com.plugin.gcm.GCMIntentService, instead of your_package.GCMIntentService 
     */
    public class CordovaGCMBroadcastReceiver extends GCMBroadcastReceiver {

        @Override
        protected String getGCMIntentServiceClassName(Context context) {
            return "com.plugin.gcm" + DEFAULT_INTENT_SERVICE_CLASS_NAME;
        }


}

PushHandlerActivity.java

package com.plugin.gcm;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;

public class PushHandlerActivity extends Activity
{
    private static String TAG = "PushHandlerActivity"; 

    /*
     * this activity will be started if the user touches a notification that we own. 
     * We send it's data off to the push plugin for processing.
     * If needed, we boot up the main activity to kickstart the application. 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.v(TAG, "onCreate");

        boolean isPushPluginActive = PushPlugin.isActive();
        processPushBundle(isPushPluginActive);

        GCMIntentService.cancelNotification(this);

        finish();

        if (!isPushPluginActive) {
            forceMainActivityReload();
        }
    }

    /**
     * Takes the pushBundle extras from the intent, 
     * and sends it through to the PushPlugin for processing.
     */
    private void processPushBundle(boolean isPushPluginActive)
    {
        Bundle extras = getIntent().getExtras();

        if (extras != null) {
            Bundle originalExtras = extras.getBundle("pushBundle");

            originalExtras.putBoolean("foreground", false);
            originalExtras.putBoolean("coldstart", !isPushPluginActive);

            PushPlugin.sendExtras(originalExtras);
        }
    }

    /**
     * Forces the main activity to re-launch if it's unloaded.
     */
    private void forceMainActivityReload()
    {
        PackageManager pm = getPackageManager();
        Intent launchIntent = pm.getLaunchIntentForPackage(getApplicationContext().getPackageName());           
        startActivity(launchIntent);
    }

}

PushPlugin.java

package com.plugin.gcm;

import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;

import com.google.android.gcm.*;

/**
 * @author awysocki
 */

public class PushPlugin extends CordovaPlugin {
    public static final String TAG = "PushPlugin";

    public static final String REGISTER = "register";
    public static final String UNREGISTER = "unregister";
    public static final String EXIT = "exit";

    private static CordovaWebView gWebView;
    private static String gECB;
    private static String gSenderID;
    private static Bundle gCachedExtras = null;
    private static boolean gForeground = false;

    /**
     * Gets the application context from cordova's main activity.
     * @return the application context
     */
    private Context getApplicationContext() {
        return this.cordova.getActivity().getApplicationContext();
    }

    @Override
    public boolean execute(String action, JSONArray data, CallbackContext callbackContext) {

        boolean result = false;

        Log.v(TAG, "execute: action=" + action);

        if (REGISTER.equals(action)) {

            Log.v(TAG, "execute: data=" + data.toString());

            try {
                JSONObject jo = data.getJSONObject(0);

                gWebView = this.webView;
                Log.v(TAG, "execute: jo=" + jo.toString());

                gECB = (String) jo.get("ecb");
                gSenderID = (String) jo.get("senderID");

                Log.v(TAG, "execute: ECB=" + gECB + " senderID=" + gSenderID);

                GCMRegistrar.register(getApplicationContext(), gSenderID);
                result = true;
                callbackContext.success();
            } catch (JSONException e) {
                Log.e(TAG, "execute: Got JSON Exception " + e.getMessage());
                result = false;
                callbackContext.error(e.getMessage());
            }

            if ( gCachedExtras != null) {
                Log.v(TAG, "sending cached extras");
                sendExtras(gCachedExtras);
                gCachedExtras = null;
            }

        } else if (UNREGISTER.equals(action)) {

            GCMRegistrar.unregister(getApplicationContext());

            Log.v(TAG, "UNREGISTER");
            result = true;
            callbackContext.success();
        } else {
            result = false;
            Log.e(TAG, "Invalid action : " + action);
            callbackContext.error("Invalid action : " + action);
        }

        return result;
    }

    /*
     * Sends a json object to the client as parameter to a method which is defined in gECB.
     */
    public static void sendJavascript(JSONObject _json) {
        String _d = "javascript:" + gECB + "(" + _json.toString() + ")";
        Log.v(TAG, "sendJavascript: " + _d);

        if (gECB != null && gWebView != null) {
            gWebView.sendJavascript(_d); 
        }
    }

    /*
     * Sends the pushbundle extras to the client application.
     * If the client application isn't currently active, it is cached for later processing.
     */
    public static void sendExtras(Bundle extras)
    {
        if (extras != null) {
            if (gECB != null && gWebView != null) {
                sendJavascript(convertBundleToJson(extras));
            } else {
                Log.v(TAG, "sendExtras: caching extras to send at a later time.");
                gCachedExtras = extras;
            }
        }
    }

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);
        gForeground = true;
    }

    @Override
    public void onPause(boolean multitasking) {
        super.onPause(multitasking);
        gForeground = false;
    }

    @Override
    public void onResume(boolean multitasking) {
        super.onResume(multitasking);
        gForeground = true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        gForeground = false;
        gECB = null;
        gWebView = null;
    }

    /*
     * serializes a bundle to JSON.
     */
    private static JSONObject convertBundleToJson(Bundle extras)
    {
        try
        {
            JSONObject json;
            json = new JSONObject().put("event", "message");

            JSONObject jsondata = new JSONObject();
            Iterator<String> it = extras.keySet().iterator();
            while (it.hasNext())
            {
                String key = it.next();
                Object value = extras.get(key); 

                // System data from Android
                if (key.equals("from") || key.equals("collapse_key"))
                {
                    json.put(key, value);
                }
                else if (key.equals("foreground"))
                {
                    json.put(key, extras.getBoolean("foreground"));
                }
                else if (key.equals("coldstart"))
                {
                    json.put(key, extras.getBoolean("coldstart"));
                }
                else
                {
                    // Maintain backwards compatibility
                    if (key.equals("message") || key.equals("msgcnt") || key.equals("soundname"))
                    {
                        json.put(key, value);
                    }

                    if ( value instanceof String ) {
                    // Try to figure out if the value is another JSON object

                        String strValue = (String)value;
                        if (strValue.startsWith("{")) {
                            try {
                                JSONObject json2 = new JSONObject(strValue);
                                jsondata.put(key, json2);
                            }
                            catch (Exception e) {
                                jsondata.put(key, value);
                            }
                            // Try to figure out if the value is another JSON array
                        }
                        else if (strValue.startsWith("["))
                        {
                            try
                            {
                                JSONArray json2 = new JSONArray(strValue);
                                jsondata.put(key, json2);
                            }
                            catch (Exception e)
                            {
                                jsondata.put(key, value);
                            }
                        }
                        else
                        {
                            jsondata.put(key, value);
                        }
                    }
                }
            } // while
            json.put("payload", jsondata);

            Log.v(TAG, "extrasToJSON: " + json.toString());

            return json;
        }
        catch( JSONException e)
        {
            Log.e(TAG, "extrasToJSON: JSON exception");
        }           
        return null;        
    }

    public static boolean isInForeground()
    {
      return gForeground;
    }

    public static boolean isActive()
    {
        return gWebView != null;
    }
}

コードは、phonegap プッシュ プラグイン github リポジトリからのものです。試してみることができるいくつかのことを助けたり、提案したりしてください。前もって感謝します。

4

3 に答える 3

1

こんにちは、「Android用のphonegapプッシュプラグインによる通知」によって提供されるonNotificationGCM(ecb)javascriptメソッドのイベントコールバック関数(ECB)でサーバーへの明示的な呼び出しを追加することで、自分で問題を解決しました。フォアグラウンドとバックグラウンドで通知を受け取る

var theUrl = new String("http://<yourUrl>:8080?regId="+e.regid+"&userName=xyz");

                            var xmlHttp = null;

                            xmlHttp = new XMLHttpRequest();
                            xmlHttp.open( "GET", theUrl, false );
                            xmlHttp.send( null );
                            alert(xmlHttp.responseText);

また、CordovaGCMBroadCastReceiver と GCMIntentService は "一緒" であり、メイン パッケージ (mainfest タグで指定されているパッケージ) にある必要があることも学びました。その理由は、同じデバイスに対してマルチキャスト (非崩壊) がある場合、複数のスレッドが発生するためです。これは、CordovaGCMBroadCastReceiver と GCMIntentService の両方をメイン パッケージ、つまり com.plugin.gcm から com に移動したときに解除されました。 votesapp.phonegap (マニフェスト タグに記載されているパッケージ)。これで、同じデバイスに複数の通知を受け取ることができます。

注 : このソリューションは phonegap プッシュ プラグイン コードに固有のものです。

于 2014-05-12T01:57:19.223 に答える
0

@ user2845335 私はあなたと同じ手順に従いました。アラートで登録 ID を取得します。GCM は Google に登録されています。サーバー上のファイルを思い出すと、デバイスへのメッセージの送信は完全に機能しますhttp://www.mydomain.com/index.php

<html>
<head>
 <title>GCM</title>
</head>
<body>
 <?php
  if(isset($_POST['submit'])){
   $con = mysql_connect("x.x.x.x", "Sqlxxxx","xxxxxxx");
   if(!$con){
    die('MySQL connection failed');
   }

   $db = mysql_select_db("Sqlxxxx");
   if(!$db){
    die('Database selection failed');
   }


   $registatoin_ids = array();
   $sql = "SELECT * FROM android_udid";
   $result = mysql_query($sql, $con);
   while($row = mysql_fetch_assoc($result)){
    array_push($registatoin_ids, $row['registration_id']);
   }

   // Set POST variables
   $url = 'https://android.googleapis.com/gcm/send';

   $message = array("message" => $_POST['message']);
       $fields = array(
           'registration_ids' => $registatoin_ids,
           'data' => $message,
        );

        $headers = array(
             'Authorization: key=mykey',
             'Content-Type: application/json'
         );
         // Open connection
         $ch = curl_init();

         // Set the url, number of POST vars, POST data
         curl_setopt($ch, CURLOPT_URL, $url);

         curl_setopt($ch, CURLOPT_POST, true);
         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

         // Disabling SSL Certificate support temporarly
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

         curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

         // Execute post
         $result = curl_exec($ch);
         if ($result === FALSE) {
             die('Curl failed: ' . curl_error($ch));
         }

         // Close connection
         curl_close($ch);
         echo $result;

  }
 ?>
 <form method="post" action="index.php">
  <label>Insert Message: </label><input type="text" name="message" />

  <input type="submit" name="submit" value="Send" />
 </form>
 <?php
if (isset($fields)) {
print_r($fields);
}
?>
</body>
</html>

私がまだできないことは、mysql ID登録に保存することです

<script> 

$(document).ready(function(){
  $("#button").click(function(){
        var name=$("#name").val();

$.ajax({
    type: "POST",  
    url: "http://www.mydomain.com/register.php",
    data:...

</script>
于 2014-05-22T09:54:31.740 に答える