android GcmIntentService not able to get new message from server - android

In one of my application i need to make app like chat application in that i am able to send data from device to server but not able to get data back from server to device.
In my manifest file... i have done
<permission android:name="<package name>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="<package name>.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<receiver
android:name="<package name>.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="<package name>" />
</intent-filter>
</receiver>
<service android:name=".GcmIntentService" ></service>
my GcmIntentService is like
public class GcmIntentService extends IntentService {
private static final String TAG = "GcmIntentService";
public static final int NOTIFICATION_ID = 101;
private NotificationManager mNotificationManager;
private DBAdapter dbAdapter;
public GcmIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("GcmIntentService>>>>>>>>>>>>>>>>>>>>>>>>>>>>");// this tag display in logcat
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String gcmMessageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
// has effect of unparcelling Bundle
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(gcmMessageType)) {
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(gcmMessageType)) {
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(gcmMessageType)) {
AppLog.Log(TAG, "newMessage :: " + intent);
String newMessage = intent.getExtras().getString("message");
AppLog.Log(TAG, "newMessage :: " + newMessage);
try {
handleMessage(newMessage);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void handleMessage(String message) throws JSONException {
if (message == null) {
return;
}
dbAdapter = new DBAdapter(getApplicationContext());
UserDetail detail = new MyPrefrence(getApplicationContext())
.getDetail();
JSONObject object = new JSONObject(message);
object = object.getJSONObject("details");
int who = object.getInt("who");
switch (who) {
case MessageModel.WHO_PERSONAL:
AHttpResponse response = new AHttpResponse(message, true);
MessageModel model = response.getSendMessage();
insertIfUSerNotExits(model, message);
model.setMessageStatus(MessageModel.STATUS_DELIVERED);
String tempMessage = null;
AppLog.Log(TAG, "MESSAGE ::" + model);
switch (model.getMessageType()) {
case MessageModel.MESSAGE_TYPE_MESSAGE:
tempMessage = model.getDisplayName() + ":" + model.getMessage();
break;
case MessageModel.MESSAGE_TYPE_VEDIO:
tempMessage = model.getDisplayName() + ": Video";
break;
case MessageModel.MESSAGE_TYPE_IMAGE:
tempMessage = model.getDisplayName() + ": image";
break;
case MessageModel.MESSAGE_TYPE_LOCATION:
tempMessage = model.getDisplayName() + ": location";
break;
case MessageModel.MESSAGE_TYPE_CONTACT:
tempMessage = model.getDisplayName() + " sends you contact of "
+ model.getMessage().split("//s+")[0];
break;
}
if (message != null) {
generateNotification(tempMessage);
}
dbAdapter.openForWrite();
int receiveMessageID = dbAdapter.insertMessage(model);
int userUpdateId = dbAdapter.updateLastMessageId(
receiveMessageID,
detail.getUserId() == model.getUserID() ? model
.getFriendId() : model.getUserID());
if (userUpdateId == 1) {
AppLog.Log(TAG, "User Update Success");
} else {
AppLog.Log(TAG, "User Update UnSucess");
}
dbAdapter.close();
// Intent intent = new Intent(MyActions.MESSAGE_UPDATE);
// LocalBroadcastManager.getInstance(getApplicationContext())
// .sendBroadcast(intent);
break;
case MessageModel.WHO_GROUP:
AppLog.Log(TAG,
"******************Group Message Received*********************");
AHttpResponse responseG = new AHttpResponse(message, true);
MessageModel modelG = responseG.getSendMessage();
insertIfUSerNotExits(modelG, message);
modelG.setMessageStatus(MessageModel.STATUS_DELIVERED);
AppLog.Log(TAG, "MESSAGE ::" + modelG);
// modelG.setUserID(new MyPrefrence(this).getDetail().getUserId());
// generateNotification(model.getDisplayName() + ":"
// + model.getMessage());
dbAdapter.openForWrite();
int receiveMessageIDG = dbAdapter.insertMessage(modelG);
if (modelG.getMessage() != null) {
generateNotification(modelG.getMessage());
}
int userUpdateIdG = dbAdapter.updateLastMessageId(
receiveMessageIDG,
detail.getUserId() == modelG.getUserID() ? modelG
.getFriendId() : modelG.getUserID());
if (userUpdateIdG == 1) {
AppLog.Log(TAG, "User Update Success");
} else {
AppLog.Log(TAG, "User Update UnSucess");
}
dbAdapter.close();
break;
case MessageModel.WHO_JOIN_GROUP:
AHttpResponse aHttpResponse = new AHttpResponse(message, true);
UserDetail userDetail = aHttpResponse.getJoinGroupDetail();
AppLog.Log(TAG, "userdetail :: " + userDetail.getName());
dbAdapter.openForRead();
dbAdapter.insertOrUpdateGroup(userDetail);
AppLog.Log(TAG, "Group is Created ");
getGtoupDetailFromServer(userDetail);
// } else {
// AppLog.Log(TAG, "Group creation failed");
// }
dbAdapter.close();
// dbAdapter.inserGroup();
// {"details":{"id":"119","time":"2014-06-12 17:02:11","type":"","user_id":"131","friend_id":"","who":"4","message":"","delivery_time":"","image":"group\/default.jpg","user_status":"","phone":"","phone_code":"","name":"test
// 33","status":""},"success":true,"message":"Successfully group
// created."}
break;
default:
break;
}
Intent intent = new Intent(MyActions.MESSAGE_UPDATE);
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(intent);
}
/**
*
* #param model
* #param newMessage
*
* responsible if user does not exists in database
*/
private void insertIfUSerNotExits(MessageModel model, String newMessage) {
dbAdapter.openForRead();
UserDetail userDetail = dbAdapter.getUserDetail(model.getUserID());
dbAdapter.close();
if (userDetail == null) {
UserDetail newUserDetail = new UserDetail();
try {
JSONObject jsonObject = new JSONObject(newMessage);
if (jsonObject.has("details")) {
jsonObject = jsonObject.getJSONObject("details");
newUserDetail.setUserId(jsonObject.getInt("user_id"));
newUserDetail.setImage(jsonObject.getString("image"));
newUserDetail
.setStatus(jsonObject.getString("user_status"));
newUserDetail.setPhoneNo(jsonObject.getString("phone"));
newUserDetail.setPhoneCode(jsonObject
.getString("phone_code"));
newUserDetail.setName(jsonObject.getString("name"));
// time to insert local database
dbAdapter.openForRead();
dbAdapter.insertOrUpdateUser(newUserDetail);
dbAdapter.close();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private void getGtoupDetailFromServer(final UserDetail detail) {
new Thread(new Runnable() {
#Override
public void run() {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", detail
.getUserId() + ""));
HttpRequest httpRequest = new HttpRequest();
try {
String responseString = httpRequest.postData(
Urls.GET_GROUP_MEMBER, nameValuePairs);
JSONObject jsonObject = new JSONObject(responseString);
AppLog.Log(TAG, "Getting Group Detail response :: "
+ responseString);
if (jsonObject.getBoolean("success")) {
JSONArray array = jsonObject.getJSONArray("details");
dbAdapter.openForWrite();
dbAdapter.deleteAllGroupUsers(detail.getUserId());
dbAdapter.close();
AppLog.Log(TAG, "GRoup Members ***************** "
+ array.length());
UserDetail detail;
for (int i = 0; i < array.length(); i++) {
detail = new UserDetail();
jsonObject = array.getJSONObject(i);
detail.setUserId(jsonObject.getInt("id"));
detail.setGroupId(jsonObject.getInt("group_id"));
detail.setAdmin(jsonObject.getInt("is_admin") == 1);
detail.setName(jsonObject.getString("name"));
detail.setPhoneCode(jsonObject
.getString("phone_code"));
detail.setPhoneNo(jsonObject.getString("phone"));
detail.setImage(jsonObject.getString("image"));
detail.setStatus(jsonObject.getString("status"));
dbAdapter.openForRead();
dbAdapter.insertUpdateGroupMember(detail);
dbAdapter.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private void generateNotification(String message) {
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getResources().getString(R.string.app_name))
.setStyle(
new NotificationCompat.BigTextStyle().bigText(message))
.setTicker(message).setContentText(message).setAutoCancel(true);
// Play default notification sound
mBuilder.setDefaults(Notification.DEFAULT_SOUND
| Notification.FLAG_AUTO_CANCEL);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, RecentChatList.class), 0);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
and GcmBroadcastReceiver class
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
// private static final String TAG = "GcmBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
System.out.println("PACKAGE NAME>>>>>>>>>>>>>>>>"+context.getPackageName()+"");
System.out.println("GcmBroadcastReceiver>>>>>>>>>>>>>>>>>>>>>");////still running
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
System.out.println("GcmBroadcastReceiver STARTED>>>>>>>>>>>>>>>>>>>>>");//still running
setResultCode(Activity.RESULT_OK);
}
*note GcmIntentService and GcmBroadcastReceiver is lies under my direct package
Please help to sove this problem

You need this permission to receive messages:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
To register,
GoogleCloudMessaging mGCM = GoogleCloudMessaging.getInstance(mContext);
String regId = mGCM.register(GOOGLE_PROJECT_ID);
Then just check if regId is a valid String.

Related

Cordova Android Push Plugin

I am trying to create push notification for my cordova project. I followed the tutorial from this link http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/ and created the plugin and I see the FCM is not sending back the registration id. I have added sender id in my application. Please help me to get this done. Thanks in advance.
GCMIntentService.java
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gcm.GCMBaseIntentService;
#SuppressLint("NewApi")
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super("GCMIntentService");
}
#Override
public void onRegistered(Context context, String regId) {
Log.v(TAG, "onRegistered: "+ regId);
JSONObject json;
try
{
json = new JSONObject().put("event", "registered");
json.put("regid", regId);
Log.v(TAG, "onRegistered: " + json.toString());
// Send this JSON data to the JavaScript application above EVENT should be set to the msg type
// In this case this is the registration ID
PushPlugin.sendJavascript( json );
}
catch( JSONException e)
{
// No message to the user is sent, JSON failed
Log.e(TAG, "onRegistered: JSON exception");
}
}
#Override
public void onUnregistered(Context context, String regId) {
Log.d(TAG, "onUnregistered - regId: " + regId);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.d(TAG, "onMessage - context: " + context);
// Extract the payload from the message
Bundle extras = intent.getExtras();
if (extras != null)
{
// if we are in the foreground, just surface the payload, else post it to the statusbar
if (PushPlugin.isInForeground()) {
extras.putBoolean("foreground", true);
createNotification(context, extras);
PushPlugin.sendExtras(extras);
}
else {
extras.putBoolean("foreground", false);
// Send a notification if there is a message
if (extras.getString("message") != null && extras.getString("message").length() != 0) {
createNotification(context, extras);
}
}
}
}
public void createNotification(Context context, Bundle extras)
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String appName = getAppName(this);
Intent notificationIntent = new Intent(this, PushHandlerActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("pushBundle", extras);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int defaults = Notification.DEFAULT_ALL;
if (extras.getString("defaults") != null) {
try {
defaults = Integer.parseInt(extras.getString("defaults"));
} catch (NumberFormatException e) {}
}
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setDefaults(defaults)
.setSmallIcon(context.getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
.setContentTitle(extras.getString("title"))
.setContentText(extras.getString("title"))
.setTicker(extras.getString("title"))
.setContentIntent(contentIntent)
.setAutoCancel(true);
String message = extras.getString("message");
if (message != null) {
mBuilder.setContentText(message);
} else {
mBuilder.setContentText("<missing message content>");
}
String msgcnt = extras.getString("msgcnt");
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
int notId = 0;
try {
notId = Integer.parseInt(extras.getString("notId"));
}
catch(NumberFormatException e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage());
}
catch(Exception e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
}
mNotificationManager.notify((String) appName, notId, mBuilder.build());
}
private static String getAppName(Context context)
{
CharSequence appName =
context
.getPackageManager()
.getApplicationLabel(context.getApplicationInfo());
return (String)appName;
}
#Override
public void onError(Context context, String errorId) {
Log.e(TAG, "onError - errorId: " + errorId);
}
}
PushPlugin.Java
import java.util.Iterator;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.android.gcm.GCMRegistrar;
import android.os.Bundle;
import android.util.Log;
public class PushPlugin extends Plugin {
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;
#Override
public PluginResult execute(String action, JSONArray data, String CallbackContext) {
// TODO Auto-generated method stub
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(this.cordova.getActivity(), 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(this.cordova.getActivity());
Log.v(TAG, "UNREGISTER");
result = true;
// callbackContext.success();
} else {
result = false;
Log.e(TAG, "Invalid action : " + action);
//callbackContext.error("Invalid action : " + action);
}
return new PluginResult(PluginResult.Status.OK);
//return null;
}
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;
}
}
}
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 void sendJavascript(JSONObject _json) {
String _d = "javascript:" + gECB + "(" + _json.toString() + ")";
Log.v(TAG, "sendJavascript: " + _d);
if (gECB != null && gWebView != null) {
gWebView.sendJavascript(_d);
}
}
public static boolean isInForeground()
{
return gForeground;
}
public static boolean isActive()
{
return gWebView != null;
}
}
PushHandlerActivity.java
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
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);
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);
}
#Override
protected void onResume() {
super.onResume();
final NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
}
Manifeast file
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="MyPackageName".push.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<activity android:name="MyPackageName".push.PushHandlerActivity"/>
<receiver android:name="MyPackageName".push.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="MyPackageName".push" />
</intent-filter>
</receiver>
<service android:name="MyPackageName".push.GCMIntentService" />

