Android एपीआई लेवल 26 से, फ़ोरग्राउंड सेवाओं के लिए लगातार सूचनाएं भेजना ज़रूरी है. इस ज़रूरी शर्त का मकसद, ऐसी सेवाओं को छिपाने से रोकना है जिनसे सिस्टम के संसाधनों पर ज़्यादा मांग पड़ सकती है. इनमें खास तौर पर बैटरी भी शामिल है. इस ज़रूरी शर्त के चलते, एक संभावित समस्या होती है: अगर फ़ोरग्राउंड सेवाओं वाला कोई ऐप्लिकेशन सूचना को ध्यान से मैनेज नहीं करता, ताकि उसे सभी सेवाओं पर शेयर किया जाए, तो उसे लगातार खारिज न किया जा सकने वाली कई सूचनाएं दिख सकती हैं. इस वजह से, सूचनाओं की सूची में, अनचाहे लोग शामिल हो सकते हैं.
यह समस्या तब और मुश्किल हो जाती है, जब नेविगेशन SDK जैसे SDK टूल का इस्तेमाल किया जाता है. ये SDK टूल, ऐप्लिकेशन के बिना फ़ोरग्राउंड सेवाओं को चलाते हैं. इन सेवाओं में, अलग से लगातार मिलने वाली सूचनाएं होती हैं. इस वजह से, इन सेवाओं को एक साथ रखना मुश्किल होता है.
इन समस्याओं को ठीक करने के लिए, नेविगेशन SDK टूल के वर्शन 1.11 में एक आसान एपीआई लॉन्च किया गया है. इसकी मदद से, ऐप्लिकेशन में लगातार मिलने वाली सूचनाओं को मैनेज किया जा सकता है. इसमें SDK टूल भी शामिल है.
घटक
फ़ोरग्राउंड सेवा मैनेजर, Android फ़ोरग्राउंड सेवा क्लास और लगातार दिखने वाली सूचना क्लास के लिए एक रैपर उपलब्ध कराता है. इस रैपर का मुख्य फ़ंक्शन, नोटिफ़िकेशन आईडी के दोबारा इस्तेमाल को लागू करना है, ताकि मैनेजर का इस्तेमाल करके सूचना को सभी फ़ोरग्राउंड सेवाओं के साथ शेयर किया जा सके.
नेविगेशन SDK टूल में, ForegroundServiceManager
सिंगलटन को शुरू करने और पाने के लिए स्टैटिक तरीके शामिल होते हैं. इस सिंगलटन को, नेविगेशन SDK टूल के लाइफ़टाइम में सिर्फ़ एक बार शुरू किया जा सकता है. ऐसे में, किसी एक शुरुआती कॉल (initForegroundServiceManagerMessageAndIntent()
या initForegroundServiceManagerProvider()
) का इस्तेमाल करने पर, पाथ फिर से डालने की स्थिति में, आपको उसे 'ट्राई-कैच करें' ब्लॉक से घेरना चाहिए. अगर किसी भी तरीके को एक से ज़्यादा बार कॉल किया जाता है, तो नेविगेशन SDK टूल, रनटाइम के दौरान अपवाद के तौर पर लागू होने वाला अपवाद लागू करता है. ऐसा तब तक होता है, जब तक कि हर एक कॉल से पहले ForegroundServiceManager
के सभी रेफ़रंस हटाए नहीं जाते और clearForegroundServiceManager()
को कॉल नहीं किया जाता.
initForegroundServiceManagerMessageAndIntent()
के चार पैरामीटर application
, notificationId
, defaultMessage
, और resumeIntent
हैं. अगर आखिरी तीन पैरामीटर शून्य हैं, तो सूचना स्टैंडर्ड नेविगेशन SDK टूल की सूचना होती है. हालांकि, इस सूचना के पीछे ऐप्लिकेशन में मौजूद अन्य फ़ोरग्राउंड सेवाओं को छिपाया जा सकता है. notificationId
पैरामीटर, सूचना के लिए इस्तेमाल किए जाने वाले सूचना आईडी की जानकारी देता है. अगर यह वैल्यू शून्य है, तो किसी भी वैल्यू का इस्तेमाल किया जाता है. इसे साफ़ तौर पर सेट किया जा सकता है, ताकि अन्य सूचनाओं के साथ होने वाली गड़बड़ियों को ठीक किया जा सके. जैसे, किसी दूसरे SDK से मिलने वाली सूचनाएं. defaultMessage
एक स्ट्रिंग होती है. यह तब दिखती है, जब सिस्टम नेविगेट न कर रहा हो. resumeIntent
एक इंटेंट है, जो सूचना पर क्लिक होने पर ट्रिगर होता है. अगर resumeIntent
शून्य है, तो सूचना पर किए गए क्लिक को अनदेखा कर दिया जाता है.
initForegroundServiceManagerProvider()
के तीन पैरामीटर ये हैं:
application
, notificationId
, और notificationProvider
. अगर आखिरी दो पैरामीटर शून्य हैं, तो सूचना स्टैंडर्ड नेविगेशन SDK टूल की सूचना होती है. notificationId
पैरामीटर, सूचना के लिए इस्तेमाल किए जाने वाले सूचना आईडी की जानकारी देता है. अगर यह शून्य है, तो किसी भी वैल्यू का इस्तेमाल किया जाता है. इसे साफ़ तौर पर सेट किया जा सकता है, ताकि अन्य सूचनाओं के साथ होने वाली गड़बड़ियों को ठीक किया जा सके. जैसे, किसी दूसरे SDK से मिलने वाली सूचनाएं. अगर notificationProvider
सेट है, तो सूचना को रेंडर करने के लिए, सेवा देने वाली कंपनी हमेशा ज़िम्मेदार होती है.
Navigation SDK टूल का getForegroundServiceManager()
तरीका, फ़ोरग्राउंड सेवा मैनेजर सिंगलटन दिखाता है. अगर आपने अब तक कोई आईडी जनरेट नहीं किया है, तो इसका मतलब है कि आपने notificationId
, defaultMessage
, और resumeIntent
के लिए, शून्य पैरामीटर के साथ initForegroundServiceManagerMessageAndIntent()
को कॉल किया है.
ForegroundServiceManager
को तीन आसान तरीकों से इस्तेमाल किया जा सकता है. पहले दो, किसी सेवा को फ़ोरग्राउंड में और उससे बाहर ले जाने के लिए होते हैं. आम तौर पर, इन्हें बनाई गई सेवा से ही कॉल किया जाता है. इन तरीकों का इस्तेमाल करने से यह पक्का होता है कि सेवाएं, शेयर की गई सूचना से जुड़ी हों. आखिरी तरीका, updateNotification()
, मैनेजर को फ़्लैग करता है कि सूचना बदल गई है और उसे फिर से रेंडर किया जाना चाहिए.
अगर आपको शेयर की गई लगातार मिलने वाली सूचनाओं पर पूरा कंट्रोल चाहिए, तो एपीआई, सूचना देने वाली कंपनी तय करने के लिए NotificationContentProvider
इंटरफ़ेस उपलब्ध कराता है. इसमें, मौजूदा कॉन्टेंट की सूचना पाने का एक ही तरीका शामिल होता है. यह एक बेस क्लास भी उपलब्ध कराता है. इसका इस्तेमाल, सेवा देने वाली कंपनी की जानकारी देने के लिए किया जा सकता है. हालांकि, ऐसा करना ज़रूरी नहीं है. बेस क्लास का एक मुख्य मकसद यह है कि यह ForegroundServiceManager
को ऐक्सेस किए बिना, updateNotification()
को कॉल करने का तरीका उपलब्ध कराती है. अगर नए सूचना मैसेज पाने के लिए सूचना देने वाली कंपनी के इंस्टेंस का इस्तेमाल किया जाता है, तो सूचना में मैसेज को रेंडर करने के लिए इस इंटरनल तरीके को सीधे कॉल किया जा सकता है.
इस्तेमाल के उदाहरण
इस सेक्शन में, शेयर की गई लगातार मिलने वाली सूचनाओं के इस्तेमाल के बारे में बताया गया है.
- फ़ोरग्राउंड में चल रही अन्य ऐप्लिकेशन की सेवाओं की लगातार दिखने वाली सूचनाएं छिपाना
- सबसे आसान तरीका यह है कि मौजूदा व्यवहार को बनाए रखा जाए और नेविगेशन SDK टूल की जानकारी को रेंडर करने के लिए, सिर्फ़ हमेशा दिखने वाली सूचना का इस्तेमाल किया जाए. फ़ोरग्राउंड सेवा मैनेजर
startForeground()
औरstopForeground()
तरीकों का इस्तेमाल करके, अन्य सेवाएं इस सूचना के पीछे छिप सकती हैं. - ऐप्लिकेशन की अन्य फ़ोरग्राउंड सेवाओं की लगातार मिलने वाली सूचनाओं को छिपाएं. हालांकि, नेविगेट न करने पर, डिफ़ॉल्ट टेक्स्ट सेट करें
- दूसरा आसान तरीका यह है कि मौजूदा व्यवहार को बनाए रखा जाए और नेविगेशन SDK टूल की जानकारी को रेंडर करने के लिए, सिर्फ़ तब सूचनाएं भेजी जाएं, जब सिस्टम नेविगेट न कर रहा हो. जब सिस्टम नेविगेट नहीं कर रहा होता है, तो
initForegroundServiceManagerMessageAndIntent()
के लिए दी गई स्ट्रिंग दिखती है, न कि डिफ़ॉल्ट नेविगेशन SDK स्ट्रिंग, जिसमें "Google Maps" का ज़िक्र होता है. इस कॉल का इस्तेमाल, फिर से शुरू करने का इंटेंट सेट करने के लिए भी किया जा सकता है. यह इंटेंट, सूचना पर क्लिक करने पर ट्रिगर होता है. - लगातार मिलने वाली सूचना को रेंडर करने का पूरा कंट्रोल अपने पास रखें
- आखिरी स्थिति में, सूचना देने वाली सेवा देने वाली कंपनी तय करना और बनाना ज़रूरी है. साथ ही,
initForegroundServiceManagerProvider()
का इस्तेमाल करके, उसेForegroundServiceManager
को भेजना होगा. इस विकल्प से आपको सूचना में रेंडर की जाने वाली चीज़ों पर पूरा कंट्रोल मिलता है. साथ ही, यह नेविगेशन SDK टूल की सूचना की जानकारी को सूचना से अलग कर देता है. इससे सूचना में दिखने वाले मोड़-दर-मोड़ निर्देश हट जाते हैं. Google, इस जानकारी को हासिल करने और सूचना में डालने का आसान तरीका उपलब्ध नहीं कराता.
सूचना देने वाली सेवा देने वाली कंपनी का उदाहरण
यहां दिए गए कोड के उदाहरण में, सूचना के कॉन्टेंट की सेवा देने वाली किसी सामान्य कंपनी का इस्तेमाल करके, सूचनाएं बनाने और उन्हें दिखाने का तरीका बताया गया है.
public class NotificationContentProviderImpl
extends NotificationContentProviderBase
implements NotificationContentProvider {
private String channelId;
private Context context;
private String message;
/** Constructor */
public NotificationContentProviderImpl(Application application) {
super(application);
message = "-- uninitialized --";
channelId = null;
this.context = application;
}
/**
* Sets message to display in the notification. Calls updateNotification
* to display the message immediately.
*
* @param msg The message to display in the notification.
*/
public void setMessage(String msg) {
message = msg;
updateNotification();
}
/**
* Returns the notification as it should be rendered.
*/
@Override
public Notification getNotification() {
Notification notification;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Spanned styledText = Html.fromHtml(message, FROM_HTML_MODE_LEGACY);
String channelId = getChannelId(context);
notification =
new Notification.Builder(context, channelId)
.setContentTitle("Notifications Demo")
.setStyle(new Notification.BigTextStyle()
.bigText(styledText))
.setSmallIcon(R.drawable.ic_navigation_white_24dp)
.setTicker("ticker text")
.build();
} else {
notification = new Notification.Builder(context)
.setContentTitle("Notification Demo")
.setContentText("testing non-O text")
.build();
}
return notification;
}
// Helper to set up a channel ID.
private String getChannelId(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (channelId == null) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(
"default", "navigation", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("For navigation persistent notification.");
notificationManager.createNotificationChannel(channel);
channelId = channel.getId();
}
return channelId;
} else {
return "";
}
}
}
NotificationContentProviderImpl
बनाने के बाद, इस कोड का इस्तेमाल करके नेविगेशन SDK टूल को इसके साथ कनेक्ट करें:
ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);
सीमाएं और आने वाले समय के प्लान
initForegroundServiceManagerMessageAndIntent()
याinitForegroundServiceManagerProvider()
को जल्द से जल्द कॉल करें, ताकि इस्तेमाल से जुड़ी उम्मीद के मुताबिक स्थिति को अच्छी तरह से बताया जा सके. नया नेविगेटर बनाने से पहले, आपको यह तरीका आज़माना होगा.- अगर कोड पाथवे एक से ज़्यादा बार डाला गया है, तो
initForegroundServiceManagerMessageAndIntent()
याinitForegroundServiceManagerProvider()
के लिए किए गए कॉल के अपवादों को ज़रूर पहचानें. Navigation SDK v2.0 में, इस तरीके को कई बार कॉल करने पर, रनटाइम अपवाद के बजाय, जांचा गया अपवाद दिखता है. - Google को अब भी सूचना के पूरे जीवनकाल के दौरान, हेडर की स्टाइल से मैच करने वाली स्टाइल को एक जैसा रखने के लिए काम करना पड़ सकता है.
- सूचना देने वाली सेवा तय करने पर, प्राथमिकता के हिसाब से हेड्स-अप के व्यवहार को कंट्रोल किया जा सकता है.
- Google, सूचना देने वाली सेवा देने वाली कंपनी के लिए, सूचना में शामिल की गई, हर मोड़ की जानकारी पाने का आसान तरीका उपलब्ध नहीं कराता.