简体   繁体   中英

Push notification message with C# and Android app

Difficult to find clear sample code to achieve push notification messaging with C# code and Andorid app.

Basically, form C# code my main backend code which will send 'Push notification messages' to an android app.

I have firebase app in google and associated with my android app. But, when i send it, I am getting Missing=registrationid error.

DeviceId is actual mobile deviceid which I saved into a database by api call from android app.

Here is my c# code:

 public string SendNotification(string deviceId, string message)
{
    string SERVER_API_KEY = "server api key";        
    var SENDER_ID = "application number";
    var value = message;
    WebRequest tRequest;
    tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
    tRequest.Method = "post";
    tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
    tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));

    tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

    string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
    Console.WriteLine(postData);
    Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
    tRequest.ContentLength = byteArray.Length;

    Stream dataStream = tRequest.GetRequestStream();
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();

    WebResponse tResponse = tRequest.GetResponse();

    dataStream = tResponse.GetResponseStream();

    StreamReader tReader = new StreamReader(dataStream);

    String sResponseFromServer = tReader.ReadToEnd();


    tReader.Close();
    dataStream.Close();
    tResponse.Close();
    return sResponseFromServer;
}

Hi I have used Same code. Its working fine to me. The error which you are telling registration id error is look like that user does not successfully registered by android device for GCM.

sendPushNotificationRegistration(registerIdNew); is function you have to defined to save the registerIdNew in database.

private void registerDeviceForGCM() {
    //Process of registering device id for push notification
    aController = new Controller();
    pushClientManager = new GCMClientManager(this, PROJECT_NUMBER);
    pushClientManager.registerIfNeeded(new GCMClientManager.RegistrationCompletedHandler() {
        @Override
        public void onSuccess(String registrationId, boolean isNewRegistration) {
            final String registerIdNew = registrationId;
            if (CommonMethods.checkInternetConnection(context)) {
                if (globalVariable.isLogin()) {
                    sendPushNotificationRegistration(registerIdNew);
                }
            }
        }

        @Override
        public void onFailure(String ex) {
            super.onFailure(ex);
        }
    });
}

Controller Class:

public class Controller extends Application {
private final int MAX_ATTEMPTS = 5;
private final int BACKOFF_MILLI_SECONDS = 2000;
private final Random random = new Random();
private PowerManager.WakeLock wakeLock;



// Issue a POST request to the server.
private static void post(String endpoint, Map<String, String> params)
        throws IOException {

    URL url;
    try {

        url = new URL(endpoint);

    } catch (MalformedURLException e) {
        throw new IllegalArgumentException("invalid url: " + endpoint);
    } catch (Exception e) {
        int i = 0;
        throw new IllegalArgumentException("invalid url: " + endpoint);
    }

    StringBuilder bodyBuilder = new StringBuilder();
    Iterator<Entry<String, String>> iterator = params.entrySet().iterator();

    // constructs the POST body using the parameters
    while (iterator.hasNext()) {
        Entry<String, String> param = iterator.next();
        bodyBuilder.append(param.getKey()).append('=')
                .append(param.getValue());
        if (iterator.hasNext()) {
            bodyBuilder.append('&');
        }
    }

    String body = bodyBuilder.toString();
    byte[] bytes = body.getBytes();

    HttpURLConnection conn = null;
    try {

        conn = (HttpURLConnection) url.openConnection();
        //conn.connect();
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setFixedLengthStreamingMode(bytes.length);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded;charset=UTF-8");
        // post the request
        OutputStream out = conn.getOutputStream();
        out.write(bytes);
        out.close();

        // handle the response
        int status = conn.getResponseCode();

        // If response is not success
        if (status != 200) {

            throw new IOException("Post failed with error code " + status);
        }
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

// Checking for all possible internet providers
public boolean isConnectingToInternet() {

    ConnectivityManager connectivity =
            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity != null) {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null)
            for (int i = 0; i < info.length; i++)
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }

    }
    return false;
}

// Notifies UI to display a message.
void displayMessageOnScreen(Context context, String message) {

    Intent intent = new Intent(Config.DISPLAY_MESSAGE_ACTION);
    intent.putExtra(Config.EXTRA_MESSAGE, message);


    // Send Broadcast to Broadcast receiver with message
    context.sendBroadcast(intent);

}

//Function to display simple Alert Dialog
@SuppressWarnings("deprecation")
public void showAlertDialog(Context context, String title, String message,
                            Boolean status) {
    AlertDialog alertDialog = new AlertDialog.Builder(context).create();

    // Set Dialog Title
    alertDialog.setTitle(title);

    // Set Dialog Message
    alertDialog.setMessage(message);

    if (status != null)
        // Set alert dialog icon
        //alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);

        // Set OK Button
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {

            }
        });

    // Show Alert Message
    alertDialog.show();
}

