Java 安卓:手机重启后设置闹钟/提醒

Java 安卓:手机重启后设置闹钟/提醒,java,android,service,alarmmanager,android-reboot,Java,Android,Service,Alarmmanager,Android Reboot,我正在开发一款集成了提醒功能的Android应用程序。 如果手机一直开着,通知就会起作用,但当我关机或重新启动时,我会丢失所有的闹钟。 我知道这是Android的一项功能,可以提高手机的使用效率,但我不知道该怎么办,我该如何解决这个问题 这是我的文件: AlarmService.java AlarmReceiver.java BootAlarmReceiver.java AndroidManifest.xml 当手机开机时,“BootAlarmReceiver.java”会调用“AlarmS

我正在开发一款集成了提醒功能的Android应用程序。 如果手机一直开着,通知就会起作用,但当我关机或重新启动时,我会丢失所有的闹钟。 我知道这是Android的一项功能,可以提高手机的使用效率,但我不知道该怎么办,我该如何解决这个问题

这是我的文件:

  • AlarmService.java

  • AlarmReceiver.java

  • BootAlarmReceiver.java

  • AndroidManifest.xml

当手机开机时,“BootAlarmReceiver.java”会调用“AlarmService.java”,它应该,但它不会重新加载我的所有闹钟。 当AlarmManager触发报警时,调用“AlarmReceiver.java”

代码如下:

AlarmService.java

public class AlarmService extends IntentService {
    public AlarmService() {
        super("AlarmService");
    }
@Override
protected void onHandleIntent(@Nullable Intent intent) {
    Calendar calendar = Calendar.getInstance();
    FileInputStream fileInputStream = null;
    int requestCode, year, month, day, hour, minute;
    String note, with;

    try {
        fileInputStream = openFileInput("my_alarms.csv");
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String row;

        while ((row = bufferedReader.readLine()) != null) {
            String[] splittedRow = row.split(";");
            requestCode = Integer.valueOf(splittedRow[0]);
            year = Integer.valueOf(splittedRow[1]);
            month = Integer.valueOf(splittedRow[2]);
            day = Integer.valueOf(splittedRow[3]);
            hour = Integer.valueOf(splittedRow[4]);
            minute = Integer.valueOf(splittedRow[5]);
            note = splittedRow[6];
            with = splittedRow[7];

            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, 0);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent alarmIntent = new Intent(this, AlarmReceiver.class);
            alarmIntent.putExtra("note", note + "\nCon: " + with);
            alarmIntent.putExtra("title", "My Memo");
            alarmIntent.putExtra("alarm", "memo");

            //requestCode must be incremental to create multiple reminders
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, alarmIntent, 0);

            if (calendar.before(Calendar.getInstance())) {
                calendar.add(Calendar.DATE, 1);
            }

            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class AlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getStringExtra("alarm").equals("memo")) {
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                @SuppressLint("WrongConstant") NotificationChannel notificationChannel = new NotificationChannel("memo_channel", "My Memo", NotificationManager.IMPORTANCE_MAX);
                notificationChannel.setDescription("Memo Notification Channel");
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.BLUE);
                notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
                notificationChannel.enableVibration(true);
                notificationManager.createNotificationChannel(notificationChannel);
            }
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "memo_channel");
            notificationBuilder.setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setWhen(System.currentTimeMillis())
                    .setShowWhen(true)
                    .setTicker("Reminder")
                    .setContentTitle("Memo")
                    .setContentText(intent.getStringExtra("note"))
                    .setContentInfo("Information")
                    .setSmallIcon(R.drawable.ic_alarm);

            notificationManager.notify(1, notificationBuilder.build());
        }
    }
}
public class BootAlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
            Intent alarmServiceIntent = new Intent(context, AlarmService.class);
            ComponentName service = context.startService(alarmServiceIntent);

            if (service == null) {
                Log.e("ALARM", "Could not start service");
            } else {
                Log.e("ALARM", "Could start service");
            }
        }
    }
}
}

