13

पर अपग्रेड करने के बाद startForeground विफल हो गया है मेरे फोन को 8.1 डेवलपर पूर्वावलोकन में अपग्रेड करने के बाद मेरी पृष्ठभूमि सेवा अब ठीक से शुरू नहीं होती है।एंड्रॉइड 8.1

मेरी लंबी चल रही सेवा में मैंने जारी अधिसूचना शुरू करने के लिए एक प्रारंभिक विधि लागू की है जिसे बनाने पर कहा जाता है।

@TargetApi(Build.VERSION_CODES.O) 
private fun startForeground() { 
    // Safe call, handled by compat lib. 
    val notificationBuilder = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID) 

    val notification = notificationBuilder.setOngoing(true) 
      .setSmallIcon(R.drawable.ic_launcher_foreground) 
      .build() 
    startForeground(101, notification) 
} 

त्रुटि संदेश:

11-28 11:47:53.349 24704-24704/$PACKAGE_NAMEE/AndroidRuntime: FATAL EXCEPTION: main 
    Process: $PACKAGE_NAME, PID: 24704 
    android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=My channel pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x42 color=0x00000000 vis=PRIVATE) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768) 
     at android.os.Handler.dispatchMessage(Handler.java:106) 
     at android.os.Looper.loop(Looper.java:164) 
     at android.app.ActivityThread.main(ActivityThread.java:6494) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

सेवा अधिसूचना के लिए अवैध चैनल, जाहिरा तौर पर अपना पुराना चैनल DEFAULT_CHANNEL_ID नहीं रह गया है एपीआई 27 मुझे लगता है के लिए उपयुक्त है। उचित चैनल क्या होगा? मैंने प्रलेखन को देखने की कोशिश की है

उत्तर

18

विभिन्न समाधान के साथ कुछ टंकण करने के बाद ऐसा लगता है कि आपको 8.1 में अपना स्वयं का अधिसूचना चैनल बनाना होगा।

private fun startForeground() { 
    val channelId = 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 
       createNotificationChannel() 
      } else { 
       // If earlier version channel ID is not used 
       // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) 
       "" 
      } 

    val notificationBuilder = NotificationCompat.Builder(this, channelId) 
    val notification = notificationBuilder.setOngoing(true) 
      .setSmallIcon(R.mipmap.ic_launcher) 
      .setPriority(PRIORITY_MIN) 
      .setCategory(Notification.CATEGORY_SERVICE) 
      .build() 
    startForeground(101, notification) 
} 


@RequiresApi(Build.VERSION_CODES.O) 
private fun createNotificationChannel(): String{ 
    val channelId = "my_service" 
    val channelName = "My Background Service" 
    val chan = NotificationChannel(channelId, 
      channelName, NotificationManager.IMPORTANCE_NONE) 
    chan.lightColor = Color.BLUE 
    chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE 
    val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager 
    service.createNotificationChannel(chan) 
    return channelId 
} 

मेरी समझ पृष्ठभूमि सेवाओं से अब सामान्य सूचनाओं का उपयोगकर्ता तो करने के लिए चुन सकते हैं अधिसूचना चैनल का चयन हटा कर नहीं दिखा के रूप में प्रदर्शित कर रहे हैं।

अद्यतन: Oreo की तुलना में पुराने संस्करणों के लिए समर्थन के साथ अपडेट किया गया समाधान

अद्यतन: जोड़ा गया Kotlin टैग

+0

कौन सा 'वैल' है?! ... –

+2

यह कोटलिन कोड है। Https://kotlinlang.org देखें। यह एक बहुत छोटी भाषा है जो तेजी से बढ़ रही है! –

+0

@ प्रतिबंध-जियोइंजिनियरिंग जैसा कि अन्य टिप्पणी द्वारा उल्लिखित है।यह कोटलिन है यह एंड्रॉइड की आधिकारिक रूप से समर्थित भाषाओं में से एक है। – Rawa

6

वर्क्स Andorid 8.1 पर ठीक से:

अपडेट किया गया नमूना (किसी भी पदावनत कोड के बिना) :