Android: Unable to update custom notification when I kill my app

I am downloading multiple files one after the other in service. I want to update download progress in notification. But my notification doesn't update when I kill my app. Download works on different thread. Download works fine in when app is running. When I kill app from recent section, I am unable to update notification.
Here is my DownloadService class
public class DownloadService extends Service {
public static DownloadMap<String, Downloadables> map = new DownloadMap<String, Downloadables>();
private static Thread thread;
private DownloadCancelReceiver receiver;
public DownloadService() {
}
public class BackgroundThread extends Thread {
int serviceId;
private DownloadMap<String, Downloadables> map;
private SpeedRevisionDatabase helper;
private final int notificationId = 1;
private RemoteViews remoteViewsSmall, remoteViewsBig;
private NotificationManagerCompat notificationManager;
private NotificationCompat.Builder mBuilder, mBuilderComplete, downloadFailBuilder;
public BackgroundThread(int serviceId, DownloadMap<String, Downloadables> map) {
this.serviceId = serviceId;
this.map = new DownloadMap<>();
this.map.putAll(map);
}
#Override
public void run() {
remoteViewsSmall = new RemoteViews(getApplicationContext().getPackageName(), R.layout.download_notification_small);
remoteViewsBig = new RemoteViews(getApplicationContext().getPackageName(), R.layout.download_notification);
Intent cancelDownload = new Intent("CANCEL_DOWNLOAD");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, cancelDownload, 0);
remoteViewsBig.setOnClickPendingIntent(R.id.tvCancel, pendingIntent);
notificationManager = NotificationManagerCompat.from(DownloadService.this);
mBuilder = new NotificationCompat.Builder(DownloadService.this, "default");
initChannels(DownloadService.this);
mBuilder.setContentTitle("Download is in progress")
.setContentText("Please wait...")
.setSmallIcon(R.mipmap.download)
.setOngoing(true)
.setCustomContentView(remoteViewsSmall)
.setCustomBigContentView(remoteViewsBig)
.setPriority(NotificationCompat.PRIORITY_HIGH);
notificationManager.notify(notificationId, mBuilder.build());
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try {
String path = getApplicationContext().getApplicationInfo().dataDir + "/" + "UEP";
File uepFolder = new File(path);
if (!uepFolder.exists()) {
uepFolder.mkdir();
}
int i = 0;
while (map.entrySet().iterator().hasNext()) {
Log.e("WhileCheck", "Now i is " + i);
Map.Entry data = (Map.Entry) map.entrySet().iterator().next();
try {
Downloadables download = (Downloadables) data.getValue();
if (NetworkUtil.getConnectivityStatus(getApplicationContext()) == 0) {
throw new InternetDisconnectedException("Internet Disconnected");
}
HttpURLConnection urlConnection;
InputStream inputStream;
//finding file on internet
try {
URL url = new URL(download.URL);
if (url.toString().endsWith(".xps")) {
url = new URL(url.toString().replace(".xps", ".pdf"));
}
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
inputStream = urlConnection.getInputStream();
} catch (IOException e) {
Log.e("IOException", "" + e.getMessage());
i++;
map.remove(data.getKey());
notificationManager.notify(notificationId, mBuilder.build());
continue;
}
//Downloading file over internet
File file = new File(uepFolder + "/" + download.FileName + "" + download.Format + ".download");
try {
int fileSize = urlConnection.getContentLength();
FileOutputStream fileOutput = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bufferLength = 0;
int count = 0;
int previousProgress = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
if (this.isInterrupted()) {
throw new InterruptedException("Thread has been kill (Destroyed)");
}
fileOutput.write(buffer, 0, bufferLength);
count += bufferLength;
int progress = (int) (count * 100L / (float) fileSize);
if (previousProgress > 999) {
updateProgress(map.insertedCount, i, progress, download.Name);
notificationManager.notify(notificationId, mBuilder.build());
previousProgress = 0;
}
previousProgress++;
}
fileOutput.close();
} catch (IOException e) {
Log.e("IOException", "" + e.getMessage());
i++;
map.remove(data.getKey());
continue;
}
File actualFile = new File(uepFolder + "/" + download.FileName + "" + download.Format);
file.renameTo(actualFile);
Log.e("Downloaded",""+actualFile.getAbsoluteFile());
} catch (InterruptedException | InternetDisconnectedException e) {
throw e;
}
i++;
map.remove(data.getKey());
Log.e("Downloaded", "Remaining files are "+map.size());
}
Log.e("WhileCheck", "While End");
// Due to thread, sometime the sequence of code flow is not in correct flow, and "Download complete" Notifaction is getting shown
// Hence this check is required.
if (this.isInterrupted()) {
throw new InterruptedException("Thread has been kill (Destroyed)");
}
notificationManager.cancel(notificationId);
mBuilderComplete = new NotificationCompat.Builder(DownloadService.this, "default");
initChannels(DownloadService.this);
mBuilderComplete.setOngoing(false)
.setContentTitle("Download Complete")
.setColor(Color.WHITE)
.setSmallIcon(R.drawable.download);
notificationManager.notify(2, mBuilderComplete.build());
Log.e("DownloadingService", "File downloaded successfully");
stopSelf();
map.insertedCount = 0;
} catch (InterruptedException e) {
closeNotification();
Log.e("InterruptedException", "" + e.getMessage());
} catch (InternetDisconnectedException e) {
stopSelf();
closeNotification();
showNotification("Internet disconnected", "Download failed. Try again later.");
Log.e("InternetDisconnect", "" + e.getMessage());
}
}
private void updateProgress(int totalFiles, int currentFileCount, int currentProgress, String fileName) {
remoteViewsSmall.setTextViewText(R.id.tvOverAll, currentFileCount + "/" + totalFiles);
remoteViewsSmall.setProgressBar(R.id.overallProgress, totalFiles, currentFileCount, false);
remoteViewsBig.setTextViewText(R.id.tvOverAll, currentFileCount + "/" + totalFiles);
remoteViewsBig.setTextViewText(R.id.tvFileName, "Downloading " + fileName);
remoteViewsBig.setTextViewText(R.id.tvCurrentProgress, currentProgress + "%");
remoteViewsBig.setProgressBar(R.id.overallProgress, totalFiles, currentFileCount, false);
remoteViewsBig.setProgressBar(R.id.currentProgress, 100, currentProgress, false);
}
public void closeNotification() {
if (notificationManager != null)
notificationManager.cancel(notificationId);
}
public void showNotification(String title, String message) {
downloadFailBuilder = new NotificationCompat.Builder(DownloadService.this, "default");
initChannels(DownloadService.this);
downloadFailBuilder.setOngoing(false)
.setContentTitle(title)
.setContentText(message)
.setColor(Color.WHITE)
.setSmallIcon(android.R.drawable.stat_sys_warning);
notificationManager.notify(3, downloadFailBuilder.build());
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
ArrayList<Downloadables> list = (ArrayList<Downloadables>) intent.getSerializableExtra("downloadList");
for (Downloadables d : list) {
String key = d.Name + "" + d.FileName;
map.put(key, d);
}
if (thread == null || !thread.isAlive()) {
thread = new BackgroundThread(startId, map);
receiver = new DownloadCancelReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
intentFilter.addAction("CANCEL_DOWNLOAD");
registerReceiver(receiver, intentFilter);
thread.start();
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.e("Service", " Stop");
try {
thread.interrupt();
} catch (Exception e) {
Log.e("Exception", "" + e.getMessage());
}
map.clear();
unregisterReceiver(receiver);
//closeNotification();
}
public static class DownloadCancelReceiver extends BroadcastReceiver {
public DownloadCancelReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase("CANCEL_DOWNLOAD")) {
Intent intent1 = new Intent(context, DownloadService.class);
context.stopService(intent1);
}
}
}
public void initChannels(Context context) {
if (Build.VERSION.SDK_INT < 26) {
return;
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("default", "Channel name", NotificationManager.IMPORTANCE_LOW);
channel.setDescription("Channel description");
channel.setImportance(NotificationManager.IMPORTANCE_LOW);
channel.setSound(null, null);
notificationManager.createNotificationChannel(channel);
}
private class InternetDisconnectedException extends Exception {
public InternetDisconnectedException(String message) {
super(message);
}
}
public static class DownloadMap<String, Downloadables> extends HashMap<String, Downloadables> {
public int insertedCount;
#Override
public Downloadables put(String key, Downloadables value) {
insertedCount++;
return super.put(key, value);
}
}
}
And From activity I start service like this.
ArrayList<Downloadables> list = helper.GetVideoFileList();
Intent intent1 = new Intent(SRDownloadActivity.this, DownloadService.class);
intent1.putExtra("downloadList", list);
startService(intent1);
I can even Add files to HashMap while downloading is in progress. It also worked fine.
I am unable to figure it out why it is not running in background since it is on different thread.
Here is my notification look like
Threads are killed by the Android OS even if the main app is still working and they dont have access to the UI thats why u should use AsyncTask class its a like a thread that works in background but it has access to the UI of the main. And the jobdispatcher class can help u assign jobs in the background
Here is a good tutorial https://youtu.be/das7FmQIGik

