Chen Goldenberg
Chen Goldenberg

Reputation: 21

gcm sends me a push only when i am on wifi and cell network

I am trying to make a simple messaging app for a class project when I send a push for my server to gcm when the phone is on WiFi it works fine when I use 3g (4g not tested) network it doesn't send the push at all

I tried on the post to gcm

$fields = array(
        'registration_ids'  => array( $reg_id ),
        'data'              => array( "message" => $message,"chat_id" => $chat_id ),
        'delay_while_idle'  => false,
        'time_to_live'      => 2019200

    ); 

'delay_while_idle'  => true, and no successes


<permission
android:name="in.ultraneo.c2dm.permission.C2D_MESSAGE"   
android:protectionLevel="signature" />
<uses-permission android:name="in.ultraneo.c2dm.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_TASKS" />



<receiver
            android:name=".MyC2dmReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />

                <category android:name="in.ultraneo.c2dm" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="in.ultraneo.c2dm" />
            </intent-filter>
        </receiver>

receiver class

 public class MyC2dmReceiver extends BroadcastReceiver {

    private static String KEY = "c2dmPref";
    private static String REGISTRATION_KEY = "registrationKey";
    private Context context;
    private String name,message,time,chat_id;
    private NotificationCompat.Builder notification;
    private NotificationManager manager;
    private  Bundle extras;


    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;
        if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) {
            String registrationId = intent.getStringExtra("registration_id");
            handleRegistration(context, intent);

            if(registrationId!=null)
            {
                Intent i=new Intent(context,register.class);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                i.putExtra("regkey",registrationId);
                context.startActivity(i);
            }

        } else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {

            Bundle bundle=intent.getExtras();
            if(bundle!=null)
            {
                name = intent.getStringExtra("message");
                message = intent.getStringExtra("message");
                chat_id = intent.getStringExtra("chat_id");
                //time= get time();
            }
            SharedPreferences sp = context.getSharedPreferences("OURINFO",context.MODE_PRIVATE);
            String active = sp.getString("chaton","");

             boolean flag = isForeground(context,"in.ultraneo.c2dm");

                        if(flag)
                        {
                            if(active.compareTo("yes")==0) {
                                Message.Message(context, "active is true");
                                Intent i = new Intent("ONLINE");
                                i.putExtra("msg",message);
                                i.putExtra("chat_id_rec",chat_id);
                                i.putExtra("name",message);
                                context.sendOrderedBroadcast(i,null);
                            }
                            else
                                Message.Message(context,"active is false but onpause or other activity");
                        }
                         else
                        {
                            Message.Message(context,"app is off line");
                            sendNotification(message, intent.getStringExtra("message"), name);
                        }
        }

    }


    private void handleRegistration(Context context, Intent intent) {
        String registration = intent.getStringExtra("registration_id");
        if (intent.getStringExtra("error") != null) {

            Log.d("c2dm", "registration failed");
            String error = intent.getStringExtra("error");
            if(error == "SERVICE_NOT_AVAILABLE"){
                Log.d("c2dm", "SERVICE_NOT_AVAILABLE");
            }else if(error == "ACCOUNT_MISSING"){
                Log.d("c2dm", "ACCOUNT_MISSING");
            }else if(error == "AUTHENTICATION_FAILED"){
                Log.d("c2dm", "AUTHENTICATION_FAILED");
            }else if(error == "TOO_MANY_REGISTRATIONS"){
                Log.d("c2dm", "TOO_MANY_REGISTRATIONS");
            }else if(error == "INVALID_SENDER"){
                Log.d("c2dm", "INVALID_SENDER");
            }else if(error == "PHONE_REGISTRATION_ERROR"){
                Log.d("c2dm", "PHONE_REGISTRATION_ERROR");
            }
        } else if (intent.getStringExtra("unregistered") != null) {

            Log.d("c2dm", "unregistered");
            Toast.makeText(context,"C2DM unregistered sucessfully",Toast.LENGTH_SHORT).show();

        } else if (registration != null) {

            Editor editor = context.getSharedPreferences(KEY, Context.MODE_PRIVATE).edit();
            editor.putString(REGISTRATION_KEY, registration);
            editor.commit();
            Toast.makeText(context,"Registration Id:"+registration,Toast.LENGTH_SHORT).show();
            new UltraFileaccess().Load_Data("REGKEY", registration, context);

        }
    }


    public boolean isForeground(Context context,String PackageName){
        // Get the Activity Manager
        ActivityManager manager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);

        // Get a list of running tasks, we are only interested in the last one,
        // the top most so we give a 1 as parameter so we only get the topmost.
        List< ActivityManager.RunningTaskInfo > task = manager.getRunningTasks(1);

        // Get the info we need for comparison.
        ComponentName componentInfo = task.get(0).topActivity;

        // Check if it matches our package name.
        if(componentInfo.getPackageName().equals(PackageName)) return true;

        // If not then our app is not on the foreground.
        return false;
    }

    private void sendNotification(String msg,String mobno,String name) {

        Bundle args = new Bundle();
        args.putString("mobno", mobno);
        args.putString("name", name);
        args.putString("msg", msg);
        Intent chat = new Intent(context, chatmsgbox.class);
        chat.putExtra("load",false);
        chat.putExtra("INFO", args);
        chat.putExtra("chat_id_notifi",chat_id);
        notification = new NotificationCompat.Builder(context);
        notification.setContentTitle(name);
        notification.setContentText(msg);
        notification.setDefaults(Notification.DEFAULT_ALL);
        notification.setTicker("New Message!");
        notification.setSmallIcon(R.drawable.icon);

        PendingIntent contentIntent = PendingIntent.getActivity(context,1000,chat, PendingIntent.FLAG_CANCEL_CURRENT);
        notification.setContentIntent(contentIntent);
        notification.setAutoCancel(true);
        manager =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(0, notification.build());
    }

}

