如果退出应用程序,AlarmManager 警报将不起作用

发布于 2025-01-11 10:49:09 字数 5495 浏览 2 评论 0原文

我有一个闹钟应用程序。当我创建警报时,它运行良好(如果不退出应用程序),但如果退出,则警报不起作用。 我希望即使应用程序关闭且手机处于睡眠模式时闹钟也能工作。这是我的代码:

AlarmFragment(从中设置闹钟):

package org.vitaliy.numbell.Fragments;

public class AlarmFragment extends Fragment {

ImageButton add_btn;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_alarm, container, false);

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());

    add_btn = view.findViewById(R.id.add_btn);

    add_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Calendar cur_time = Calendar.getInstance();
            MaterialTimePicker materialTimePicker = new MaterialTimePicker.Builder()
                    .setTimeFormat(TimeFormat.CLOCK_24H)
                    .setHour(cur_time.get(Calendar.HOUR_OF_DAY))
                    .setMinute(cur_time.get(Calendar.MINUTE))
                    .build();

            materialTimePicker.addOnPositiveButtonClickListener(new View.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void onClick(View view) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(Calendar.SECOND, 0);
                    calendar.set(Calendar.MILLISECOND, 0);
                    calendar.set(Calendar.MINUTE, materialTimePicker.getMinute());
                    calendar.set(Calendar.HOUR_OF_DAY, materialTimePicker.getHour());

                    //Set alarm clock
                    AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(ALARM_SERVICE);
                    AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), getAlarmInfoPendingIntent());
                    alarmManager.setAlarmClock(alarmClockInfo, getAlarmActionPendingIntent());

                }
            });

            materialTimePicker.show(getActivity().getSupportFragmentManager(),"tag_picker");

        }
    });

    return view;
}

private PendingIntent getAlarmInfoPendingIntent() {
    Intent alarmInfoIntent = new Intent(getActivity(), StartActivity.class);
    alarmInfoIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    return PendingIntent.getActivity(getActivity(),0,alarmInfoIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}

private PendingIntent getAlarmActionPendingIntent() {
    Intent intent = new Intent(getActivity(), AlarmActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    return PendingIntent.getActivity(getActivity(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

}

AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.vitaliy.numbell">

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

<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/Theme.Numbell">

    <activity android:name=".AlarmActivity" />

    <receiver
        android:name=".Widget"
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_info" />
    </receiver>

    <activity
        android:name=".AppActivity"
        android:configChanges="colorMode|keyboardHidden|screenSize|orientation|locale"
        android:exported="false"
        android:screenOrientation="portrait" />
    <activity
        android:name=".StartActivity"
        android:configChanges="colorMode|keyboardHidden|screenSize|orientation|locale"
        android:exported="true"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

AlarmActivity(闹钟响起时打开的活动):

package org.vitaliy.numbell;

public class AlarmActivity extends AppCompatActivity {

Ringtone ringtone;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_alarm);
    WindowCompat.setDecorFitsSystemWindows(getWindow(), false);

    Uri notificationUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
    ringtone = RingtoneManager.getRingtone(this, notificationUri);
    if(ringtone==null){
        notificationUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        ringtone = RingtoneManager.getRingtone(this, notificationUri);
    }
    if(ringtone != null){
        ringtone.play();
    }
}

@Override
protected void onDestroy() {
    if(ringtone != null && ringtone.isPlaying()){
        ringtone.stop();
    }
    super.onDestroy();
}

}

I have an alarm clock app. When I create an alarm, it works well (If you do not exit the application), but if you exit, then the alarm does not work.
I want the alarm to work even when the application is turned off and the phone is in sleep mode. Here is my code:

AlarmFragment (From which the alarm is set):

package org.vitaliy.numbell.Fragments;

public class AlarmFragment extends Fragment {

ImageButton add_btn;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_alarm, container, false);

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());

    add_btn = view.findViewById(R.id.add_btn);

    add_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Calendar cur_time = Calendar.getInstance();
            MaterialTimePicker materialTimePicker = new MaterialTimePicker.Builder()
                    .setTimeFormat(TimeFormat.CLOCK_24H)
                    .setHour(cur_time.get(Calendar.HOUR_OF_DAY))
                    .setMinute(cur_time.get(Calendar.MINUTE))
                    .build();

            materialTimePicker.addOnPositiveButtonClickListener(new View.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void onClick(View view) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(Calendar.SECOND, 0);
                    calendar.set(Calendar.MILLISECOND, 0);
                    calendar.set(Calendar.MINUTE, materialTimePicker.getMinute());
                    calendar.set(Calendar.HOUR_OF_DAY, materialTimePicker.getHour());

                    //Set alarm clock
                    AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(ALARM_SERVICE);
                    AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), getAlarmInfoPendingIntent());
                    alarmManager.setAlarmClock(alarmClockInfo, getAlarmActionPendingIntent());

                }
            });

            materialTimePicker.show(getActivity().getSupportFragmentManager(),"tag_picker");

        }
    });

    return view;
}