public NotificationBattery(Context context) { 
    this.mCtx = context; 

    mBuilder = new NotificationCompat.Builder(context, CHANNEL_ID) 
      .setContentTitle(context.getString(R.string.notification_title_battery)) 
      .setSmallIcon(R.drawable.ic_launcher) 
      .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) 
      .setChannelId(CHANNEL_ID) 
      .setOnlyAlertOnce(true) 
      .setPriority(NotificationCompat.PRIORITY_MAX) 
      .setWhen(System.currentTimeMillis() + 500) 
      .setGroup(GROUP) 
      .setOngoing(true); 

    mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_view_battery); 

    initBatteryNotificationIntent(); 

    mBuilder.setContent(mRemoteViews); 

    mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 

    if (AesPrefs.getBooleanRes(R.string.SHOW_BATTERY_NOTIFICATION, true)) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 
      NotificationChannel channel = new NotificationChannel(CHANNEL_ID, context.getString(R.string.notification_title_battery), 
        NotificationManager.IMPORTANCE_DEFAULT); 
      channel.setShowBadge(false); 
      channel.setSound(null, null); 
      mNotificationManager.createNotificationChannel(channel); 
     } 
    } else { 
     mNotificationManager.cancel(Const.NOTIFICATION_CLIPBOARD); 
    } 
} 

पुराना स्निप

public static final String NOTIFICATION_CHANNEL_ID_SERVICE = "com.mypackage.service"; 
public static final String NOTIFICATION_CHANNEL_ID_TASK = "com.mypackage.download_info"; 

public void initChannel(){ 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 
     NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, "App Service", NotificationManager.IMPORTANCE_DEFAULT)); 
     nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, "Download Info", NotificationManager.IMPORTANCE_DEFAULT)); 
    } 
} 

सबसे अच्छा:

@Override 
public int onStartCommand(Intent intent, int flags, final int startId) { 
    Log.d(TAG, "onStartCommand"); 

    String CHANNEL_ONE_ID = "com.kjtech.app.N1"; 
    String CHANNEL_ONE_NAME = "Channel One"; 
    NotificationChannel notificationChannel = null; 
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { 
     notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, 
       CHANNEL_ONE_NAME, IMPORTANCE_HIGH); 
     notificationChannel.enableLights(true); 
     notificationChannel.setLightColor(Color.RED); 
     notificationChannel.setShowBadge(true); 
     notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); 
     NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     manager.createNotificationChannel(notificationChannel); 
    } 

    Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); 
    Notification notification = new Notification.Builder(getApplicationContext()) 
      .setChannelId(CHANNEL_ONE_ID) 
      .setContentTitle(getString(R.string.obd_service_notification_title)) 
      .setContentText(getString(R.string.service_notification_content)) 
      .setSmallIcon(R.mipmap.ic_launcher) 
      .setLargeIcon(icon) 
      .build(); 

    Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    notification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0); 

    startForeground(START_FOREGROUND_ID, notification); 

    return START_STICKY; 
} 
+1

उपर्युक्त कोड का हिस्सा अब हटा दिया गया है, जिसे आप 'अधिसूचना.बिल्डर (getAplicationContext()) बदलकर हटा सकते हैं। SetChannelId (CHANNEL_ONE_ID) ... '' अधिसूचना। बिल्डर (getAplicationContext(), CHANNEL_ONE_ID)। ..' –

+1

@ प्रतिबंध-जियोइंजिनियरिंग आप बिल्कुल सही हैं ... मैंने नया नमूना कोड जोड़ा। धन्यवाद। –

0

मेरे मामले में, क्योंकि हम NotificationChannel निर्दिष्ट किए बिना बारे में सूचना पोस्ट करने की कोशिश की है, यह है: - d (ऊपर कोड से संबंधित नहीं वह किसी भिन्न ऐप है) जगह कोड ऊपर डाल करने के लिए, Application कक्षा में onCreate() विधि में है ताकि हम बस सभी के लिए एक बार यह घोषणा करने के लिए की जरूरत है:

public class App extends Application { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     initChannel(); 
    } 
} 
हम इस सेट अप

के बाद, हम channelId साथ अधिसूचना उपयोग कर सकते हैं हम सिर्फ निर्दिष्ट:

Intent i = new Intent(this, MainActivity.class); 
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
PendingIntent pi = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT); 
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID_INFO); 
      .setContentIntent(pi) 
      .setWhen(System.currentTimeMillis()) 
      .setContentTitle("VirtualBox.exe") 
      .setContentText("Download completed") 
      .setSmallIcon(R.mipmap.ic_launcher); 

फिर, हम एक अधिसूचना पोस्ट करने के लिए उपयोग कर सकते हैं:

int notifId = 45; 
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
nm.notify(notifId, builder.build()); 

आप इसे उपयोग करना चाहते हैं अग्रभूमि सेवा की अधिसूचना के रूप में:

startForeground(notifId, builder.build()); 
संबंधित मुद्दे