Android Get SMS Code with the Service BroadCastReceiver

I have login which requests for the SMS Code to Login the user. I have created the Receiver Class to receive the SMS Code the service reads the Full SMS from the Sender and it prints in the Log. I just want the recevier to get the code and verifiy on its own just like whatsapp.
This is the SMS I receive :-
Sent from your Twilio trial account - Your login code for App is :4132
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = SmsReceiver.class.getSimpleName();
private static final String SMS_ORIGIN = "+1 904-414-3527";
private static final String OTP_DELIMITER = ":";
private Context context;
private String code = null;
#Override
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
Object[] pdusObj = (Object[]) bundle.get("pdus");
for (Object aPdusObj : pdusObj) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) aPdusObj);
String senderAddress = currentMessage.getDisplayOriginatingAddress();
String message = currentMessage.getDisplayMessageBody();
Log.e(TAG, "Received SMS: " + message + ", Sender: " + senderAddress);
// if the SMS is not from our gateway, ignore the message
if (!senderAddress.toLowerCase().contains(SMS_ORIGIN)) {
return;
}
// verification code from sms
String verificationCode = getVerificationCode(message);
Toast.makeText(context, "OTP received: " + verificationCode, Toast.LENGTH_SHORT).show();
Log.e(TAG, "OTP received: " + verificationCode);
Intent hhtpIntent = new Intent(context, LoginActivity.class);
hhtpIntent.putExtra("otp", verificationCode);
context.startService(hhtpIntent);
}
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
/**
* Getting the OTP from sms message body
* ':' is the separator of OTP from the message
*
* #param message
* #return
*/
private String getVerificationCode(String message) {
int index = message.indexOf(OTP_DELIMITER);
if (index != -1) {
int start = index + 2;
int length = 4;
code = message.substring(start, start + length);
}
return code;
}
}
This where I want the code to be verified on its own with the intent but it doesn't work
public void doLogin() {
/* String otp = getIntent().getStringExtra("otp");
Toast.makeText(getApplicationContext(),
"You must enter the 4 digit code texted to your phone number." + otp,
Toast.LENGTH_LONG).show();*/
if (textField.getText().toString().length() != 4) {
codeUI();
} else {
code = Integer.parseInt(textField.getText().toString());
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("phoneNumber", phoneNumber);
params.put("codeEntry", code);
progressBar.setVisibility(View.VISIBLE);
ParseCloud.callFunctionInBackground("logIn", params, new FunctionCallback<String>() {
public void done(String response, ParseException e) {
progressBar.setVisibility(View.GONE);
if (e == null) {
token = response;
Log.d("Cloud Response", "There were no exceptions! " + response);
ParseUser.becomeInBackground(token, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (e == null) {
parseUser.isAuthenticated();
Log.d("Cloud Response", "There were no exceptions! ");
Intent i = new Intent(LoginActivity.this, EditProfileActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
} else {
Log.d("Cloud Response", "Exception: " + e);
TSnackbar snackbar = TSnackbar
.make(relative,"Something went wrong:" + e,TSnackbar.LENGTH_SHORT);
snackbar.show();
phoneNumberUI();
}
}
});
} else {
codeUI();
Log.d("Cloud Response", "Exception: " + response + e);
TSnackbar snackbar = TSnackbar
.make(relative,"Incorrect Code",TSnackbar.LENGTH_SHORT);
snackbar.show();
}
}
});
}
}
Try Like This
public String GENERAL_OTP_TEMPLATE = "Sent from your Twilio trial account - Your login code for App is : (.*).";
SmsMessage[] message = new SmsMessage[pdusObj.length];
Pattern generalCodePattern = Pattern.compile(GENERAL_OTP_TEMPLATE);
Matcher generalCodeMatcher = generalCodePattern .matcher(message[0]
.getMessageBody().toString());
if (generalCodeMatcher.find()) {
String code= generalCodeMatcher.group(1);
//Do Your stuff here for Match your otp
}