private PendingIntent getAlarmInfoPendingIntent() {
    Intent alarmInfoIntent = new Intent(getActivity(), StartActivity.class);
    alarmInfoIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    return PendingIntent.getActivity(getActivity(),0,alarmInfoIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}

private PendingIntent getAlarmActionPendingIntent() {
    Intent intent = new Intent(getActivity(), AlarmActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    return PendingIntent.getActivity(getActivity(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

}

AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.vitaliy.numbell">

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

<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/Theme.Numbell">

    <activity android:name=".AlarmActivity" />

    <receiver
        android:name=".Widget"
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_info" />
    </receiver>

    <activity
        android:name=".AppActivity"
        android:configChanges="colorMode|keyboardHidden|screenSize|orientation|locale"
        android:exported="false"
        android:screenOrientation="portrait" />
    <activity
        android:name=".StartActivity"
        android:configChanges="colorMode|keyboardHidden|screenSize|orientation|locale"
        android:exported="true"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

AlarmActivity (Activity that opens when the alarm goes off):

package org.vitaliy.numbell;

public class AlarmActivity extends AppCompatActivity {

Ringtone ringtone;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_alarm);
    WindowCompat.setDecorFitsSystemWindows(getWindow(), false);

    Uri notificationUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
    ringtone = RingtoneManager.getRingtone(this, notificationUri);
    if(ringtone==null){
        notificationUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        ringtone = RingtoneManager.getRingtone(this, notificationUri);
    }
    if(ringtone != null){
        ringtone.play();
    }
}

@Override
protected void onDestroy() {
    if(ringtone != null && ringtone.isPlaying()){
        ringtone.stop();
    }
    super.onDestroy();
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

℉服软 2025-01-18 10:49:09

更好的方法是当应用程序不在后台时通过通知(广播接收器)显示警报,并且当手机锁定或处于待机状态时,您可以在那里调用活动。

首先,将这两行添加到清单中以在锁定屏幕上显示活动:

<activity
    android:name=".AppActivity"
    android:configChanges="colorMode|keyboardHidden|screenSize|orientation|locale"
    android:exported="false"
    android:screenOrientation="portrait"
    android:showOnLockScreen="true"
    android:showWhenLocked="true" />

之后,您可以使用 KeyGuardManager 和 PowerManager 检查手机处于哪种状态:

 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
 KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            if (pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked()) {
                // This will be helpful to show your activity or notification on lock screen
            }

A better approach to this can be to show alarm via notifications (Broadcast Receiver) when app is not in background and when phone is locked or on standby you can call an activity there.

First off all add these two lines to Manifest to show activities on lockscreen:

<activity
    android:name=".AppActivity"
    android:configChanges="colorMode|keyboardHidden|screenSize|orientation|locale"
    android:exported="false"
    android:screenOrientation="portrait"
    android:showOnLockScreen="true"
    android:showWhenLocked="true" />

After this you can use KeyGuardManager and PowerManager to check in which state your phone is:

 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
 KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            if (pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked()) {
                // This will be helpful to show your activity or notification on lock screen
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文