前台通知服务无法在一台设备中使用

时间:2018-12-04 11:48:15

标签: android foreground-service oneplusone oneplusthree foregroundnotification

下面是用于启动前台服务的代码。 它对于许多设备(如三星,moto,Vivo,Oppo)以及Android版本的牛轧糖和oreo都可以正常工作,但不能在One plus设备上运行。 任何人都可以让我知道是否需要在One Plus设备上运行任何其他更改或权限,或者是否有任何仿真器支持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;
}

}

2 个答案:

答案 0 :(得分:1)

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

清单

<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);
    }
}

}

活动

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

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 profiler测试您的服务:

我的应用使用了异常的CPU使用率,当我离线跟踪时,在Oppo,OnePlus,小米和三星上使用 50至60%的CPU。发现我调用了一些线程但仍在运行

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

  • 示例Java方法

  • 跟踪Java方法

Android Logcat很高兴看到BG检测到oneplus试图删除您的服务以及是否需要您的应用程序。

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

正如您可能已经注意到的那样,当这些操作系统要杀死它们是从应用程序启动而不是从服务启动时,请记住:不要将应用程序绑定到服务中,我不知道为什么,但是操作系统更加无情。

BG-Detect太多->当重新实现该功能时,应该给android devs警告

P.P.S 太多了,但是我戴上了帽子,OnePlus BugHunters,实现得很好。

希望我能帮上忙。

在OP3 Oreo 8.0.1上进行了测试

已编辑

重新启动时,OnePlus会重新设置您的应用程序。我正在测试以修复问题

答案 1 :(得分:0)

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

 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);
            }
        }
    }

}