Not receiving push notifications in android

Hi In My Application I used this site for sending push notification using gcm concept androidhive.info . I am testing in localhost to server that one its working fine and no of devices also it showing after detecting the emulator registration id and then sending notification.Now that details also stored in local database.
Now My problem I am receiving any push notifications from server.
can anyone please help me and reslove it
AlertDialogManager.java:
public class AlertDialogManager {
public void showAlertDialog(Context context, String title, String message,
Boolean status) {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
// Setting Dialog Title
alertDialog.setTitle(title);
// Setting Dialog Message
alertDialog.setMessage(message);
if(status != null)
// Setting alert dialog icon
alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);
// Setting OK Button
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
// Showing Alert Message
alertDialog.show();
}
}
CommonUtilities.java
public final class CommonUtilities {
// give your server registration url here
static final String SERVER_URL = "http://10.0.2.2/gcm_server_php/register.php";
// Google project id
static final String SENDER_ID = "907381889394";
static final String TAG = "AndroidHive GCM";
static final String DISPLAY_MESSAGE_ACTION =
"com.androidhive.pushnotifications.DISPLAY_MESSAGE";
static final String EXTRA_MESSAGE = "message";
static void displayMessage(Context context, String message) {
Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
intent.putExtra(EXTRA_MESSAGE, message);
context.sendBroadcast(intent);
}
}
ConnectionDetector.java:
public class ConnectionDetector {
private Context _context;
public ConnectionDetector(Context context){
this._context = context;
}
public boolean isConnectingToInternet(){
ConnectivityManager connectivity = (ConnectivityManager) _context.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;
}
}
GCMIntentService.java:
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super(SENDER_ID);
}
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
displayMessage(context, "Your device registred with GCM");
Log.d("NAME", MainActivity.name);
ServerUtilities.register(context, MainActivity.name, MainActivity.email, registrationId);
}
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
displayMessage(context, getString(R.string.gcm_unregistered));
ServerUtilities.unregister(context, registrationId);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("price");
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);
}
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// 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, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
MainActivity.java:
public class MainActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Connection detector
ConnectionDetector cd;
public static String name;
public static String email;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(MainActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Getting name, email from intent
Intent i = getIntent();
name = i.getStringExtra("name");
email = i.getStringExtra("email");
// 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);
lblMessage = (TextView) findViewById(R.id.lblMessage);
registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(this, SENDER_ID);
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
ServerUtilities.register(context, name, email, regId);
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
}
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message
* depending upon your app requirement
* For now i am just displaying it on the screen
* */
// Showing received message
lblMessage.append(newMessage + "\n");
Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
// Releasing wake lock
WakeLocker.release();
}
};
#Override
protected void onDestroy() {
if (mRegisterTask != null) {
mRegisterTask.cancel(true);
}
try {
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
} catch (Exception e) {
Log.e("UnRegister Receiver Error", "> " + e.getMessage());
}
super.onDestroy();
}
}
RegisterActivity.java:
public class RegisterActivity extends Activity {
// alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Internet detector
ConnectionDetector cd;
// UI elements
EditText txtName;
EditText txtEmail;
// Register button
Button btnRegister;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(RegisterActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Check if GCM configuration is set
if (SERVER_URL == null || SENDER_ID == null || SERVER_URL.length() == 0
|| SENDER_ID.length() == 0) {
// GCM sernder id / server url is missing
alert.showAlertDialog(RegisterActivity.this, "Configuration Error!",
"Please set your Server URL and GCM Sender ID", false);
// stop executing code by return
return;
}
txtName = (EditText) findViewById(R.id.txtName);
txtEmail = (EditText) findViewById(R.id.txtEmail);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Read EditText dat
String name = txtName.getText().toString();
String email = txtEmail.getText().toString();
// Check if user filled the form
if(name.trim().length() > 0 && email.trim().length() > 0){
// Launch Main Activity
Intent i = new Intent(getApplicationContext(), MainActivity.class);
// Registering user on our server
// Sending registraiton details to MainActivity
i.putExtra("name", name);
i.putExtra("email", email);
startActivity(i);
finish();
}else{
// user doen't filled that data
// ask him to fill the form
alert.showAlertDialog(RegisterActivity.this, "Registration Error!", "Please enter your details", false);
}
}
});
}
}
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();
static void register(final Context context, String name, String email, final String regId) {
Log.i(TAG, "registering device (regId = " + regId + ")");
String serverUrl = SERVER_URL;
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
params.put("name", name);
params.put("email", email);
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
// Once GCM returns a registration id, we need to register on our 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;
} 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;
}
// increase backoff exponentially
backoff *= 2;
}
}
String message = context.getString(R.string.server_register_error,
MAX_ATTEMPTS);
CommonUtilities.displayMessage(context, message);
}
static void unregister(final Context context, final String regId) {
Log.i(TAG, "unregistering device (regId = " + regId + ")");
String serverUrl = SERVER_URL + "/unregister";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
try {
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, false);
String message = context.getString(R.string.server_unregistered);
CommonUtilities.displayMessage(context, message);
} 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);
}
}
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);
}
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 {
Log.e("URL", "> " + url);
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);
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();
}
}
}
}
WakeLocker.java:
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(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 static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.pushnotifications"
android:versionCode="1"
android:versionName="1.0" >
<!-- GCM requires Android SDK version 2.2 (API level 8) or above. -->
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Main activity. -->
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<!-- Register Activity -->
<activity
android:name=".RegisterActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Main Activity -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.androidhive.pushnotifications" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
A couple of points for you to check out:
Make sure your emulator's Target API is one of the Google APIs *** -- not just Android ***
Make sure you have a Google account logged in on the emulator

Receive Push Notifications into library project (Android C2DM in a lib project)

I have one project as a library of another one because I need whitelabeling it (and more projects for other partners). In the library project, I have implemented push notifications system. I've executed the library project as a normal project and the pushs work like a charm. My problem happens when i am importing this project as a library in another project. The receiver is never called.
There is one post with the same issue but the solution is not working for me. I am getting crazy!!!
Android C2DM and lib project
The main problem is that I am not receiving the message from C2DM. My code is the next:
Manifests of the both project (I have the same piece of code in both projects) (I am using the tags lib_project and app_project to be clear):
<receiver
android:name="com.lib_project.C2DMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.app_project.android" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.app_project.android" />
</intent-filter>
</receiver>
And the permissions:
<uses-permission android:name="com.app_project.android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.app_project.android.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
And also I have declared in the manifest the service that manage the push notifications but it is called properly.
<service android:name="com.lib_project.android.C2DMReceiver" />
Really, I don't know what is wrong. I think is ok but is not working. Thanks in advance.
It is my class C2DMBaseReceiver :
public abstract class C2DMBaseReceiver extends IntentService {
private static final String C2DM_RETRY = "com.google.android.c2dm.intent.RETRY";
public static final String REGISTRATION_CALLBACK_INTENT = "com.google.android.c2dm.intent.REGISTRATION";
private static final String C2DM_INTENT = "com.google.android.c2dm.intent.RECEIVE";
// Logging tag
private static final String TAG = "C2DM";
// Extras in the registration callback intents.
public static final String EXTRA_UNREGISTERED = "unregistered";
public static final String EXTRA_ERROR = "error";
public static final String EXTRA_REGISTRATION_ID = "registration_id";
public static final String ERR_SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE";
public static final String ERR_ACCOUNT_MISSING = "ACCOUNT_MISSING";
public static final String ERR_AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED";
public static final String ERR_TOO_MANY_REGISTRATIONS = "TOO_MANY_REGISTRATIONS";
public static final String ERR_INVALID_PARAMETERS = "INVALID_PARAMETERS";
public static final String ERR_INVALID_SENDER = "INVALID_SENDER";
public static final String ERR_PHONE_REGISTRATION_ERROR = "PHONE_REGISTRATION_ERROR";
// wakelock
private static final String WAKELOCK_KEY = "C2DM_LIB";
private static PowerManager.WakeLock mWakeLock;
private final String senderId;
/**
* The C2DMReceiver class must create a no-arg constructor and pass the
* sender id to be used for registration.
*/
public C2DMBaseReceiver(String senderId) {
// senderId is used as base name for threads, etc.
super(senderId);
this.senderId = senderId;
}
/**
* Called when a cloud message has been received.
*/
protected abstract void onMessage(Context context, Intent intent);
/**
* Called on registration error. Override to provide better
* error messages.
*
* This is called in the context of a Service - no dialog or UI.
*/
public abstract void onError(Context context, String errorId);
/**
* Called when a registration token has been received.
*/
public void onRegistered(Context context, String registrationId) throws IOException {
// registrationId will also be saved
}
/**
* Called when the device has been unregistered.
*/
public void onUnregistered(Context context) {
}
#Override
public final void onHandleIntent(Intent intent) {
try {
Context context = getApplicationContext();
if (intent.getAction().equals(REGISTRATION_CALLBACK_INTENT)) {
handleRegistration(context, intent);
} else if (intent.getAction().equals(C2DM_INTENT)) {
onMessage(context, intent);
} else if (intent.getAction().equals(C2DM_RETRY)) {
C2DMessaging.register(context, senderId);
}
} finally {
// Release the power lock, so phone can get back to sleep.
// The lock is reference counted by default, so multiple
// messages are ok.
// If the onMessage() needs to spawn a thread or do something else,
// it should use it's own lock.
mWakeLock.release();
}
}
/**
* Called from the broadcast receiver.
* Will process the received intent, call handleMessage(), registered(), etc.
* in background threads, with a wake lock, while keeping the service
* alive.
*/
static void runIntentInService(Context context, Intent intent) {
if (mWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
PowerManager pm =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
WAKELOCK_KEY);
}
mWakeLock.acquire();
// Use a naming convention, similar with how permissions and intents are
// used. Alternatives are introspection or an ugly use of statics.
String receiver = context.getPackageName() + ".C2DMReceiver";
intent.setClassName(context, receiver);
context.startService(intent);
}
private void handleRegistration(final Context context, Intent intent) {
final String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(EXTRA_ERROR);
String removed = intent.getStringExtra(EXTRA_UNREGISTERED);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "dmControl: registrationId = " + registrationId +
", error = " + error + ", removed = " + removed);
}
if (removed != null) {
// Remember we are unregistered
C2DMessaging.clearRegistrationId(context);
onUnregistered(context);
return;
} else if (error != null) {
// we are not registered, can try again
C2DMessaging.clearRegistrationId(context);
// Registration failed
Log.e(TAG, "Registration error " + error);
onError(context, error);
if ("SERVICE_NOT_AVAILABLE".equals(error)) {
long backoffTimeMs = C2DMessaging.getBackoff(context);
Log.d(TAG, "Scheduling registration retry, backoff = " + backoffTimeMs);
Intent retryIntent = new Intent(C2DM_RETRY);
PendingIntent retryPIntent = PendingIntent.getBroadcast(context,
0 /*requestCode*/, retryIntent, 0 /*flags*/);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,
backoffTimeMs, retryPIntent);
// Next retry should wait longer.
backoffTimeMs *= 2;
C2DMessaging.setBackoff(context, backoffTimeMs);
}
} else {
try {
onRegistered(context, registrationId);
C2DMessaging.setRegistrationId(context, registrationId);
} catch (IOException ex) {
Log.e(TAG, "Registration error " + ex.getMessage());
}
}
}
}
Ant this one is my C2DMReceiver:
public class C2DMReceiver extends C2DMBaseReceiver {
public static final String EXTRA_DATETIME = "datetime";
public static final String EXTRA_CAM_ID = "cam_id";
public static final String EXTRA_TYPE = "type";
public static final String GCM_PROJECT_ID = "58312821729";
public static void getC2DMRegistration(Context context){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO){
String id = C2DMessaging.getRegistrationId(context);
if(id.equals(""))
C2DMessaging.register(context, C2DMReceiver.GCM_PROJECT_ID);
else
C2DMReceiver.registerPushDevice(context, id);
Log.d("restored id: " + id);
}
}
public static String getDeviceID(Context context){
String out = null;
try {
TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);
out = telephonyManager.getDeviceId();
} catch (Exception e) {
Log.w("Error getting device uid", e);
}
return out;
}
public static void registerPushDevice(Context context, String registrationId){
try {
CameraManager app = null;
if(context instanceof Activity)
{
app = (CameraManager)(((Activity)context).getApplication());
}
else if(context instanceof Service)
{
app = (CameraManager)(((Service)context).getApplication());
}
else if(context instanceof Application)
{
app = (CameraManager)context;
}
if(app != null && app.isLoggedIn())
{
HashMap<String, String> keyValues = new HashMap<String, String>(app.getUserSessionKeys());
keyValues.put("imei", getDeviceID(context));
keyValues.put("registration_id", registrationId);
keyValues.put("application_id", context.getString(R.string.application_id));
keyValues.put("gcm", "true");
new ServerCall(context, Script.MOBILE, Method.ADD_REGISTRATION_ID, keyValues, null)
.execute();
}
} catch (Exception e) {
Log.e("Failed to register C2DM", e);
}
}
public C2DMReceiver() {
super(GCM_PROJECT_ID);
}
#Override
public void onRegistered(Context context, String registrationId) {
Log.i("onRegistered: " + registrationId);
registerPushDevice(context, registrationId);
}
#Override
public void onUnregistered(Context context) {
Log.i("onUnregistered");
}
#Override
public void onError(Context context, String errorId) {
Log.w("onError: " + errorId);
}
#SuppressWarnings("unchecked")
#Override
protected void onMessage(Context context, Intent receiveIntent){
Bundle extras = receiveIntent.getExtras();
CameraManager app = null;
if(context instanceof Activity)
{
app = (CameraManager)(((Activity)context).getApplication());
}
else if(context instanceof Service)
{
app = (CameraManager)(((Service)context).getApplication());
}
else if(context instanceof Application)
{
app = (CameraManager)context;
}
boolean activateNotificationsphone = app.getUserStorage().getBoolean(Constants.PUSH_NOTIFI_ACTIVATE_FROM_PHONE, true);
if(extras != null && activateNotificationsphone)
{
Log.e(""+extras.keySet());
Iterator<String> i = extras.keySet().iterator();
while(i.hasNext())
{
String key = i.next();
if(key.equalsIgnoreCase(Constants.EXTRA_ALARM_MOTION) || key.equalsIgnoreCase(Constants.EXTRA_CAMERA_DOWN) || key.equalsIgnoreCase(Constants.EXTRA_LSU_DOWN))
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis());
Intent notificationIntent = new Intent(context, FragmentTabs.class);
String type = key.toUpperCase();
String value = receiveIntent.getStringExtra(key);
String collapse_key = receiveIntent.getStringExtra("collapse_key");
String message = "";
String[] pair = value.split("[:]");
if(pair.length == 2)
{
notificationIntent
.putExtra(EXTRA_TYPE, type)
.putExtra(EXTRA_CAM_ID, pair[0])
.putExtra(EXTRA_DATETIME, pair[1])
.setAction(collapse_key);
Log.e("Type c2dm:"+type);
Log.e("Cam ID c2dm: " + pair[0]);
Log.e("DateTime c2dm: " + pair[1]);
ArrayList<CamerasFeedItem> cameras = null;
XMLObject settings = null;
ArrayList<EventItem> listEvents = null;
User user = null;
try
{
user = (User)Utils.deserializeObject(new File(getFilesDir(), CameraManager.USER_OBJ_FILE));
cameras = (ArrayList<CamerasFeedItem>)Utils.deserializeObject(new File(getFilesDir(), user.getUserId() + "_" + CameraManager.CAMERAS_OBJ_FILE));
settings = (XMLObject)Utils.deserializeObject(new File(getFilesDir(), user.getUserId() + "_" + CameraManager.SETTINGS_OBJ_FILE));
//List of events:
if(user!=null)
{
listEvents = (ArrayList<EventItem>)Utils.deserializeObject(new File(getFilesDir(), user.getUserId() + "_" + CameraManager.LIST_EVENTS_OBJ_FILE));
}
}
catch (Exception e)
{ }
CamerasFeedItem item = null;
if(settings == null || cameras == null || (item = isItemExists(cameras, pair[0])) == null)
{
return;
}
if(type.equals(Constants.EXTRA_ALARM_MOTION))
{
if(settings.getValue("motion", "no").equals("no"))
{
return;
}
GregorianCalendar curTime = new GregorianCalendar();
long offset = curTime.get(Calendar.ZONE_OFFSET) + curTime.get(Calendar.DST_OFFSET);
Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("UTC"));
c.setTimeInMillis(Long.parseLong(pair[1]) + offset);
String when = DateFormat.format("dd-MM-yyyy kk:mm:ss", c).toString();
message = context.getString(R.string.push_motion_on_camera, item.getName(), when);
}
else if(type.equals(Constants.EXTRA_CAMERA_DOWN))
{
if(settings.getValue("cameraDown", "no").equals("no"))
{
return;
}
message = context.getString(R.string.push_camera_is_down, item.getName(), getDownString(pair[1]));
//typeIndex = 1;
}
else if(type.equals(Constants.EXTRA_LSU_DOWN))
{
//typeIndex = 3;
message = "";
}
}
if(!message.equals(""))
{
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
contentView.setTextViewText(R.id.title, context.getString(R.string.app_name));
contentView.setTextViewText(R.id.text, message);
notification.contentView = contentView;
notification.contentIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), notificationIntent, 0);
mNotificationManager.notify(collapse_key, (int)Math.random(), notification);
}
return;
}
}
}
}
private CamerasFeedItem isItemExists(ArrayList<CamerasFeedItem> cameras, String id){
for(CamerasFeedItem item: cameras)
{
if(item.getID().equals(id))
{
return item;
}
if(item.isFolderItem())
{
LSUItem lsu = ((FolderItem)item).getLsuItem();
if(lsu != null && lsu.getID().equals(id))
{
return lsu;
}
CamerasFeedItem result = isItemExists(CamerasFeedItem.parse(item), id);
if(result != null)
{
return result;
}
}
}
return null;
}
private String getDownString(String hours){
StringBuilder out = new StringBuilder();
int total = Integer.parseInt(hours);
int m = total / 720;
total = total % 720;
int w = total / 168;
total = total % 168;
int d = total / 24;
total = total % 24;
if(m > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_month, m, m));
out.append(" ");
}
if(w > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_weeks, w, w));
out.append(" ");
}
if(d > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_days, d, d));
out.append(" ");
}
if(total > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_hours, total, total));
out.append(" ");
}
return out.toString().trim();
}
C2DMBroadcastReceiver.java
public class C2DMBroadcastReceiver extends BroadcastReceiver {
#Override
public final void onReceive(Context context, Intent intent) {
// To keep things in one place.
C2DMBaseReceiver.runIntentInService(context, intent);
setResult(Activity.RESULT_OK, null /* data */, null /* extra */);
}
}
And the last one: C2DMessaging:
public class C2DMessaging {
public static final String EXTRA_SENDER = "sender";
public static final String EXTRA_APPLICATION_PENDING_INTENT = "app";
public static final String REQUEST_UNREGISTRATION_INTENT = "com.google.android.c2dm.intent.UNREGISTER";
public static final String REQUEST_REGISTRATION_INTENT = "com.google.android.c2dm.intent.REGISTER";
public static final String LAST_REGISTRATION_CHANGE = "last_registration_change";
public static final String BACKOFF = "backoff";
public static final String GSF_PACKAGE = "com.google.android.gsf";
// package
static final String PREFERENCE = "com.google.android.c2dm";
private static final long DEFAULT_BACKOFF = 30000;
/**
* Initiate c2d messaging registration for the current application
*/
public static void register(Context context, String senderId) {
try {
Intent registrationIntent = new Intent(REQUEST_REGISTRATION_INTENT);
registrationIntent.setPackage(GSF_PACKAGE);
registrationIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT, PendingIntent.getBroadcast(context, 0, new Intent(), 0));
registrationIntent.putExtra(EXTRA_SENDER, senderId);
context.startService(registrationIntent);
} catch (Exception e) {
Log.w("Couldn't use C2DM, check OS version", e);
}
}
/**
* Unregister the application. New messages will be blocked by server.
*/
public static void unregister(Context context) {
Intent regIntent = new Intent(REQUEST_UNREGISTRATION_INTENT);
regIntent.setPackage(GSF_PACKAGE);
regIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT, PendingIntent.getBroadcast(context, 0, new Intent(), 0));
context.startService(regIntent);
}
/**
* Return the current registration id.
*
* If result is empty, the registration has failed.
*
* #return registration id, or empty string if the registration is not complete.
*/
public static String getRegistrationId(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
String registrationId = prefs.getString("dm_registration", "");
return registrationId;
}
public static long getLastRegistrationChange(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
return prefs.getLong(LAST_REGISTRATION_CHANGE, 0);
}
static long getBackoff(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
return prefs.getLong(BACKOFF, DEFAULT_BACKOFF);
}
static void setBackoff(Context context, long backoff) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putLong(BACKOFF, backoff);
editor.commit();
}
// package
static void clearRegistrationId(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("dm_registration", "");
editor.putLong(LAST_REGISTRATION_CHANGE, System.currentTimeMillis());
editor.commit();
}
// package
static void setRegistrationId(Context context, String registrationId) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("dm_registration", registrationId);
editor.commit();
}
}
Your problem is in this method :
static void runIntentInService(Context context, Intent intent) {
if (mWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
PowerManager pm =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
WAKELOCK_KEY);
}
mWakeLock.acquire();
// Use a naming convention, similar with how permissions and intents are
// used. Alternatives are introspection or an ugly use of statics.
String receiver = context.getPackageName() + ".C2DMReceiver";
intent.setClassName(context, receiver);
context.startService(intent);
}
In the following line context.getPackageName() returns the package of your app (com.app_project.android).
String receiver = context.getPackageName() + ".C2DMReceiver";
However, .C2DMReceiver is located in your library project (com.lib_project.android), and that's why this class is not found when you try to use your library project from your app.
The way to fix it is to refer to the C2DMReceiver class explicitly :
String receiver = C2DMReceiver.class.getName ();

Categories

Resources