0

我的前臺服務在Android Oreo上運行時不顯示通知。前臺服務通知未顯示在Android 8上。+

當我做targetSdkVersion2625這個問題消失它完美地在Android版本,從15到25 。但是這個解決方案似乎並不好。

我準備了test project這個問題。

我該怎麼辦才能在Android Oreo上修復它targetSdkVersion 26

我的前臺服務,SoundService.java(full source):

 public class SoundService extends Service implements MediaPlayer.OnErrorListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnBufferingUpdateListener { 
      private final static String TAG = SoundService.class.getSimpleName(); 
      static private int mStateService = MusicConstants.STATE_SERVICE.NOT_INIT; 
      private final Uri mUriRadioDefault = Uri.parse("https://nfw.ria.ru/flv/audio.aspx?ID=75651129&type=mp3"); 
      private final Object mLock = new Object(); 
      private final Handler mHandler = new Handler(); 
      private MediaPlayer mPlayer; 
      private Uri mUriRadio; 
      private NotificationManager mNotificationManager; 
      private WifiManager.WifiLock mWiFiLock; 
      private PowerManager.WakeLock mWakeLock; 
      private Handler mTimerUpdateHandler = new Handler(); 
      private Runnable mTimerUpdateRunnable = new Runnable() { 

       @Override 
       public void run() { 
        mNotificationManager.notify(MusicConstants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); 
        mTimerUpdateHandler.postDelayed(this, MusicConstants.DELAY_UPDATE_NOTIFICATION_FOREGROUND_SERVICE); 
       } 
      }; 
      private Runnable mDelayedShutdown = new Runnable() { 

       public void run() { 
        unlockWiFi(); 
        unlockCPU(); 
        stopForeground(true); 
        stopSelf(); 
       } 

      }; 

      public SoundService() { 
      } 

      public static int getState() { 
       return mStateService; 
      } 

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

      @Override 
      public void onCreate() { 
       super.onCreate(); 
       mStateService = MusicConstants.STATE_SERVICE.NOT_INIT; 
       mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
       mUriRadio = mUriRadioDefault; 
      } 

      @Override 
      public int onStartCommand(Intent intent, int flags, int startId) { 

       if (intent == null) { 
        stopForeground(true); 
        stopSelf(); 
        return START_NOT_STICKY; 
       } 


       switch (intent.getAction()) { 
        case MusicConstants.ACTION.START_ACTION: 
         mStateService = MusicConstants.STATE_SERVICE.PREPARE; 
         startForeground(MusicConstants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); 
         destroyPlayer(); 
         initPlayer(); 
         play(); 
         break; 

        case MusicConstants.ACTION.PAUSE_ACTION: 
         mStateService = MusicConstants.STATE_SERVICE.PAUSE; 
         mNotificationManager.notify(MusicConstants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); 
         destroyPlayer(); 
         mHandler.postDelayed(mDelayedShutdown, MusicConstants.DELAY_SHUTDOWN_FOREGROUND_SERVICE); 
         break; 

        case MusicConstants.ACTION.PLAY_ACTION: 
         mStateService = MusicConstants.STATE_SERVICE.PREPARE; 
         mNotificationManager.notify(MusicConstants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); 

         destroyPlayer(); 
         initPlayer(); 
         play(); 
         break; 

        case MusicConstants.ACTION.STOP_ACTION: 
         Log.i(TAG, "Received Stop Intent"); 
         destroyPlayer(); 
         stopForeground(true); 
         stopSelf(); 
         break; 

        default: 
         stopForeground(true); 
         stopSelf(); 
       } 
       return START_NOT_STICKY; 
      } 

      @Override 
      public void onDestroy() { 
       destroyPlayer(); 
       mStateService = MusicConstants.STATE_SERVICE.NOT_INIT; 
       try { 
        mTimerUpdateHandler.removeCallbacksAndMessages(null); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       super.onDestroy(); 
      } 

      private void destroyPlayer() { 
       if (mPlayer != null) { 
        try { 
         mPlayer.reset(); 
         mPlayer.release(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } finally { 
         mPlayer = null; 
        } 
       } 
       unlockWiFi(); 
       unlockCPU(); 

      } 

      public boolean onError(MediaPlayer mp, int what, int extra) { 
       destroyPlayer(); 
       mHandler.postDelayed(mDelayedShutdown, MusicConstants.DELAY_SHUTDOWN_FOREGROUND_SERVICE); 
       mNotificationManager.notify(MusicConstants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); 
       mStateService = MusicConstants.STATE_SERVICE.PAUSE; 
       return false; 
      } 

    ... 
    //Part of code was skipped 
    ... 

      private Notification prepareNotification() { 

       Intent notificationIntent = new Intent(this, MainActivity.class); 
       notificationIntent.setAction(MusicConstants.ACTION.MAIN_ACTION); 
       if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { 
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
       } else { 
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
       } 

       PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

       Intent lPauseIntent = new Intent(this, SoundService.class); 
       lPauseIntent.setAction(MusicConstants.ACTION.PAUSE_ACTION); 
       PendingIntent lPendingPauseIntent = PendingIntent.getService(this, 0, lPauseIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

       Intent playIntent = new Intent(this, SoundService.class); 
       playIntent.setAction(MusicConstants.ACTION.PLAY_ACTION); 
       PendingIntent lPendingPlayIntent = PendingIntent.getService(this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

       Intent lStopIntent = new Intent(this, SoundService.class); 
       lStopIntent.setAction(MusicConstants.ACTION.STOP_ACTION); 
       PendingIntent lPendingStopIntent = PendingIntent.getService(this, 0, lStopIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

       RemoteViews lRemoteViews = new RemoteViews(getPackageName(), R.layout.radio_notification); 
       lRemoteViews.setOnClickPendingIntent(R.id.ui_notification_close_button, lPendingStopIntent); 

       switch (mStateService) { 

        case MusicConstants.STATE_SERVICE.PAUSE: 
         lRemoteViews.setViewVisibility(R.id.ui_notification_progress_bar, View.INVISIBLE); 
         lRemoteViews.setOnClickPendingIntent(R.id.ui_notification_player_button, lPendingPlayIntent); 
         lRemoteViews.setImageViewResource(R.id.ui_notification_player_button, R.drawable.ic_play_arrow_white); 
         break; 

        case MusicConstants.STATE_SERVICE.PLAY: 
         lRemoteViews.setViewVisibility(R.id.ui_notification_progress_bar, View.INVISIBLE); 
         lRemoteViews.setOnClickPendingIntent(R.id.ui_notification_player_button, lPendingPauseIntent); 
         lRemoteViews.setImageViewResource(R.id.ui_notification_player_button, R.drawable.ic_pause_white); 
         break; 

        case MusicConstants.STATE_SERVICE.PREPARE: 
         lRemoteViews.setViewVisibility(R.id.ui_notification_progress_bar, View.VISIBLE); 
         lRemoteViews.setOnClickPendingIntent(R.id.ui_notification_player_button, lPendingPauseIntent); 
         lRemoteViews.setImageViewResource(R.id.ui_notification_player_button, R.drawable.ic_pause_white); 
         break; 
       } 

       NotificationCompat.Builder lNotificationBuilder = new NotificationCompat.Builder(this); 
       lNotificationBuilder 
         .setContent(lRemoteViews) 
         .setSmallIcon(R.mipmap.ic_launcher) 
         .setCategory(NotificationCompat.CATEGORY_TRANSPORT) 
         .setOngoing(true) 
         .setAutoCancel(true) 
         .setContentIntent(pendingIntent); 
       if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { 
        lNotificationBuilder.setVisibility(Notification.VISIBILITY_PUBLIC); 
       } 

       return lNotificationBuilder.build(); 

      } 

      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mStateService = MusicConstants.STATE_SERVICE.PLAY; 
       mNotificationManager.notify(MusicConstants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); 
       try { 
        mPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       mPlayer.start(); 
       mTimerUpdateHandler.postDelayed(mTimerUpdateRunnable, 0); 
      } 


      private void lockCPU() { 
... 
    //Part of code was skipped 
    ... 
      } 

      private void unlockCPU() { 
       ... 
    //Part of code was skipped 
    ... 
      } 

      private void lockWiFi() { 
       ... 
    //Part of code was skipped 
    ... 
      } 

      private void unlockWiFi() { 
       ... 
    //Part of code was skipped 
    ... 
      } 
     } 

我的build.gradle:

apply plugin: 'com.android.application' 

repositories { 
    maven { url 'https://maven.google.com' } 
} 

android { 
    compileSdkVersion 26 
    buildToolsVersion "26.0.1" 
    defaultConfig { 
     applicationId "com.example.foreground" 
     minSdkVersion 15 
     targetSdkVersion 26 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    compile "com.android.support:support-compat:${project.ext.supportLibVersion}" 
    compile "com.android.support:support-v4:${project.ext.supportLibVersion}" 
    compile "com.android.support:design:${project.ext.supportLibVersion}" 
    compile "com.android.support:appcompat-v7:${project.ext.supportLibVersion}" 
    compile 'com.android.support.constraint:constraint-layout:1.0.2' 
    testCompile 'junit:junit:4.12' 
} 

project.ext.supportLibVersion = '26.1.0'

看看它是如何適用於Android API

回答

2

第1步:設置project.ext.supportLibVersion26.1.0或更高

第2步:請注意,你現在在你的所有new NotificationCompat.Builder()電話越來越廢棄警告

第3步:Define a NotificationChannel(如果你還沒有定義它以前的一些應用程序的運行)

第4步:通過該信道標識NotificationCompat.Builder構造

+0

儘管創建了一個前臺服務,Will **不定義** NotificationChannel會使該服務成爲Oreo操作系統中的一個候選人。我注意到前臺服務在運行一段時間後死亡!!? – ranjjose

+1

@ranjjose:「如果我沒有通過NotificationChannel讓該服務成爲奧利奧操作系統殺死的候選人?」 - 我沒有嘗試過這種情況,對不起。 – CommonsWare

+0

感謝您的快速響應。我修正了幾個錯別字。 – ranjjose

-1

我只是改變了我的方法prepareNotification()SoundService.java來自:

private Notification prepareNotification() { 
      Intent notificationIntent = new Intent(this, MainActivity.class); 
      notificationIntent.setAction(MusicConstants.ACTION.MAIN_ACTION); 
      //... 
      NotificationCompat.Builder lNotificationBuilder = new NotificationCompat.Builder(this); 
      //... 

到:

private Notification prepareNotification() { 
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && 
        mNotificationManager.getNotificationChannel(FOREGROUND_CHANNEL_ID) == null) { 
       // The user-visible name of the channel. 
       CharSequence name = getString(R.string.text_value_radio_notification); 
       int importance = NotificationManager.IMPORTANCE_DEFAULT; 
       NotificationChannel mChannel = new NotificationChannel(FOREGROUND_CHANNEL_ID, name, importance); 
       mChannel.enableVibration(false); 
       mNotificationManager.createNotificationChannel(mChannel); 
      } 
      Intent notificationIntent = new Intent(this, MainActivity.class); 
      notificationIntent.setAction(MusicConstants.ACTION.MAIN_ACTION); 
      //... 
      NotificationCompat.Builder lNotificationBuilder; 
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { 
      lNotificationBuilder = new NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID); 
      } else { 
      lNotificationBuilder = new NotificationCompat.Builder(this); 
      } 
      //... 

你可以看到完整的差異here