I'm new to android. In my app, I didn't receive notification when the app is closed. If it is running it received. I tried all the way but still I didn't get the solution. Please find what I make wrong
Here my code:
Manifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.REGISTER" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<permission android:name="com.h2o.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.h2o.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name="com.h2o.ExternalReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.REGISTER" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
<service
android:name="com.h2o.MessageReceivingService"
android:label="com.h2o.MessageReceivingService" >
<intent-filter>
<action android:name="com.h2o.ExternalReceiver" />
<category android:name="com.h2o"/>
</intent-filter>
</service>
Receiver:
public class ExternalReceiver extends WakefulBroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),MessageReceivingService.class.getName());
startWakefulService(context,(intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Service:
public class MessageReceivingService extends Service{
private GoogleCloudMessaging gcm;
public static SharedPreferences savedValues;
public static void sendToApp(Bundle extras, Context context){
Intent newIntent = new Intent();
newIntent.setClass(context, AndroidMobilePushApp.class);
newIntent.putExtras(extras);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
public void onCreate(){
super.onCreate();
final String preferences = getString(R.string.preferences);
savedValues = getSharedPreferences(preferences, Context.MODE_PRIVATE);
gcm = GoogleCloudMessaging.getInstance(getBaseContext());
SharedPreferences savedValues = PreferenceManager.getDefaultSharedPreferences(this);
if(savedValues.getBoolean(getString(R.string.first_launch), true)){
register();
SharedPreferences.Editor editor = savedValues.edit();
editor.putBoolean(getString(R.string.first_launch), false);
editor.commit();
}
if(savedValuess.getBoolean(getString(R.string.first_launch), true)){
// Let AndroidMobilePushApp know we have just initialized and there may be stored messages
sendToApp(new Bundle(), this);
}
}
protected static void saveToLog(Bundle extras, Context context){
SharedPreferences.Editor editor=savedValues.edit();
String numOfMissedMessages = context.getString(R.string.num_of_missed_messages);
int linesOfMessageCount = 0;
for(String key : extras.keySet()){
String line = String.format("%s=%s", key, extras.getString(key));
editor.putString("MessageLine" + linesOfMessageCount, line);
linesOfMessageCount++;
}
editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
editor.putInt(numOfMissedMessages, savedValues.getInt(numOfMissedMessages, 0) + 1);
editor.commit();
postNotification(new Intent(context, AndroidMobilePushApp.class), context);
}
protected static void postNotification(Intent intentAction, Context context){
final NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intentAction, Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL);
final Notification notification = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Message Received!")
.setContentText("")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.getNotification();
mNotificationManager.notify(R.string.notification_number, notification);
}
private void register() {
new AsyncTask(){
protected Object doInBackground(final Object... params) {
String token;
try {
token = gcm.register(getString(R.string.project_number));
Log.i("registrationId", token);
}
catch (IOException e) {
Log.i("Registration Error", e.getMessage());
}
return true;
}
}.execute(null, null, null);
}
public IBinder onBind(Intent arg0) {
return null;
}
}
Thanks in advance!
To be able to receive notifications when your application is closed, you have to register a service listener with the following permission
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
See the documentation for more details
https://developer.android.com/reference/android/service/notification/NotificationListenerService.html
you need to define your broadcast receiver in manifest like this:
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
and in the broadcast receiver class add the following codes:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#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());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}}
there is some problem with wakeful broadcast receiver, read this
Confusion about WakefulBroadcastReceiver
For best practice it is recommended that you should use Firebase cloud messaging (FCM) instead of GCM.
Related
I am writing an app that uses GCM Push Notifications, however when a notification appears, it opens the app but doesn't show the message. When I am in the app though, the messages show up normally. Please help.
This is my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.amosang.pushtest" >
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- GCM Permissions - Start here -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.example.amosang.pushtest.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.amosang.pushtest.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:exported="true"
android:name=".HomeActivity"
android:label="#string/title_activity_home" >
</activity>
<receiver
android:name=".GCMBroadcastReceiver"
android:exported="true"
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" />
<action android:name="com.example.amosang.pushtest" />
</intent-filter>
</receiver>
<service android:name=".GCMNotificationIntentService"
android:exported="false">
</service>
<activity
android:name=".NewRequest"
android:label="#string/title_activity_new_request" >
</activity>
</application>
Notification Code
public class GCMNotificationIntentService extends IntentService{
//set ID for the notification, so it can be updated
public static final int notifyID = 9001;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
Log.d("GCMN","GCMNTEST");
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
sendNotification("Message Received from Google GCM Server:\n\n"
+ extras.get(AppConstants.MSG_KEY));
}
}
GCMBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg){
Intent resultIntent = new Intent(this, HomeActivity.class);
Log.d("RECEIVEDPT2",msg);
resultIntent.putExtra("msg", msg);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mNotifyBuilder;
NotificationManager mNotificationManager;
mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyBuilder = new NotificationCompat.Builder(this).setContentTitle("Alert")
.setContentTitle("You've received a new message")
.setSmallIcon(R.drawable.ic_cast_dark);
//Set pending intent
mNotifyBuilder.setContentIntent(resultPendingIntent);
//Set vibration
int defaults = 0;
defaults = defaults | Notification.DEFAULT_LIGHTS;
defaults = defaults | Notification.DEFAULT_VIBRATE;
defaults = defaults | Notification.DEFAULT_SOUND;
mNotifyBuilder.setDefaults(defaults);
// Set the content for Notification
mNotifyBuilder.setContentText("You have new notifications");
// Set autocancel
mNotifyBuilder.setAutoCancel(true);
// Post a notification
mNotificationManager.notify(notifyID, mNotifyBuilder.build());
}
As requested in the comments, please include the code for HomeActivity which handles the notification so we can examine the code and suggest solutions. In the meantime, this is how I'd suggest you process the incoming GCM notification in your HomeActivity class (will update the answer once I see you code, if necessary). In my example, I have a helper method processIntent(Intent intent) which handles the Intent and its Extras. I call this method from both onCreate and onNewIntent methods.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.<layout-id>);
//here I call our processing method
processIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//call our processing method
processIntent(getIntent());
}
/**
* Helper method to process the incoming GCM Notification.
* #param intent
*/
private void processIntent(Intent intent){
if(intent == null) { return; }
Bundle extras = intent.getExtras();
try{
if(extras.containsKey("msg")){
//possibly a message
String message = extras.getString("msg");
Log.i(TAG, "Received Message "+message);
//do whatever with the message, like set as Text of TextView, etc
}
}
catch(Exception e){
Log.e(TAG, "Error Processing GCM Notification Intent", e);
}
}
I followed the documentation of google to implement push notifications.
When the app is open works fine, but when I close the app does not receive notifications.
Here is the code:
Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="it.bsdsoftware.cnabologna.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<permission
android:name="it.bsdsoftware.cnabologna.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<application>
...
<service android:name=".notifiche.RegistrationIntentService"
android:exported="false" >
</service>
<service android:name=".notifiche.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name=".notifiche.MyInstanceIDListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<receiver android:name=".notifiche.GcmBroadcastReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.GCM_RECEIVED_ACTION"/>
<category android:name="it.bsdsoftware.cnabologna" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
</intent-filter>
</receiver>
</application>
RegistrationIntentService.java
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.notifiche_push_sender_id), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.i(TAG, "GCM Registration Token: " + token);
sendRegistrationToServer(token);
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
}
}
private void sendRegistrationToServer(String token) {
OperazioneInvioToken op = new OperazioneInvioToken(token);
WebServiceTask ws = new WebServiceTask(op, this, false);
ws.execute();
}
}
MyGcmListenerService.java
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
#Override
public void onMessageReceived(String from, Bundle data) {
Bundle notification = data.getBundle("notification");
String title = "";
String message = "";
if(notification!=null){
title = notification.getString("title");
message = notification.getString("body");
}
NotificationUtility.showNotification(title, message);
NotificationUtility.setBadge(1);
}
}
MyInstanceIDListenerService.java
public class MyInstanceIDListenerService extends InstanceIDListenerService {
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. This call is initiated by the
* InstanceID provider.
*/
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
GcmBroadcastReceiver.java
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), MyGcmListenerService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
When the app is open onMessageReceived of GcmListenerService class is called but when the app is closed is not called.
What did I do wrong?
Thanks
I resolved by updating the play service from com.google.android.gms:play-services:8.3.0 to com.google.android.gms:play-services:8.4.0
I am using an indefinitely running service (with its own process) and an extension of GcmListenerService to receive push messages. The push messages will initiate an operation within the service.
The problem is, that if the app is closed/removed from the recently used app, the service is still running, but will stop immediately if a new message is received. The process list shows that first the background process is terminated and then a usual application process starts without any processing of the push message.
AndroidManifest.xml
<application android:allowBackup="false" android:label="#string/app_name"
android:icon="#drawable/icon" android:theme="#style/AppTheme"
android:process="domain.android.Application"
android:name=".Application">
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="domain.android" />
</intent-filter>
</receiver>
<service
android:name=".service.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".service.BackgroundService"
android:icon="#drawable/icon"
android:label="#string/service_name"
android:process="domain.android.service.BackgroundService"
android:exported="false"
android:enabled="true"/>
</application>
The GCM listener
public class MyGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
String code = data.getString("code");
if ("j".equals(code)) {
final String id = data.getString("id", null);
String status = data.getString("status", null);
Intent serviceIntent = new Intent(getBaseContext(), domain.android.service.BackgroundService.class);
serviceIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
serviceIntent.putExtra("method", "push");
serviceIntent.putExtra("id", id);
serviceIntent.putExtra("status", status);
serviceIntent.putExtra("notificationId", (new Date()).getTime());
startService(serviceIntent);
}
}
}
The service:
public class BackgroundService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, final int startId) {
if (intent.hasExtra("method")) {
// Start processing
}
}
#Override
public void onCreate() {
Intent notificationIntent = new Intent(this, Main.class);
PendingIntent intent = PendingIntent.getActivity(getBaseContext(), 0, notificationIntent, 0);
android.app.Notification.Builder builder = new android.app.Notification.Builder(this)
.setContentIntent(intent)
.setContentTitle(getText(R.string.app_name))
.setContentText("Connected")
.setSmallIcon(R.drawable.marker_walker_white);
android.app.Notification notification = builder.build();
startForeground(1, notification);
}
}
I'm not sure how to autostart an android application after the android emulator completes its booting. Does anyone have any code snippets that will help me?
You have to add a manifest permission entry:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
(of course you should list all other permissions that your app uses).
Then, implement BroadcastReceiver class, it should be simple and fast executable. The best approach is to set an alarm in this receiver to wake up your service (if it's not necessary to keep it running ale the time as Prahast wrote).
public class BootUpReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context, MyService.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pi);
}
}
Then, add a Receiver class to your manifest file:
<receiver android:enabled="true" android:name=".receivers.BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Edit your AndroidManifest.xml to add RECEIVE_BOOT_COMPLETED permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Edit your AndroidManifest.xml application-part for below Permission
<receiver android:enabled="true" android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Now write below in Activity.
public class BootUpReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
If by autostart you mean auto start on phone bootup then you should register a BroadcastReceiver for the BOOT_COMPLETED Intent. Android systems broadcasts that intent once boot is completed.
Once you receive that intent you can launch a Service that can do whatever you want to do.
Keep note though that having a Service running all the time on the phone is generally a bad idea as it eats up system resources even when it is idle. You should launch your Service / application only when needed and then stop it when not required.
I always get in here, for this topic. I'll put my code in here so i (or other) can use it next time. (Phew hate to search into my repository code).
Add the permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Add receiver and service:
<receiver android:enabled="true" android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name="Launcher" />
Create class Launcher:
public class Launcher extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new AsyncTask<Service, Void, Service>() {
#Override
protected Service doInBackground(Service... params) {
Service service = params[0];
PackageManager pm = service.getPackageManager();
try {
Intent target = pm.getLaunchIntentForPackage("your.package.id");
if (target != null) {
service.startActivity(target);
synchronized (this) {
wait(3000);
}
} else {
throw new ActivityNotFoundException();
}
} catch (ActivityNotFoundException | InterruptedException ignored) {
}
return service;
}
#Override
protected void onPostExecute(Service service) {
service.stopSelf();
}
}.execute(this);
return START_STICKY;
}
}
Create class BootUpReceiver to do action after android reboot.
For example launch MainActivity:
public class BootUpReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent target = new Intent(context, MainActivity.class);
target.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(target);
}
}
I've have a simple app to schedule a notification 5 minutes after a button is pressed. It works fine for me. But if I restart the phone within that 5 minutes I don't get the notification. I have done a research on Alarm Manager and Scheduling Notifications on device reboots. I have a basic idea but I really don't know how to implement it into my project. I have 4 classes in my project. They are:
MainActivity
NotificationUtil
NotificationPublisher
NotificationView
This is the my NotificationUtil class:
public class NotificationUtil
{
public static void createNotification(Context context,Class<?> cls, String title, String content)
{
Intent intent = new Intent(context,cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
sendNotification(getNotification(pendingIntent,context,title,content),context);
}
private static void sendNotification(Notification notification,Context context)
{
Intent notificationIntent = new Intent(context, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID,1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION,notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5*60 * 1000,pendingIntent);
}
private static Notification getNotification(PendingIntent pendingIntent, Context context, String title, String content)
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,"ChannelID");
builder.setSmallIcon(R.drawable.notification_bell);
builder.setContentTitle(title);
builder.setContentText("You have a Notification");
builder.setSubText("Tap To View");
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(content));
builder.setContentIntent(pendingIntent);
return builder.build();
}
}
This is my NotificationPublisher class:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
#Override
public void onReceive(final Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int notificationId = intent.getIntExtra(NOTIFICATION_ID, 1);
notificationManager.notify(notificationId, notification);
}
}
This is how I call the NotificationUtil class on button click in the MainActivity:
public class MainActivity extends AppCompatActivity {
private Button button;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.notification);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NotificationUtil.createNotification(MainActivity.this,NotificationView.class,"Notification","You have a new Task");
}
});
}
}
This is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.notificationtest">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".NotificationView"
android:parentActivityName=".MainActivity"/>
<receiver android:name=".NotificationPublisher">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".DeviceBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I have created a new DeviceBootReceiver class:
public class DeviceBootReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
}
}
}
But I'm not sure what to put in the onReceive function. I tried putting this in the onReceive function
Intent pushIntent = new Intent(context, NotificationPublisher.class);
context.startService(pushIntent);
Works normal, but if I reboot my phone, after 5 minutes I get a message "The Application has stopped working"
I have a basic idea after having gone through these tutorials but I don't know how to implement them into my project
https://www.stacktips.com/tutorials/android/repeat-alarm-example-in-android
https://droidmentor.com/schedule-notifications-using-alarmmanager/
What I need is, to get the notification even after my phone is rebooted. If any one out there who could help me to achieve this, I would be grateful.
you need to create a BroadcastReceiver in order to be able to listen REBOOT event that is delivered by OS and then you can start your alarm manager there again
Well here is a complete example of an AutoStart Application.
Give permission of RECEIVE_BOOT_COMPLETED in manifest file, and register your broadcast for BOOT_COMPLETED.
AndroidManifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.saltriver" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".hello"></activity>
<service android:enabled="true" android:name=".service" />
</application>
</manifest>
autostart.java
public class autostart extends BroadcastReceiver
{
public void onReceive(Context context, Intent arg1)
{
// This callback will be fired automatically when device starts after boot
// Do your alarm alarm manager work here
}
}