当应用处于后台或关闭状态时,Android应用中的本地通知不会显示

我已经使用Service生成了本地通知。当应用程序打开时,通知窗口将正常运行并显示出来。但是,当应用程序进入后台或收到关闭的通知时,它们不会显示。当我重新打开我的应用程序时,所有通知都会显示。

关于这个问题,我经历了很多讨论。因此,我尝试了startForegroundAlarmManagerBroadcastReceiver,但没有任何帮助。仅当应用程序打开时,仍会显示本地通知。我发现,当我将电池设置设置为在手机设置中在后台运行我的应用程序时,它就可以正常工作,并且会显示通知。但是用户不会知道他应该这样做。

MyService:

public class MyService2 extends Service {

private boolean running = true;
private MyAsyncTask myAsyncTask;

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

public void onCreate() {
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent,int flags,int startId) {
    startForeground(1,showAndGetNotification(getapplicationContext(),"Twoja aplikacja działa w tle","",new Intent(getapplicationContext(),Mainactivity.class)));
    myAsyncTask = new MyAsyncTask();
    myAsyncTask.execute();
    return START_STICKY;
}

public void onDestroy() {
    super.onDestroy();
    stopForeground(true);
    stopSelf();
    if (myAsyncTask != null) {
        myAsyncTask.cancel(true);
    }
    running = false;
    SharedPreferences sharedPref = getSharedPreferences("service",activity.MODE_PRIVATE);
    boolean fromAppStop = sharedPref.getBoolean("fromAppStop",false);
    if (!fromAppStop) {
        Intent broadcastIntent = new Intent(this,SensorRestarterBroadcastReceiver.class);
        sendBroadcast(broadcastIntent);
    }
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putBoolean("fromAppStop",false);
    editor.commit();
}

private class MyAsyncTask extends AsyncTask<Void,Void,Void> {

    @Override
    protected Void doInBackground(Void... voids) {
        try {
            while (running) {
                List<Map<String,String>> medicinesToTake = getMedicinesToTake();
                for (Map<String,String> medicineToTake : medicinesToTake) {
                    String medicineName = medicineToTake.keySet().toArray()[0].toString();
                    Thread.sleep(countSleepToNextTake(medicineToTake.get(medicineName)));
                    doAlarm("Czas na lek",medicineName,medicineName);
                }
                Thread.sleep(countLeftTimeForNextDay());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}

private void doAlarm(String title,String medicineName,String body) {
    Intent intent = new Intent(getapplicationContext(),AlarmReceiver.class);
    intent.putExtra("title",title);
    intent.putExtra("medicineName",medicineName);
    intent.putExtra("body",body);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    int id = generateUniqueId();
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getapplicationContext(),id,intent,PendingIntent.flaG_CANCEL_CURRENT);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),pendingIntent);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP,pendingIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP,pendingIntent);
    }
}

public Notification showAndGetNotification(Context context,String title,String body,Intent intent) {
    Notificationmanager notificationmanager = (Notificationmanager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    Date now = new Date();
    int notificationId = Integer.parseInt(new SimpleDateFormat("ddHHmmss",Locale.UK).format(now)) + new Random().nextInt();
    //String channelId = "channel-01";
    String channelId = UUID.randomUUID().toString();
    String channelName = "Channel Name";
    int importance = Notificationmanager.IMPORTANCE_HIGH;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        NotificationChannel mChannel = new NotificationChannel(
                channelId,channelName,importance);
        notificationmanager.createNotificationChannel(mChannel);
    }

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context,channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setautoCancel(true)
            .setsound(RingtoneManager.getDefaulturi(RingtoneManager.TYPE_NOTIFICATION))
            .setContentText(body);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addNextIntent(intent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
            generateUniqueId(),PendingIntent.flaG_UPDATE_CURRENT
    );
    mBuilder.setContentIntent(resultPendingIntent);

    notificationmanager.notify(notificationId,mBuilder.build());

    return mBuilder.build();
}

private int generateUniqueId() {
    UUID idOne = UUID.randomUUID();
    String str = "" + idOne;
    int uid = str.hashCode();
    String filterStr = "" + uid;
    str = filterStr.replaceAll("-","");
    return Integer.parseInt(str);
}
}

MyAlarmReceiver:

public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context,Intent intent) {
    String medicineName = intent.getStringExtra("medicineName");
    String body = intent.getStringExtra("body");

    Intent notificationIntent = null;
    String title = intent.getStringExtra("title");
    if (title.equals("Czas na lek")) {
        notificationIntent = new Intent(context,TimeForMedicineactivity.class);
        notificationIntent.putExtra("medicineName",medicineName);
    } else if (title.equals("Twój lek się skończył")) {
        notificationIntent = new Intent(context,AddOrDeleteMyMedicineactivity.class);
    } else if (title.equals("Twój lek się kończy")) {
        notificationIntent = new Intent(context,Mainactivity.class);
    }

    Notificationmanager notificationmanager = (Notificationmanager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    Date now = new Date();
    int notificationId = Integer.parseInt(new SimpleDateFormat("ddHHmmss",Locale.UK).format(now)) + new Random().nextInt();
    String channelId = UUID.randomUUID().toString();
    String channelName = "Channel Name";
    int importance = Notificationmanager.IMPORTANCE_HIGH;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        NotificationChannel mChannel = new NotificationChannel(
                channelId,channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setautoCancel(true)
            .setsound(RingtoneManager.getDefaulturi(RingtoneManager.TYPE_NOTIFICATION))
            .setContentText(body);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addNextIntent(notificationIntent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
            generateUniqueId(),mBuilder.build());
}


private int generateUniqueId() {
    UUID idOne = UUID.randomUUID();
    String str = "" + idOne;
    int uid = str.hashCode();
    String filterStr = "" + uid;
    str = filterStr.replaceAll("-","");
    return Integer.parseInt(str);
}
}
yezhunan11 回答:当应用处于后台或关闭状态时,Android应用中的本地通知不会显示

问题出在华为使用的MIUI操作系统上。它违反了android规范,该规范要求将使用startForeground的服务视为前台。

我的应用程序中存在相同的问题。我没有找到更好的解决方案,除了检测应用程序是否在MIUI上运行,然后打开警报告诉用户如果他们想要前台,他们应该手动打开电池设置并将该应用程序添加到异常中。

您可以尝试

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (!pm.isIgnoringBatteryOptimizations(packageName)) {
            intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + packageName));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }

使用

<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

但是在MIUI上可能不起作用。

本文链接:https://www.f2er.com/3154204.html

大家都在问