Upvotes: 2

Views: 456

Answers (4)

Chen Goldenberg
Chen Goldenberg

Reputation: 21

tested Tomo answer didn't worked only on wifi it sends me a message

public class MyC2dmReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Intent service = new Intent(context, MyC2dmService.class);

    Message.Message(context,"test");

    // Start the service, keeping the device awake while it is launching.
    Log.i("MyC2dmService", "Starting service @");
    startWakefulService(context, service);

}

}

Upvotes: -1

Tomo
Tomo

Reputation: 6897

You put all your logic about receiving and showing notification in MyC2dmReceiver which extends BroadcastReceiver. If you look at documentation of BroadcastReceiver, especially description of method onReceiver, you'll notice that you have limited time and freedom for custom logic.

From documentation:

When it runs on the main thread you should never perform long-running operations in it (there is a timeout of 10 seconds that the system allows before considering the receiver to be blocked and a candidate to be killed). You cannot launch a popup dialog in your implementation of onReceive().

If this BroadcastReceiver was launched through a <receiver>tag, then the object is no longer alive after returning from this function. This means you should not perform any operations that return a result to you asynchronously


What you probably want to do is remove all logic from your MyC2dmReceiver BroadcastReceiver, and put it into service.

Example:

public class MyC2dmReceiver extends WakefulBroadcastReceiver { //note this is now WakefullBroadcastReceiver
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Intent service = new Intent(context, MyC2dmService.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("MyC2dmService", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

And code for service (taken from WakefulBroadcastReceiver documentation)

public class MyC2dmService extends IntentService {
    public MyC2dmService() {
        super("MyC2dmService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point MyC2dmReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.  


        //move your code from MyC2dmReceiver here


        //and finally release wake lock.
        MyC2dmReceiver.completeWakefulIntent(intent);
    }
}


Hint: on this page, you have full introduction how to implement GCM client, and since C2DM and GCM API are deprecated from Google, you should start using (if possible) Google Play Services.

Upvotes: 2

QArea
QArea

Reputation: 4981

Check you system settings or other applications settings, as "google settings". This is not your app code problem.

Upvotes: 0

tim687
tim687

Reputation: 2276

Remove the delay_while_idle so the message gets delivered at the moment you've send it. Double check the time_to_live value and set it to a normal amount of time (for example 5 or 6 weeks) if you set it to 1 hour, the message may get deleted while in the queue to be send to you're receivers

Upvotes: 0

Related Questions