public void acquireWakeLock(Context context) {
    if (wakeLock != null) wakeLock.release();

    PowerManager pm = (PowerManager)
            context.getSystemService(Context.POWER_SERVICE);

    wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
            PowerManager.ACQUIRE_CAUSES_WAKEUP |
            PowerManager.ON_AFTER_RELEASE, "WakeLock");

    wakeLock.acquire();
}

public void releaseWakeLock() {
    if (wakeLock != null) wakeLock.release();
    wakeLock = null;
}

}

GCM Client Manager Class

public class GCMClientManager {

// Constants
public static final String TAG = "GCMClientManager";
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
// Member variables
private GoogleCloudMessaging gcm;
private String regid;
private String projectNumber;
private Activity activity;

public GCMClientManager(Activity activity, String projectNumber) {
    this.activity = activity;
    this.projectNumber = projectNumber;
    this.gcm = GoogleCloudMessaging.getInstance(activity);
}

/**
 * @return Application's version code from the {@code PackageManager}.
 */
private static int getAppVersion(Context context) {
    try {
        PackageInfo packageInfo = context.getPackageManager()
                .getPackageInfo(context.getPackageName(), 0);
        return packageInfo.versionCode;
    } catch (NameNotFoundException e) {
        // should never happen
        throw new RuntimeException("Could not get package name: " + e);
    }
}

// Register if needed or fetch from local store
public void registerIfNeeded(final RegistrationCompletedHandler handler) {
    if (checkPlayServices()) {
        regid = getRegistrationId(getContext());

        if (regid.isEmpty()) {
            registerInBackground(handler);
        } else { // got id from cache
            Log.i(TAG, regid);
            handler.onSuccess(regid, false);
        }
    } else { // no play services
        Log.i(TAG, "No valid Google Play Services APK found.");
    }
}

/**
 * Registers the application with GCM servers asynchronously.
 * <p/>
 * Stores the registration ID and app versionCode in the application's
 * shared preferences.
 */
private void registerInBackground(final RegistrationCompletedHandler handler) {
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            try {
                if (gcm == null) {
                    gcm = GoogleCloudMessaging.getInstance(getContext());
                }
                InstanceID instanceID = InstanceID.getInstance(getContext());
                regid = instanceID.getToken(projectNumber, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                Log.i(TAG, regid);

                // Persist the regID - no need to register again.
                storeRegistrationId(getContext(), regid);

            } catch (IOException ex) {
                // If there is an error, don't just keep trying to register.
                // Require the user to click a button again, or perform
                // exponential back-off.
                handler.onFailure("Error :" + ex.getMessage());
            }
            return regid;
        }

        @Override
        protected void onPostExecute(String regId) {
            if (regId != null) {
                handler.onSuccess(regId, true);
            }
        }
    }.execute(null, null, null);
}

/**
 * Gets the current registration ID for application on GCM service.
 * <p/>
 * If result is empty, the app needs to register.
 *
 * @return registration ID, or empty string if there is no existing
 * registration ID.
 */
private String getRegistrationId(Context context) {
    final SharedPreferences prefs = getGCMPreferences(context);
    String registrationId = prefs.getString(PROPERTY_REG_ID, "");
    if (registrationId.isEmpty()) {
        Log.i(TAG, "Registration not found.");
        return "";
    }

    // Check if app was updated; if so, it must clear the registration ID
    // since the existing regID is not guaranteed to work with the new
    // app version.
    int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
    int currentVersion = getAppVersion(context);
    if (registeredVersion != currentVersion) {
        Log.i(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}

/**
 * Stores the registration ID and app versionCode in the application's
 * {@code SharedPreferences}.
 *
 * @param context application's context.
 * @param regId   registration ID
 */
private void storeRegistrationId(Context context, String regId) {
    final SharedPreferences prefs = getGCMPreferences(context);
    int appVersion = getAppVersion(context);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString(PROPERTY_REG_ID, regId);
    editor.putInt(PROPERTY_APP_VERSION, appVersion);
    editor.commit();
}

private SharedPreferences getGCMPreferences(Context context) {
    // This sample app persists the registration ID in shared preferences, but
    // how you store the regID in your app is up to you.
    return getContext().getSharedPreferences(context.getPackageName(),
            Context.MODE_PRIVATE);
}

/**
 * Check the device to make sure it has the Google Play Services APK. If
 * it doesn't, display a dialog that allows users to download the APK from
 * the Google Play Store or enable it in the device's system settings.
 */
private boolean checkPlayServices() {
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getContext());
    if (resultCode != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
        } else {
            Log.i(TAG, "This device is not supported.");
        }
        return false;
    }
    return true;
}

private Context getContext() {
    return activity;
}

private Activity getActivity() {
    return activity;
}

public static abstract class RegistrationCompletedHandler {
    public abstract void onSuccess(String registrationId, boolean isNewRegistration);

    public void onFailure(String ex) {
        // If there is an error, don't just keep trying to register.
        // Require the user to click a button again, or perform
        // exponential back-off.
        Log.e(TAG, ex);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM