I'm working on an app where it has it's own DB and will be syncing with the backend via GCM, I'm thinking of using background service but I'm not sure if this is the right way to think about it, so, I would really appreciate if you can tell me the below is correct or not, if not can you please state what I need to do in steps or how should think about it? no code is required.
When the app has no running/active activity, assume that GCM has a payload and no need to contact the backend,
1. Backend had new data and sent it with GCM
2. Background service received it and updated the DB
When the app is currently running
1. Backend had new data and sent it with GCM
2. Background service received it and updated the DB and notifydatasetchanged
3. Data on activity will be changed as the source has changed(e.g listview update it's items)
In general your idea is ok. But you don't need to have always running background Service. Just create WakefulBroadcastReceiver and add it into your Manifest:
<receiver
android:name=".receivers.GCMReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.your.package" />
</intent-filter>
</receiver>
Receiver could look like this:
public class GCMReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(), GCMService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
}
}
This receiver launches your Service(GCMService).
Related
I have app that get data from mysql with GetActivity activity and save in mysqlite and create notifications Now how i want my app run automatic and start GetActivity in background to get data
You'll want to look into Services which are threads that run in the background of Android. From within there you'll be able to load your data from your SQL database.
To take care of the automatic starting, you'll want to look into BroadcastReceivers, specifically the BOOT_COMPLETED receiver.
First you need to add this.
public class MyBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
///// Add your Background Service that Sync your data from database or internet//////////
//// I do the same work it fine work to me.///////
context.startService(new Intent(context, service_ReloadSqlDB.class));
/* Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);*/
}
}
Secondly you need to add this in manifest
<receiver
android:name="com.b2mtech.wrapper.MyBroadcastreceiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Hope this help you. Enjoy
http://smrnatore08.wix.com/smr-it-ltd
I have followed the Android GCM Client tutorial from Implementing GCM Client and the code from here. Also I am using the new process with the help of GoogleCloudMessaging.register(PROJECT_ID) to register devices.
The notifications seem to work fine and the ids stored on the server are also consistent.
The problem arises when the app is idle for a long time. The app stops getting any notifications, until it is opened again, after which it starts getting new notifications again (the previous ones are lost though).
Is this a common thing, or am I the only one facing the problem?
Here's some code for better insight:
the manifest file:
<receiver
android:name="GcmBroadcastReceiver"
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="myPackage" />
</intent-filter>
</receiver>
<service android:name="GcmIntentServiceNew" />
GcmBroadcastReceiver.java
#Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentServiceNew.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
And finally the GcmIntentServiceNew.java
public class GcmIntentServiceNew extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
//
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
//
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// Custom code here
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
}
Edit (No Solution yet)
I tested this a lot and can confirm now that the notifications stop after some time. I've been testing 10-15 notifications after an interval for 5-10 mins, could this be the reason of the notifications stopping?
The only solution that I see is going back to GCMRegistrar which is not ideal or reliable either.
The problem was with a library called Localytics, which was also handling Push notifications. Nothing related to GCM setup.
The app may be ended by the system if idle too long, but the example registers a GcmBroadcastReceiver that is started/invoked by the system whenever a GCM message arrives. That receiver in turn starts a Service which will then create the notification.
This pattern also works if the app is not running - actually, the system launches the app, resp. the broadcast receiver as part of the app, if necessary. If that is not the case with your app, you did something wrong.
Check your manifest file to see if the broadcast receiver and the service are specified correctly.
EDIT : Telling by your manifest file, I think you didn't provide the correct names for the broadcast receiver and the service. You have to provide either the fully qualified class name here (e.g com.example.GcmBroadcastReceiver) or you can leave the package name part of your app out but then you'd have at least to provide .GcmBroadcastReceiver (mind the leading dot!).
I am working on badges on launcher icon of application in android,I want to get total number of push notification for my app to display as a badge on my app's launcher icon,I am using parse.com for the push notifications in android,So can any buddy please tell me how to get count of push notifications and reflect it in badge in android?
code
Parse.initialize(this, "Hl59kzuF4yGr36XEUZByOgtorvyrYcVm7zAb6amG",
"YohxPugahDoiBZ2kaQ7qtqmO40y0JmLYkMuT");
PushService.setDefaultPushCallback(this, QuestionOFDayActivity.class);
If you are using parse.com then you might have using BroadcastReceiver for handling push notification(if not then use that).
So in onRecieve() of Broadcast receiver you can take count as application level. then u will get no. of push notification through out of app.
Edited :
Add this Receiver in your manifest
<receiver android:name="your.package.MyCustomReceiver" android:exported="false">
<intent-filter>
<action android:name="your.package.UPDATE_STATUS" />
</intent-filter>
</receiver>
create new class:-
public class MyCustomReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Here you will get the event when you receive Notification
// you can maintain a count here as application level.
}
}
If you want detailed doc - Then read this
I know these methods are deprecated, but since the new GCM API seems to be buggy, I am reverting to these methods until a stable version is pushed by Google.
We are declaring this receiver inside the manifest.
<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.myApp" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
And we have the onMessage() method inside the GCMIntentService class.
#Override
protected void onMessage(Context context, Intent intent)
{
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("msg");
}
1. However, upon receiving a message this method is never called. Why
?
Moreover, the example I follow uses the following.
registerReceiver(mHandleMessageReceiver, new IntentFilter("intent_filter_string"));
associated with the following class.
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String newMessage = intent.getExtras().getString("data");
}
};
which gets unregistered inside the onPause.
Why do we need to create this Broadcast Receiver?
Can't we do this in the manifest ?
Isn't this already covered by the onMessage() inside the GCMIntentService class ?
What role does the Pending Intent String play ?
Answers are appreciated.
Why do we need to create this Broadcast Receiver?
In some cases you might be interested in updating the UI if the app is running.
So you create a broadcast receiver at runtime and unregister it when the app
goes into background.
Can't we do this in the manifest?
Yes, you can do it in manifest too.
Isn't this already covered by the onMessage() inside the GCMIntentService class?
GCMIntentService extends GCMBaseIntentService. So any message coming from gcm,
will first be recieved in the onMessage of the GCMIntentService.
Its upto you to decide how you handle the message.
You can create a notification or send a broadcast to your custom broadcast
receivers and update the UI when the app is running.
What role does the Pending Intent play ?
According to the docs
A PendingIntent itself is simply a reference to a token maintained by the system
describing the original data used to retrieve it. This means that, even if its
owning application's process is killed, the PendingIntent itself will remain
usable from other processes that have been given it.
Did you registered your app/device combination to your GCm project? You have to do that first in the onRegistered Method. And did you add all necessary permissions? Google says you dont have to add the Custom Permissions above android 4.0 but my apps never worked without'em.
If you're looking for an easier way to work with GCM I recommend apiOmat: http://www.apiomat.com I know its Backend as a Service. But if your app is small you don't have to pay anything and it's much easier with it.
As my code looks today, I'm periodically sending a alarm(?) using AlarmManager that is received by AlarmReceiver extends BroadcastReceiver which in turn starts a Service. The Service do some updating and ends with a stopSelf(). IMO this is the best way of periodically perfom a task without constantly having a Service running. Correct?
The issue with this code is however that the whole chain of events is initiated onSharedPreferenceChanged(). I (initially) thought this was a good idea since the whole updating thing is enabled by the user in SharedPreferences.
I've now come to the conclusion that this is in fact not very good and that I need to initiate the AlarmManager/AlarmReceiver/Service/whatever both onPreferenceChange but also on boot.
I've done some searching but everyone seems to want to start the Service on boot. As I see it, I just need to initiate the AlarmManager which will then start the Service (when needed and only periodically).
Please help me with, first of all, sorting this out and secondly coding it!
Thanks in advance!
Then, create and register a BroadcastReceiver where you will do the AlarmManager stuff:
public class YourBootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// do the AlarmManager here
}
}
Then, on your manifest:
<application>
... other stuff
<receiver android:name=".YourBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />