android - 手机锁定时保持应用程序运行的问题

标签 android notifications garbage-collection wakelock

所以我遇到了一个恼人的问题。我目前正在开发一个用于跟踪用户 sleep 的应用程序。我们有一项服务可以发出声纳并收听返回的波浪。为此,服务需要整夜运行,并且由于其他一些问题,我们需要锁定屏幕。该服务由一个对象启动,我们将接口(interface)传递给该对象以处理与处理相关的回调。目前,调用 Activity 正在实现此接口(interface)以正确响应回调。

现在我遇到的问题有时是在监视 session 期间,服务被终止或应用程序被终止。为了消除被系统杀死的可能性,我正在寻找策略来尝试向系统识别该应用程序正在运行并且即使屏幕被锁定也需要整夜运行。

首先,我尝试使用唤醒锁:PowerManager.PARTIAL_WAKE_LOCK

我最近在 session 运行时添加了一个托盘通知,试图让它保持 Activity 状态,但效果不是很好

public class Notification extends ContextWrapper {
    Context context;

    public Notification(Context base) {
        super(base);
        this.context = base;
        createChannels();
    }

    private NotificationManager mManager;

    public void createChannels() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel sessionChannel = new NotificationChannel(Constants.Notification.TRACKING_CHANNEL,
                    Constants.Notification.ANDROID_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
            sessionChannel.enableLights(false);
            sessionChannel.enableVibration(false);
            getManager().createNotificationChannel(sessionChannel);
            NotificationChannel  bedtimeChannel = new NotificationChannel(Constants.Notification.BEDTIME_CHANNEL,
                    Constants.Notification.ANDROID_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            getManager().createNotificationChannel(bedtimeChannel);

        }
    }

    public NotificationManager getManager() {
        if (mManager == null) {
            mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mManager;
    }

    public NotificationCompat.Builder getTrackingChannelNotification(String title, String body) {
        Intent trackingIntent = new Intent(context, SessionRecordingActivity.class);
        trackingIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, trackingIntent, 0);

        return new NotificationCompat.Builder(getApplicationContext(), Constants.Notification.TRACKING_CHANNEL)
                .setContentTitle(title)
                .setContentText(body)
                .setContentIntent(pendingIntent)
                .setOngoing(true)
                .setSmallIcon(R.mipmap.ic_launcher_new);
    }

    public NotificationCompat.Builder getBedTimeChannelNotification(String title, String body, Intent actionIntent) {
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, actionIntent, 0);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        return new NotificationCompat.Builder(getApplicationContext(), Constants.Notification.TRACKING_CHANNEL)
                .setSmallIcon(R.mipmap.ic_launcher_new)
                .setContentTitle(title)
                .setContentText(body)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(body))
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(pendingIntent)
                .setSound(defaultSoundUri)
                .setAutoCancel(true);
    }
}

这是我在服务启动后所做的事情:

NotificationCompat.Builder nb = mNotification.getTrackingChannelNotification(getString(R.string.tracking_in_progress), getString(R.string.sleep_well));
mNotification.getManager().notify(Constants.Notification.TRACKING_ID, nb.build());

然后我在 session 结束时执行此操作:

mNotification.getManager().cancel(Constants.Notification.TRACKING_ID);

那么对于我的问题:我还能做些什么来向系统确定我的应用程序需要继续运行直到用户结束它? (顺便说一句,该服务不是由我的应用程序直接启动的,它是由第三方库启动该服务的)。

编辑:经过进一步调查,现在看来可能是我的 Activity/应用程序被杀死,而不是服务。除了唤醒锁定或托盘通知之外,还有其他方法可以在屏幕锁定时让我的应用程序保持 Activity 状态吗?

最佳答案

您必须在 Oncreate() 中为您使用 Context.startForegroundService() 的服务调用 startForeground

@Override
public void onCreate() {
    super.onCreate();

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        String CHANNEL_ID = "my_channel_01";
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_DEFAULT);

        ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("")
                .setContentText("").build();

        startForeground(1, notification);
    }
}

您可以从这个 link 中了解更多信息

关于android - 手机锁定时保持应用程序运行的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53111114/

相关文章:

java - 如何将此 Android 电子邮件发送代码投入使用?

java - Android 无法解析符号 auth_failed

java - 我可以将 C++ 垃圾收集器附加到对 C/C++ 库进行 JNI 调用的 Java 程序吗?

java - 可运行对象与方法引用和垃圾

java - 如何从 WakefulBroadcastReceiver 启动 IntentService

Android SQLite 插入行时遇到问题

ios - 如何安排和重复本地通知

javascript - 显示 Chrome 扩展程序的通知

android - 将新条目添加到数据库时如何向服务器应用程序发送通知

c++ - 运行时系统如何在已编译的二进制文件上支持 "GC"?