请帮助我了解Cordova
我在我的Android应用程序中使用了用于cordova的Push插件。
我在Android应用处于前台模式时收到推送通知,但在应用未运行或空闲模式时无法收到通知。
你能告诉我解决方案吗?
答案 0 :(得分:1)
插件不支持cordova android用于后台通知,这就是我使用自己的代码进行推送通知的原因。
我已从我的cordova项目中删除了Push插件和相关文件。
它解决了使用cordova android(前景和背景两者)推送通知的问题。您可以使用推送插件的代码。
CommonUtilities.java
import android.content.Context; import android.content.Intent;
/ ** * Helper类提供了其他类中常见的方法和常量 * app。 * / 公共最终班级CommonUtilities {
/**
* Base URL of the Demo Server (such as http://my_host:8080/gcm-demo)
*/
static final String SERVER_URL = "http://www.milagro.in/wip/milagroApp/android/gcm/saveDeviceId.php";
/**
* Google API project id registered to use GCM.
*/
static final String SENDER_ID = "593186608269";
/**
* Tag used on log messages.
*/
static final String TAG = "GCMDemo";
/**
* Intent used to display a message in the screen.
*/
static final String DISPLAY_MESSAGE_ACTION =
"com.google.android.gcm.demo.app.DISPLAY_MESSAGE";
/**
* Intent's extra that contains the message to be displayed.
*/
static final String EXTRA_MESSAGE = "message";
/**
* Notifies UI to display a message.
* <p>
* This method is defined in the common helper because it's used both by
* the UI and the background service.
*
* @param context application's context.
* @param message message to be displayed.
*/
static void displayMessage(Context context, String message)
{
Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
intent.putExtra(EXTRA_MESSAGE, message);
context.sendBroadcast(intent);
}
}
public class GCMIntentService extends GCMBaseIntentService {
@SuppressWarnings("hiding")
private static final String TAG = "GCMIntentService";
boolean noti_status = false;
public GCMIntentService()
{
super(SENDER_ID);
}
@Override
protected void onRegistered(Context context, String registrationId)
{
Log.i(TAG, "Device registered: regId = " + registrationId);
displayMessage(context, getString(R.string.gcm_registered));
ServerUtilities.register(context, registrationId);
}
@Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
displayMessage(context, getString(R.string.gcm_unregistered));
if (GCMRegistrar.isRegisteredOnServer(context))
{
System.out.println("registration id: "+registrationId);
ServerUtilities.unregister(context, registrationId);
}
else
{
System.out.println("registration id: "+registrationId);
ServerUtilities.unregister(context, registrationId);
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
Log.i(TAG, "Ignoring unregister callback");
}
}
@Override
protected void onMessage(Context context, Intent intent)
{
Log.i(TAG, "Received message");
//String message = getString(R.string.gcm_message);
String message = intent.getExtras().getString("notify");
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
@Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
String message = getString(R.string.gcm_deleted, total);
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
@Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
displayMessage(context, getString(R.string.gcm_error, errorId));
}
@Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
displayMessage(context, getString(R.string.gcm_recoverable_error,
errorId));
return super.onRecoverableError(context, errorId);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
@SuppressWarnings("deprecation")
private static void generateNotification(Context context, String message) {
String notification_message = "";
try {
JSONObject notiObj = new JSONObject(message);
// String noti_type = notiObj.getString("notify_type");
String noti_text = notiObj.getString("notify_text");
// String noti_date = notiObj.getString("notify_date");
notification_message = noti_text;
} catch (Exception e) {
e.printStackTrace();
}
/* if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
System.out.println(" build version less than version 4.1");
int icon = R.drawable.l2;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, notification_message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, Home_Activity.class).putExtra("message", notification_message);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, notification_message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
} else {*/
System.out.println(" build version greater than version 4.1");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setContentTitle(context.getResources().getString(R.string.notification_title))
.setSmallIcon(R.drawable.l2)
.setContentText(notification_message)
.setAutoCancel(true);
Intent resultIntent = new Intent(context, MainActivity.class).putExtra("message", notification_message);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(0, mBuilder.build());
}
//}
}
公共类PushNotiActivity扩展了Activity { @覆盖 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); startActivity(new Intent(PushNotiActivity.this,MainActivity.class)); } }
public final class ServerUtilities {
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
/**
* Register this account/device pair within the server.
*
* @return whether the registration succeeded or not.
*/
static boolean register(final Context context, final String regId)
{
Log.i(TAG, "registering device (regId = " + regId + ")");
String serverUrl = SERVER_URL;
Map<String, String> params = new HashMap<String, String>();
params.put("deviceRegID", regId);
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
// Once GCM returns a registration id, we need to register it in the
// demo server. As the server might be down, we will retry it a couple
// times.
for (int i = 1; i <= MAX_ATTEMPTS; i++)
{
Log.d(TAG, "Attempt #" + i + " to register");
try
{
displayMessage(context, context.getString(R.string.server_registering, i, MAX_ATTEMPTS));
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
String message = context.getString(R.string.server_registered);
CommonUtilities.displayMessage(context, message);
return true;
}
catch (IOException e)
{
// Here we are simplifying and retrying on any error; in a real
// application, it should retry only on unrecoverable errors
// (like HTTP error code 503).
Log.e(TAG, "Failed to register on attempt " + i, e);
if (i == MAX_ATTEMPTS) {
break;
}
try {
Log.d(TAG, "Sleeping for " + backoff + " ms before retry");
Thread.sleep(backoff);
} catch (InterruptedException e1) {
// Activity finished before we complete - exit.
Log.d(TAG, "Thread interrupted: abort remaining retries!");
Thread.currentThread().interrupt();
return false;
}
// increase backoff exponentially
backoff *= 2;
}
}
String message = context.getString(R.string.server_register_error,
MAX_ATTEMPTS);
CommonUtilities.displayMessage(context, message);
return false;
}
/**
* Unregister this account/device pair within the server.
*/
static boolean unregister(final Context context, final String regId)
{
Log.i(TAG, "unregistering device (regId = " + regId + ")");
String serverUrl = SERVER_URL;
Map<String, String> params = new HashMap<String, String>();
params.put("deviceUnRegisterID", regId);
try
{
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, false);
String message = context.getString(R.string.server_unregistered);
CommonUtilities.displayMessage(context, message);
return true;
}
catch (IOException e)
{
// At this point the device is unregistered from GCM, but still
// registered in the server.
// We could try to unregister again, but it is not necessary:
// if the server tries to send a message to the device, it will get
// a "NotRegistered" error message and should unregister the device.
String message = context.getString(R.string.server_unregister_error,
e.getMessage());
CommonUtilities.displayMessage(context, message);
return false;
}
}
/**
* Issue a POST request to the server.
*
* @param endpoint POST address.
* @param params request parameters.
*
* @throws IOException propagated from POST.
*/
private static void post(String endpoint, Map<String, String> params)
throws IOException
{
System.out.println("params: "+params+" endpoint: "+endpoint);
URL url;
try
{
url = new URL(endpoint);
} catch (MalformedURLException e)
{
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();
Log.v(TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try
{
conn = (HttpURLConnection) url.openConnection();
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);
System.out.println(" server response is : "+body);
out.close();
// handle the response
int status = conn.getResponseCode();
if (status != 200) {
throw new IOException("Post failed with error code " + status);
}
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}
public class MainActivity extends CordovaActivity
{
SharedPreferences prefs;
AsyncTask<Void, Void, Void> mRegisterTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs=getSharedPreferences("milagro",this.MODE_PRIVATE);
loadUrl(launchUrl);
if (getIntent().hasExtra("message")) {
if (!getIntent().getStringExtra("message").equals("")) {
new AlertDialog.Builder(MainActivity.this)
.setTitle(this.getResources().getString(R.string.notification_title))
.setMessage(getIntent().getStringExtra("message"))
.setNeutralButton(this.getResources().getString(R.string.alert_button), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
}
gcmService();
}
@覆盖 public void onDestroy() { super.onDestroy();
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(getApplicationContext());
this.finish();
}
private void gcmService()
{
checkNotNull(SERVER_URL, "SERVER_URL");
checkNotNull(SENDER_ID, "SENDER_ID");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));
final String regId = GCMRegistrar.getRegistrationId(MainActivity.this);
System.out.println("***** " + regId);
prefs.edit().putString("deviceRegID",regId).commit();
//APA91bFxh7qxsolGdThFwO9CXAoboPfZfPDggTpMmas2gMUibwurv_0uFmYtVTJ6xd3Cw-KD3qrjnG7GPUiLsUoOeEURM_Ryw8qtybYMG7uXo2Em8ncPH8P34IBfEgHPNvrTa_57txAk
if (regId.equals(""))
{
GCMRegistrar.register(getApplicationContext(), SENDER_ID);
System.out.println("***** IF REG ***** " + regId);
}
else
{
if (GCMRegistrar.isRegisteredOnServer(MainActivity.this))
{
System.out.println("***** ELSE REG ***** " + regId);
}
else
{
final Context context = MainActivity.this;
mRegisterTask = new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
boolean registered = ServerUtilities.register(context, regId);
// At this point all attempts to register with the app
// server failed, so we need to unregister the device
// from GCM - the app will try to register again when
// it is restarted. Note that GCM will send an
// unregistered callback upon completion, but
// GCMIntentService.onUnregistered() will ignore it.
if (!registered)
{
GCMRegistrar.unregister(getApplicationContext());
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
}
private void checkNotNull(Object reference, String name)
{
if (reference == null)
{
throw new NullPointerException(getResources().getString(R.string.error_config, name));
}
}
private final BroadcastReceiver mHandleMessageReceiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
System.out.println("new Message: "+newMessage);
}
};
}