Eloa Barretto
Eloa Barretto

Reputation: 21

Alarm Manager does not show notification api 26

Works perfectly in the verses until api 25. I am new to android and working on Notification Alarm Manager to show notification.

Can Any one help me what is the error in it?

Main Activity:

package br.exemploalarmmanagerbn;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        boolean alarmeAtivo = (PendingIntent.getBroadcast(this, 0, new Intent("ALARME_DISPARADO"), PendingIntent.FLAG_NO_CREATE) == null);
        
        if(alarmeAtivo){
            Log.i("Script", "Novo alarme");
            
            Intent intent = new Intent("ALARME_DISPARADO");
            PendingIntent p = PendingIntent.getBroadcast(this, 0, intent, 0);
            
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(System.currentTimeMillis());
            c.add(Calendar.SECOND, 3);
            
            AlarmManager alarme = (AlarmManager) getSystemService(ALARM_SERVICE);
            alarme.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 5000, p);
        }
        else{
            Log.i("Script", "Alarme já ativo");
        }
    }
    
    @Override
    public void onDestroy(){
        super.onDestroy();
        
        /*Intent intent = new Intent("ALARME_DISPARADO");
        PendingIntent p = PendingIntent.getBroadcast(this, 0, intent, 0);
        
        AlarmManager alarme = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarme.cancel(p);*/
    }
} 

BroadcastReceiverAux

package br.exemploalarmmanagerbn;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

public class BroadcastReceiverAux extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        
        Log.i("Script", "-> Alarme");
        
        gerarNotificacao(context, new Intent(context, MainActivity.class), "Nova mensagem", "Título", "Descrição nova mensagem");
    }
    
    
    public void gerarNotificacao(Context context, Intent intent, CharSequence ticker, CharSequence titulo, CharSequence descricao){

if (Build.VERSION.SDK_INT >= 26) {
            if (nm.getNotificationChannel(CHANNEL_ID) == null) {
                nm.createNotificationChannel(new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
                        NotificationManager.IMPORTANCE_DEFAULT));
            }
        }

        NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        PendingIntent p = PendingIntent.getActivity(context, 0, intent, 0);
        
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        builder.setTicker(ticker);
        builder.setContentTitle(titulo);
        builder.setContentText(descricao);
        builder.setSmallIcon(R.drawable.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher));
        builder.setContentIntent(p);
        
        Notification n = builder.build();
        n.vibrate = new long[]{150, 300, 150, 600};
        n.flags = Notification.FLAG_AUTO_CANCEL;
        nm.notify(R.drawable.ic_launcher, n);
        
        try{
            Uri som = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            Ringtone toque = RingtoneManager.getRingtone(context, som);
            toque.play();
        }
        catch(Exception e){}
    }
}

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.exemploalarmmanagerbn"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.VIBRATE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="br.exemploalarmmanagerbn.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>
        <receiver android:name="BroadcastReceiverAux" android:label="BroadcastReceiverAux">
            <intent-filter>
                <action android:name="ALARME_DISPARADO"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

Upvotes: 2

Views: 1510

Answers (3)

Abu bakar
Abu bakar

Reputation: 881

Tested and perfectly working on API 32 as well.

First create a notification channel like this:

@RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel() {

        val name = "Notification Channel"
        val desc = "A Description of the Channel"
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(channelID, name, importance)
        channel.description = desc

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }

then call this function inside your onCreate() or at least before setting up your Alarm Manager like this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel()
}

After this, create Notification helper class like this, basically a Broadcast Receiver:

class Notification : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val notification = NotificationCompat.Builder(context, channelID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle(intent.getStringExtra(titleExtra))
            .setContentText(intent.getStringExtra(messageExtra))
            .build()

        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        manager.notify(notificationID, notification)
    }
}

And don't forget to register it in the manifest like this inside Application tag:

<receiver
      android:name=".Notification"
      android:enabled="true" />

Finally, you can use the below function to schedule an alarm, it uses Notification class for Broadcast Receiver, you can pass any necessary data through intents and get them inside Notification class. The getTime() function can be used to fetch the current time in milliseconds. If you wanna set your own time then you can use it's set method that I commented out.

@RequiresApi(Build.VERSION_CODES.M)
    private fun scheduleNotification() {

        val intent = Intent(this, Notification::class.java)
        intent.putExtra(titleExtra, "title")
        intent.putExtra(messageExtra, "message")

        val pendingIntent = PendingIntent.getBroadcast(
            this,
            1,
            intent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        var time = getTime()

        alarmManager.setExactAndAllowWhileIdle(
            AlarmManager.RTC_WAKEUP,
            time,
            pendingIntent
        )
    }

    private fun getTime(): Long {

        val calendar = Calendar.getInstance()
        // calendar.set(globalYear, globalMonth, globalDay, globalHour, globalMinute)
        return calendar.timeInMillis
    }

You can call above function like this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    scheduleNotification()
}

Lastly, if you are using API 32 then you need this permission in the manifest:

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

Let me know if something doesn't work out! :)

Upvotes: 0

user3762591
user3762591

Reputation: 1

Try sending notifications from IntentService:

  1. Create IntentService (do not forget to declare it in the manifest)
  2. Move the gerarNotificacao () method to the IntentService class
  3. Run IntentService from your BroadcastReceiver's onReceive () method
  4. Inside the IntentService, call gerarNotificacao () in the onHandleIntent () method

Upvotes: 0

Prakash S
Prakash S

Reputation: 652

You have to create notification channel first and then use that channel to post notificatins

NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// The id of the channel.
String id = "my_channel_01";
// The user-visible name of the channel.
CharSequence name = getString(R.string.channel_name);
// The user-visible description of the channel.
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
mNotificationManager.createNotificationChannel(mChannel);


// The id of the channel.
String CHANNEL_ID = "my_channel_01";
NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!");

Upvotes: 1

Related Questions