前台通知服务在一加设备中不起作用

Foreground notification service not working in one plus devices

下面是启动前台服务的代码。 它适用于许多设备,如 Samsung、moto、Vivo、Oppo 以及 Android 版本的 nougat 和 oreo,但不适用于 One plus 设备。 谁能告诉我在一加设备中 运行 是否需要任何额外的更改或许可,或者是否有任何模拟器支持一加手机。

public class ForegroundService extends Service {

private Context ctx;
private static final String PRIMARY_NOTIF_CHANNEL = "default";

@Override
public void onCreate() {
    super.onCreate();
    ctx = this;
    createNotificationService();
}

private void createNotificationService(){

    TelephonyManager mTelephonyManager = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
    if(mTelephonyManager != null)
        mTelephonyManager.listen(new CellTowerStateListener(ctx), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

    Intent notificationIntent = new Intent(this, MainActivity.class);
    notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    //PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    RemoteViews notificationView = new RemoteViews(this.getPackageName(), R.layout.notification);

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

    Notification notification = new NotificationCompat.Builder(this, PRIMARY_NOTIF_CHANNEL)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setColor(Color.parseColor("#00f6d8"))
            .setContent(notificationView)
            .setPriority(Notification.PRIORITY_MIN)
            .setOngoing(true).build();

    startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, notification);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    return START_REDELIVER_INTENT;
}

private void setupChannel(){
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationChannel chan1;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        chan1 = new NotificationChannel(
                PRIMARY_NOTIF_CHANNEL,
                PRIMARY_NOTIF_CHANNEL,
                NotificationManager.IMPORTANCE_NONE);

        chan1.setLightColor(Color.TRANSPARENT);
        chan1.setLockscreenVisibility(Notification.VISIBILITY_SECRET);

        if(notificationManager != null)
            notificationManager.createNotificationChannel(chan1);
    }
}


@Override
public IBinder onBind(Intent intent) {
    // Used only in case of bound services.
    return null;
}

}

所以我在一小时前解决了这个问题:

清单

<application
    android:name=".AppNotification"
    android:allowBackup="true"
    android:icon="@mipmap/pro_icon"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/pro_icon"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
<service
        android:name=".services.TrackingBackgroundService"
        android:enabled="true"
        android:exported="true" />

应用程序 - 创建通知渠道

public class AppNotification extends Application {

public static final String CHANNEL_ID = "AppNotificationChannel";
private void CreateNotificationChannel() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        NotificationChannel serviceChannel = new NotificationChannel(
                CHANNEL_ID,
                "App Notification",
                NotificationManager.IMPORTANCE_HIGH
        );
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(serviceChannel);
    }
}

}

Activity

首先你需要要求用户禁用电池优化:

Intent intent = new Intent();
    String packageName = this.getPackageName();
    PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
    if (pm.isIgnoringBatteryOptimizations(packageName))
        intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
    else {
        intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + packageName));
        startActivity(intent);
    }

那么你需要像这样启动服务来处理不同的版本:

public void startService() {
    Intent serviceIntent = new Intent(InitSkipperActivity.this, TrackingBackgroundService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(serviceIntent);
    } else {
        startService(serviceIntent);
    }
}

服务

public class TrackingBackgroundService extends Service {

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

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

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Intent notificationIntent = new Intent(this, TrackingActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("title")
            .setContentText("content")
            .setSmallIcon(R.mipmap.pro_icon)
            .setPriority(5)
            .setContentIntent(pendingIntent)
            .build();
    startForeground(1, notification);

    return START_STICKY;
}

}

之后您需要使用 android 分析器测试您的服务:

我的应用程序使用异常 CPU 并且在 Oppo、OnePlus 和小米和三星上,当我离线跟踪时正在使用 50 到 60% CPU。发现它是一些线程,我称之为中断但仍然 运行

学会使用后,开始记录您的应用程序的片段并对其进行分析,您有 2 个不错的选择:

  • 样本Java方法

  • 跟踪Java方法

Android Logcat 很高兴看到 oneplus 的 BG 检测到试图删除您的服务,如果需要,还可以删除您的应用程序。

P.S:BGDetect无惧消除。在 OnePlus 和 Oppo 停止杀死我之前,我需要将我的在线和离线跟踪性能在应用程序中平均提高 20% 到 30%,在睡眠中提高到 15% 到 20%,而不给我重启服务的机会。

你可能已经注意到,当这些 OS 想要杀死他们从应用程序而不是服务启动的东西时,请记住:如果你这样做,请不要将应用程序绑定到服务 我这样做不知道为什么,OS就更狠了。

BG-Detect 太多了 -> 他们应该在重新实现函数

时向 android 开发人员发出警告

P.P.S 太多了,但我带上了我的帽子 OnePlus BugHunters,它的 damm 实现得很好。

希望我能帮到你。

在 OP3 Oreo 8.0.1 上测试

已编辑

重启后的 OnePlus 会将您的应用设置为再次优化。正在测试以解决问题

在所有设备上使用我的方法

 private void checkOptimization() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        String packageName = getApplicationContext().getPackageName();
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        if (pm != null) {
            if (!pm.isIgnoringBatteryOptimizations(packageName)) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivity(intent);
            }
        }
    }

}