0

Mein Vordergrunddienst zeigt keine Benachrichtigung an, wenn er auf Android Oreo funktioniert.Eine Benachrichtigung des Vordergrunddienstes wird auf Android 8 nicht angezeigt. +

Es funktioniert perfekt auf Android-Versionen von 15 bis 25 Wenn ich targetSdkVersion von 26 zu 25 dieses Problem verschwindet tun. Aber diese Lösung scheint nicht gut zu sein.

Ich bereitete test project mit diesem Problem vor.

Was soll ich tun, um es auf Android Oreo mit targetSdkVersion 26 zu beheben?

Mein Vordergrund Service, 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 
    ... 
      } 
     } 

Mein 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' 
} 

Wo project.ext.supportLibVersion = '26.1.0'

Sehen Sie, wie es funktioniert auf Android API

Antwort

2

Schritt # 1: project.ext.supportLibVersion-26.1.0 oder höher Stellen

Schritt # 2: Beachten Sie, dass Sie jetzt deprecation Warnungen auf allen new NotificationCompat.Builder() Anrufe

Schritt # 3 erhalten: Define a NotificationChannel (wenn Sie es nicht auf definiert einig vorheriger Lauf der app)

Schritt # 4: Übergeben des Kanal-ID an den Konstruktor NotificationCompat.Builder

+0

Trotz des Erstellens eines Vordergrunddienstes macht Will **, der nicht ** einen 'NotificationChannel' definiert, den Dienst zu einem Kandidaten, der von OS in Oreo getötet werden soll? Ich habe bemerkt, dass der Vordergrund-Dienst nach einiger Zeit getötet wurde !!? – ranjjose

+1

@ranjjose: "Wenn ich keinen NotificationChannel nehme, mache den Dienst zu einem Kandidaten, der von OS in Oreo getötet werden soll?" - Ich habe dieses Szenario nicht ausprobiert, tut mir leid. – CommonsWare

+0

danke für die schnelle Antwort. Ich habe ein paar Tippfehler korrigiert. – ranjjose

-1

ich meine Methode geändert nur prepareNotification() in SoundService.java aus:

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

zu:

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

können Sie sehen die volle Differenz here.

Verwandte Themen