AlarmReceiver.java

public class AlarmService extends IntentService {
    public AlarmService() {
        super("AlarmService");
    }
@Override
protected void onHandleIntent(@Nullable Intent intent) {
    Calendar calendar = Calendar.getInstance();
    FileInputStream fileInputStream = null;
    int requestCode, year, month, day, hour, minute;
    String note, with;

    try {
        fileInputStream = openFileInput("my_alarms.csv");
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String row;

        while ((row = bufferedReader.readLine()) != null) {
            String[] splittedRow = row.split(";");
            requestCode = Integer.valueOf(splittedRow[0]);
            year = Integer.valueOf(splittedRow[1]);
            month = Integer.valueOf(splittedRow[2]);
            day = Integer.valueOf(splittedRow[3]);
            hour = Integer.valueOf(splittedRow[4]);
            minute = Integer.valueOf(splittedRow[5]);
            note = splittedRow[6];
            with = splittedRow[7];

            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, 0);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent alarmIntent = new Intent(this, AlarmReceiver.class);
            alarmIntent.putExtra("note", note + "\nCon: " + with);
            alarmIntent.putExtra("title", "My Memo");
            alarmIntent.putExtra("alarm", "memo");

            //requestCode must be incremental to create multiple reminders
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, alarmIntent, 0);

            if (calendar.before(Calendar.getInstance())) {
                calendar.add(Calendar.DATE, 1);
            }

            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class AlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getStringExtra("alarm").equals("memo")) {
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                @SuppressLint("WrongConstant") NotificationChannel notificationChannel = new NotificationChannel("memo_channel", "My Memo", NotificationManager.IMPORTANCE_MAX);
                notificationChannel.setDescription("Memo Notification Channel");
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.BLUE);
                notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
                notificationChannel.enableVibration(true);
                notificationManager.createNotificationChannel(notificationChannel);
            }
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "memo_channel");
            notificationBuilder.setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setWhen(System.currentTimeMillis())
                    .setShowWhen(true)
                    .setTicker("Reminder")
                    .setContentTitle("Memo")
                    .setContentText(intent.getStringExtra("note"))
                    .setContentInfo("Information")
                    .setSmallIcon(R.drawable.ic_alarm);

            notificationManager.notify(1, notificationBuilder.build());
        }
    }
}
public class BootAlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
            Intent alarmServiceIntent = new Intent(context, AlarmService.class);
            ComponentName service = context.startService(alarmServiceIntent);

            if (service == null) {
                Log.e("ALARM", "Could not start service");
            } else {
                Log.e("ALARM", "Could start service");
            }
        }
    }
}
BootAlarmReceiver.java

public class AlarmService extends IntentService {
    public AlarmService() {
        super("AlarmService");
    }
@Override
protected void onHandleIntent(@Nullable Intent intent) {
    Calendar calendar = Calendar.getInstance();
    FileInputStream fileInputStream = null;
    int requestCode, year, month, day, hour, minute;
    String note, with;

    try {
        fileInputStream = openFileInput("my_alarms.csv");
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String row;

        while ((row = bufferedReader.readLine()) != null) {
            String[] splittedRow = row.split(";");
            requestCode = Integer.valueOf(splittedRow[0]);
            year = Integer.valueOf(splittedRow[1]);
            month = Integer.valueOf(splittedRow[2]);
            day = Integer.valueOf(splittedRow[3]);
            hour = Integer.valueOf(splittedRow[4]);
            minute = Integer.valueOf(splittedRow[5]);
            note = splittedRow[6];
            with = splittedRow[7];

            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, 0);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent alarmIntent = new Intent(this, AlarmReceiver.class);
            alarmIntent.putExtra("note", note + "\nCon: " + with);
            alarmIntent.putExtra("title", "My Memo");
            alarmIntent.putExtra("alarm", "memo");

            //requestCode must be incremental to create multiple reminders
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, alarmIntent, 0);

            if (calendar.before(Calendar.getInstance())) {
                calendar.add(Calendar.DATE, 1);
            }

            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class AlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getStringExtra("alarm").equals("memo")) {
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                @SuppressLint("WrongConstant") NotificationChannel notificationChannel = new NotificationChannel("memo_channel", "My Memo", NotificationManager.IMPORTANCE_MAX);
                notificationChannel.setDescription("Memo Notification Channel");
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.BLUE);
                notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
                notificationChannel.enableVibration(true);
                notificationManager.createNotificationChannel(notificationChannel);
            }
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "memo_channel");
            notificationBuilder.setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setWhen(System.currentTimeMillis())
                    .setShowWhen(true)
                    .setTicker("Reminder")
                    .setContentTitle("Memo")
                    .setContentText(intent.getStringExtra("note"))
                    .setContentInfo("Information")
                    .setSmallIcon(R.drawable.ic_alarm);

            notificationManager.notify(1, notificationBuilder.build());
        }
    }
}
public class BootAlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
            Intent alarmServiceIntent = new Intent(context, AlarmService.class);
            ComponentName service = context.startService(alarmServiceIntent);

            if (service == null) {
                Log.e("ALARM", "Could not start service");
            } else {
                Log.e("ALARM", "Could start service");
            }
        }
    }
}
AndroidManifest.xml

<manifest>
    <application>
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
        <uses-permission android:name="android.permission.VIBRATE" />

        //Other code here

        <receiver
            android:name=".BootAlarmReceiver"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <receiver android:name=".AlarmReceiver" />
        <service android:name=".AlarmService" />
    </application>
</manifest>

我该怎么办?

一些品牌正在使用额外的策略来加快启动和电池优化。例如,小米对此具有自动启动权限。如果您想在重新启动后不中断地继续报警,则必须授予您此权限。(设置/应用程序/您的应用程序/自动启动)。许多制造商都有类似的产品

你能做什么

您可以通过编程方式请求自动启动权限,也可以请求忽略电池优化权限

这些问题/答案对你有帮助

编辑:您的日志显示您没有权限在启动完成后启动服务

你必须谷歌“如何在LG6中白名单你的应用”和“如何获得LG的自动启动许可”。因为这个问题与品牌和设备有关。我不可能确切地告诉你应该做什么


即使您说您检查了所有内容,但权限中仍缺少一些内容解决方案:

public class BootAlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {

            Intent alarmServiceIntent = new Intent(context, AlarmService.class);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(alarmServiceIntent);
            } else {
                context.startService(alarmServiceIntent);
            }
        }
    }
}
大家好,我发现了我遇到的问题,我的代码是正确的,工作正常,问题出在我设备的操作系统上,从Android OS Oreo开始,启动服务的命令已更改,需要一个新的命令语法:

更改位于“BootAlarmReceiver.java”中

以前的代码:

public class BootAlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
            Intent alarmServiceIntent = new Intent(context, AlarmService.class);
            ComponentName service = context.startService(alarmServiceIntent);

            if (service == null) {
                Log.e("ALARM", "Could not start service");
            } else {
                Log.e("ALARM", "Could start service");
            }
        }
    }
}
新代码:

public class BootAlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {

            Intent alarmServiceIntent = new Intent(context, AlarmService.class);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(alarmServiceIntent);
            } else {
                context.startService(alarmServiceIntent);
            }
        }
    }
}
因此,如果您在Oreo或更高版本上运行,您应该使用
.startForegroundService(yourIntent)
,否则您应该使用
.startService(yourIntent)


此解决方案也适用于您。

您丢失了哪些设备(品牌)?@ErenTüfekçi我正在使用我的物理设备LG G6。然后我发现了这个错误:无法启动receiver com.package.appname.BootAlarmReceiver:java.lang.IllegalStateException:不允许启动服务意图谢谢,现在我来看看这些主题,我会让你知道它是否能工作我已经检查了所有内容,我的应用程序拥有启动时启动的所有权限。。。我还是不知道该怎么办。