बिना सूचना दिखाए कैसे शुरू करें फ़ॉरग्राउंड ()?


87

मैं एक सेवा बनाना चाहता हूं और इसे अग्रभूमि में चलाना चाहता हूं।

अधिकांश उदाहरण कोडों पर सूचनाएं हैं। लेकिन मैं कोई अधिसूचना नहीं दिखाना चाहता। क्या यह संभव है?

क्या आप मुझे कुछ उदाहरण दे सकते हैं? क्या कोई विकल्प है?

मेरी ऐप सेवा मध्यस्थ कर रही है। सिस्टम को कैसे मेरी सेवा को नहीं मारना है, ऐप को छोड़कर इसे खुद ही मारना है (जैसे कि बटन द्वारा संगीत को रोकना या रोकना)।


11
आपके पास अधिसूचना के बिना "फोरग्राउंड" सेवा नहीं हो सकती। अवधि।
जुगनारनॉट

1
कैसे एक "नकली" अधिसूचना के बारे में? यह एक चाल है?
मुहम्मद रेसना रिजकी प्रणाम

एक बार अग्रभूमि अधिसूचना सेटअप हो जाने के बाद, आप रबड़ ऐप का उपयोग करके "पृष्ठभूमि सूचनाओं में चल रहे" को हटा सकते हैं ।
लॉरेंट

1
@MuhammadResnaRizkiPratama, क्या आप स्वीकृत उत्तर को बदलने पर विचार करेंगे? यह सवाल बेहद लोकप्रिय है, लेकिन स्वीकृत उत्तर पूरी तरह से पुराना है, बहुत भारी-भरकम है, और यह अनुमान लगाता है कि डेवलपर को इसकी आवश्यकता क्यों है। मैं इस जवाब का सुझाव देता हूं क्योंकि यह विश्वसनीय है, ओएस बग का शोषण नहीं करता है, और अधिकांश एंड्रॉइड डिवाइसों पर काम करता है।
सैम

जवाबों:


95

एंड्रॉयड प्लेटफॉर्म के एक सुरक्षा सुविधा के रूप में, आप नहीं कर सकते हैं , के तहत किसी भी परिस्थिति में, एक foregrounded सेवा भी एक सूचना के बिना है। इसका कारण यह है कि अग्रगामी सेवा भारी मात्रा में संसाधनों का उपभोग करती है और पृष्ठभूमि सेवाओं की तुलना में विभिन्न समय-निर्धारण बाधाओं (यानी, यह जल्दी से नहीं मारा जाता है) के अधीन है, और उपयोगकर्ता को यह जानना होगा कि संभवतः उनकी बैटरी क्या खा रही है। तो, यह मत करो।

हालांकि, "नकली" अधिसूचना होना संभव है, अर्थात, आप एक पारदर्शी अधिसूचना आइकन (iirc) बना सकते हैं। यह आपके उपयोगकर्ताओं के लिए बेहद अपमानजनक है, और आपके पास ऐसा करने का कोई कारण नहीं है, उनकी बैटरी को मारने और इस प्रकार मैलवेयर बनाने के अलावा।


3
धन्यवाद। इससे मुझे स्पष्ट होता है कि सेटफ़ोरग्राउंड को अधिसूचना की आवश्यकता क्यों है।
मुहम्मद रेसना रिजकी प्रणाम

21
वैसे ऐसा लगता है कि आपके पास ऐसा करने का एक कारण है, उपयोगकर्ताओं ने इसके लिए कहा है। यद्यपि यह असंगत हो सकता है जैसा कि आप कहते हैं, यह एक उत्पाद के लिए अनुरोध किया गया था जो मैं परीक्षण समूहों द्वारा काम कर रहा हूं। हो सकता है कि एंड्रॉइड के पास कुछ सेवाओं से सूचनाएं छिपाने का विकल्प हो, जिन्हें आप हमेशा से जानते हैं। अन्यथा आपकी सूचना पट्टी क्रिसमस के पेड़ की तरह दिखाई देगी।
रादु

3
@Radu वास्तव में आपके पास अग्रभूमि में कई ऐप्स नहीं होने चाहिए : जो आपके बैटरी जीवन को मार देंगे, क्योंकि वे अलग-अलग तरीके से निर्धारित होते हैं (अनिवार्य रूप से, वे मरते नहीं हैं)। यह एक मॉड के लिए स्वीकार्य हो सकता है, लेकिन मैं उस विकल्प को जल्द ही किसी भी समय वैनिला एंड्रॉइड में नहीं बनाता। "उपयोगकर्ता" आमतौर पर नहीं जानते कि उनके लिए सबसे अच्छा क्या है ..
क्रिस्टोफर मिकिंस्की

2
@Radu जो आपके तर्क का समर्थन नहीं करता है। "अवार्ड विनिंग ऐप्स" आमतौर पर ऐसे होते हैं जो वास्तव में सिस्टम की विसंगतियों (जैसे कार्य हत्यारों) के माध्यम से एंड्रॉइड के छेद को "ठीक" करते हैं। ऐसा कोई कारण नहीं है कि आपको अग्रभूमि सेवा का उपयोग सिर्फ इसलिए करना चाहिए क्योंकि "पुरस्कार विजेता ऐप्स" करते हैं: यदि आप ऐसा करते हैं तो आप उपयोगकर्ता की बैटरी को मारने के लिए स्वीकार कर रहे हैं।
क्रिस्टोफर मिकिन्स्की

2
जाहिर है, यह विधि अब 4.3 में शुरू होने से काम नहीं करेगी। plus.google.com/u/0/105051985738280261832/posts/MTinJWdNL8t
erbi

79

अपडेट: यह एंड्रॉइड 7.1 पर "निश्चित" था। https://code.google.com/p/android/issues/detail?id=213309

4.3 अपडेट के बाद से, बिना सूचना दिखाए सेवा शुरू करना मूल रूप से असंभव है startForeground()

हालाँकि, आप आधिकारिक APIs का उपयोग करके आइकन छिपा सकते हैं ... पारदर्शी आइकन की कोई आवश्यकता नहीं है: ( NotificationCompatपुराने संस्करणों का समर्थन करने के लिए उपयोग करें )

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setPriority(Notification.PRIORITY_MIN);

मैंने इस तथ्य के साथ शांति बनाई है कि अधिसूचना को अभी भी वहां रहने की आवश्यकता है लेकिन जो कभी भी इसे छुपाना चाहता है, उसके लिए मुझे एक वैकल्पिक हल मिल सकता है:

  1. startForeground()अधिसूचना और सब कुछ के साथ एक नकली सेवा शुरू करें ।
  2. वह वास्तविक सेवा प्रारंभ करें जिसे आप चलाना चाहते हैं, startForeground()(उसी सूचना आईडी के साथ)
  3. पहली (फर्जी) सेवा बंद करें (आप कॉल कर सकते हैं stopSelf()और ऑनडेस्ट्रो कॉल में stopForeground(true))।

देखा! कोई सूचना बिल्कुल भी नहीं है और आपकी दूसरी सेवा चलती रहती है।


23
इसके लिए धन्यवाद। मुझे लगता है कि कुछ लोगों को एहसास नहीं है कि एंड्रॉइड विकास है जो आंतरिक व्यावसायिक उपयोग के लिए जाता है (अर्थात, यह कभी भी बाजार पर दिखाई नहीं देता है या जो ब्लो को बेचा जाता है)। कभी-कभी लोग "सर्विस नोटिफिकेशन को रोकना" जैसी चीजों के लिए पूछते हैं और सामान्य उपभोग के लिए कोषेर नहीं होने पर भी काम के आस-पास देखना अच्छा होता है।
जेमीबी

5
@JamieB मैं और अधिक सहमत नहीं हो सका ... मैंने डायने हैकॉर्न को सुझाव दिया कि उन्हें पृष्ठभूमि सेवाओं की पूरी अवधारणा पर पुनर्विचार करने की आवश्यकता है और शायद सूचनाओं के बिना पृष्ठभूमि में सेवा चलाने की अनुमति जोड़ें। ऐसा नहीं है कि यह हमारे लिए डेवलपर्स के लिए मायने रखता है अगर कोई अधिसूचना है या नहीं - इसे हटाने के लिए यह USER अनुरोध है! :) वैसे, क्या आप यह सत्यापित कर सकते हैं कि यह आपके लिए भी काम करता है?
लियोर इलुज़

1
@JamieB user875707 आइकन पैरामीटर (आइकन के संसाधन आईडी) को 0 पर सेट करने के लिए कहता है, अधिसूचना की आईडी नहीं (यदि ऐसा है, तो डॉक्स का कहना है कि "startForeground" काम नहीं करेगा)।
wangqi060934

9
बेशक, आपको यह मान लेना चाहिए कि यह भविष्य के प्लेटफॉर्म के संस्करणों में काम नहीं करेगा।
हैकबॉड

1
@JamieB मैंने वास्तव में अभी Android 5.0.1 पर इसका परीक्षण किया है और यह अभी भी मेरे लिए काम करता है।
लायर इलुज़

20

यह अब एंड्रॉइड 7.1 के रूप में काम नहीं करता है और यह Google Play की डेवलपर नीतियों का उल्लंघन कर सकता है ।

इसके बजाय, उपयोगकर्ता को सेवा अधिसूचना को ब्लॉक करना होगा


यहाँ Lior Iluz द्वारा उत्तर में तकनीक का मेरा कार्यान्वयन है ।

कोड

ForegroundService.java

public class ForegroundService extends Service {

    static ForegroundService instance;

    @Override
    public void onCreate() {
        super.onCreate();

        instance = this;

        if (startService(new Intent(this, ForegroundEnablingService.class)) == null)
            throw new RuntimeException("Couldn't find " + ForegroundEnablingService.class.getSimpleName());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        instance = null;
    }

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

}

ForegroundEnablingService.java

public class ForegroundEnablingService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (ForegroundService.instance == null)
            throw new RuntimeException(ForegroundService.class.getSimpleName() + " not running");

        //Set both services to foreground using the same notification id, resulting in just one notification
        startForeground(ForegroundService.instance);
        startForeground(this);

        //Cancel this service's notification, resulting in zero notifications
        stopForeground(true);

        //Stop this service so we don't waste RAM.
        //Must only be called *after* doing the work or the notification won't be hidden.
        stopSelf();

        return START_NOT_STICKY;
    }

    private static final int NOTIFICATION_ID = 10;

    private static void startForeground(Service service) {
        Notification notification = new Notification.Builder(service).getNotification();
        service.startForeground(NOTIFICATION_ID, notification);
    }

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

}

AndroidManifest.xml

<service android:name=".ForegroundEnablingService" />
<service android:name=".ForegroundService" />

अनुकूलता

परीक्षण किया गया और इस पर काम किया जा रहा है:

  • आधिकारिक एमुलेटर
    • 4.0.2
    • 4.1.2
    • 4.2.2
    • 4.3.1
    • 4.4.2
    • 5.0.2
    • 5.1.1
    • 6.0
    • 7.0
  • सोनी एक्सपीरिया एम
    • 4.1.2
    • 4.3
  • सैमसंग गैलेक्सी ?
    • 4.4.2
    • 5.X
  • Genymotion
    • 5.0
    • 6.0
  • CyanogenMod
    • 5.1.1

अब एंड्रॉइड 7.1 के रूप में काम नहीं कर रहा है।


2
अभी तक इसका परीक्षण नहीं किया गया है, लेकिन इसके लिए कम से कम अनुमति प्राप्त करना अच्छा होगा !!! +1 "टू गूगल" भाग के लिए, मेरे उपयोगकर्ता ऐप को पृष्ठभूमि में रखने के लिए आवश्यक अधिसूचना के बारे में शिकायत कर रहे हैं, मैं स्काइप / लामा और किसी अन्य ऐप के लिए आवश्यक अधिसूचना के बारे में भी शिकायत करता हूं
रामी दबैन

खेद है कि इस उदाहरण का उपयोग अलार्म सुनने के लिए कैसे किया जा सकता है। Im एक ऐप विकसित कर रहा है, जो अलार्म मैनजर के साथ अलार्म सेट करता है और मेरे पास जो समस्या है, वह यह है कि जब मैं ऐप को बंद करता हूं (हाल के ऐप्स-> स्पष्ट) सभी अलार्म को हटा दिया जाता है और Im इसे रोकने का एक तरीका
ढूंढता है

@ Ares91, उस के लिए एक अलग StackOverflow प्रश्न बनाने की कोशिश करें, और संबंधित कोड सहित अधिक से अधिक जानकारी शामिल करना सुनिश्चित करें। मुझे अलार्म के बारे में ज्यादा जानकारी नहीं है, और यह सवाल सिर्फ सेवाओं के बारे में है।
सैम

@Sam को किस सेवा को पहले कहा जाना चाहिए, फॉरग्राउंड एनेबलिंग सर्विस या फोरग्राउंड
एंड्रॉइड मैन

@AndroidManForegroundService
सैम

14

आप इसका उपयोग कर सकते हैं (जैसा कि @Kristopher Micinski द्वारा सुझाया गया है):

Notification note = new Notification( 0, null, System.currentTimeMillis() );
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground( 42, note );

अपडेट करें:

कृपया ध्यान दें कि Android किटकैट + रिलीज़ के साथ अब इसकी अनुमति नहीं है। और ध्यान रखें कि यह एंड्रॉइड में डिज़ाइन सिद्धांत का कम या ज्यादा उल्लंघन कर रहा है जो उपयोगकर्ताओं को पृष्ठभूमि के संचालन को दृश्यमान बनाता है जैसा कि @ क्रिस्‍टोफर जिंस्‍की ने बताया है।


2
ध्यान दें कि यह एसडीके 17 के साथ अब और स्वीकार नहीं किया जा रहा है। यदि यह नोटिफिकेशन पास किया गया है तो सेवा अग्रभूमि में नहीं जाएगी। 0.
स्निकोलस

यह एक बग था और उम्मीद है कि तय हो गया। फोरग्राउंड सेवाओं का विचार यह है कि वे मारे जाने की संभावना कम हैं, और यह उपयोगकर्ता को उसके अस्तित्व के बारे में सुनिश्चित करने का एक तरीका है।
मार्टिन मार्कोसिनी

4
एंड्रॉइड 18 के साथ अधिसूचना किसी भी अधिक अदृश्य नहीं है, लेकिन यह कहती है कि "ऐप चल रहा है, अधिक जानकारी के लिए टच करें या ऐप को बंद करें"
इमानुएल मोएक्लिन

1
मेरे एक ग्राहक का स्क्रीनशॉट: 1gravity.com/k10/Screenshot_2013-07-25-12-35-49.jpg । मेरे पास एक 4.3 डिवाइस भी है और उस खोज की पुष्टि कर सकता है।
इमानुएल मोएक्लिन

2
चेतावनी: मुझे Android 4.1.2 (SDK 16) के साथ Sony Ericsson LT26i (Xperia S) की क्रैश रिपोर्ट मिल रही है: android.app.RemoteServiceException: पैकेज से पोस्ट की गई खराब सूचना ...: आइकन नहीं बना सका: StatusBarIcon (pkg =) ... आईडी = 0x7f020052 स्तर = 0 दृश्यमान = वास्तविक संख्या = 0) मैंने आइकन आईडी 0 से एसडीके 17 तक सेट किया है। एसडीके 18 से मैंने इसे एक वैध ड्रॉबल रिसोर्स पर सेट किया है। हो सकता है, आपको SDK 16 से मान्य आइकन आईडी की आवश्यकता हो!
अल्मिसॉफ्ट

13

चेतावनी : हालाँकि यह जवाब काम करता प्रतीत होता है, यह वास्तव में आपकी सेवा को अग्रभूमि सेवा बनने से रोकता है

मूल उत्तर:


बस अपनी अधिसूचना की आईडी को शून्य पर सेट करें:

// field for notification ID
private static final int NOTIF_ID = 0;

    ...
    startForeground(NOTIF_ID, mBuilder.build());
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    mNotificationManager.cancel(NOTIF_ID);
    ...

एक लाभ जो आपको मिल सकता है, वह Serviceएंड्रॉइड सिस्टम द्वारा नष्ट किए बिना उच्च प्राथमिकता पर चलने में सक्षम होगा, जब तक कि उच्च मेमोरी दबाव पर नहीं।

संपादित करें

इसे प्री-हनीकॉम्ब और एंड्रॉइड 4.4 और उच्चतर के साथ काम करने के लिए, सुनिश्चित करें कि आप इसका उपयोग करते हैं, NotificationCompat.Builderजिसके बजाय समर्थन लाइब्रेरी v7 द्वारा प्रदान किया गया है Notification.Builder


1
यह मेरे लिए 4.3 (18) @vlad सोल पर पूरी तरह से काम करता है। मुझे आश्चर्य है कि इस उत्तर के लिए कोई अन्य अपवित्र क्यों नहीं है?
रोब मैकफ़ेली

मैंने एंड्रॉइड एन प्रीव्यू 4 में यह कोशिश की और यह काम नहीं किया। मैंने कोशिश की Notification.Builder, समर्थन पुस्तकालय v4 NotificationCompat.Builderऔर समर्थन पुस्तकालय v7 NotificationCompat.Builder। नोटिफिकेशन ड्रॉअर या स्टेटस बार में नोटिफिकेशन दिखाई नहीं देता था, लेकिन जब मैंने इसे इस्तेमाल किया था getRunningServices()और चेक किया था, तो यह सेवा अग्रभूमि मोड में नहीं चल रही थी dumpsys
सैम

@ शम, तो यह बग पहले वाले संस्करण पर दिखाई नहीं देता, सही है?
अंगरेजुडी एच।

@AnggrayudiH, "इस बग" के द्वारा, क्या आपको लगता है कि अधिसूचना प्रदर्शित नहीं हो रही है? या क्या आपका मतलब है कि सेवा अग्रभूमि मोड में नहीं जा रही है?
सैम

1
यह मेरे लिए काम नहीं करता है। जब आईडी भेजा जाता है तो अग्रभूमि के रूप में प्रक्रिया शुरू की जाती है! = 0 भेजा जाता है, लेकिन आईडी के रूप में अग्रभूमि के रूप में शुरू नहीं किया जाता है। adb shell dumpsys activity servicesसत्यापित करने के लिए उपयोग करें।
बीट्री

8

आप लेआउट 9 के साथ कस्टम लेआउट का उपयोग करके एंड्रॉइड 9+ पर सूचना छिपा सकते हैं = "0dp"

NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationUtils.CHANNEL_ID);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.custom_notif);
builder.setContent(remoteViews);
builder.setPriority(NotificationCompat.PRIORITY_LOW);
builder.setVisibility(Notification.VISIBILITY_SECRET);

custom_notif.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="0dp">
</LinearLayout>

Pixel 1, Android 9 पर परीक्षण किया गया। यह समाधान एंड्रॉइड 8 या उससे कम पर काम नहीं करता है


अच्छा काम है। इसके अलावा, मुझे लगता है कि इसे एंड्रॉइड 10 पर आइकन की आवश्यकता है। आइकन के लिए पारदर्शी प्लेसहोल्डर छवि का उपयोग करने से समस्या हल होती है।
श्योस

7

अपडेट: यह अब एंड्रॉइड 4.3 और इसके बाद के संस्करण में काम नहीं करता है


एक वर्कअराउंड है। आइकन सेट किए बिना अधिसूचना बनाने का प्रयास करें, और अधिसूचना नहीं दिखाई देगी। पता नहीं यह कैसे काम करता है, लेकिन यह करता है :)

    Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle("Title")
            .setTicker("Title")
            .setContentText("App running")
            //.setSmallIcon(R.drawable.picture)
            .build();
    startForeground(101,  notification);

3
Android N पूर्वावलोकन 4 में, यह काम नहीं करता है। (YourServiceName) is runningजब आप किसी आइकन को निर्दिष्ट नहीं करते हैं तो एंड्रॉइड आपकी खुद की बजाय एक अधिसूचना दिखाता है । कॉमन्सवेयर के अनुसार, एंड्रॉइड 4.3 के बाद से यह मामला रहा है: commonsware.com/blog/2013/07/30/…
सैम

1
मैंने आज कुछ परीक्षण किया और पुष्टि की कि यह एंड्रॉइड 4.3 और इसके बाद के संस्करण में काम नहीं करता है।
सैम

5

अपडेट: यह अब एंड्रॉइड 4.3 और इसके बाद के संस्करण में काम नहीं करता है


मैंने शून्य करने के लिए अधिसूचना के लिए निर्माणकर्ता को आइकन पैरामीटर सेट किया, और फिर शुरू करने के लिए परिणामी अधिसूचना को पारित कर दिया। लॉग में कोई त्रुटि नहीं है और कोई सूचना दिखाई नहीं देती है। मुझे नहीं पता, हालांकि, क्या सेवा को सफलतापूर्वक अग्रसर किया गया था - क्या जांच का कोई तरीका है?

संपादित: dumpsys के साथ जाँच की, और वास्तव में सेवा मेरे 2.3 प्रणाली पर आधारित है। अभी तक अन्य OS संस्करणों के साथ जाँच नहीं की गई है।


9
यह जांचने के लिए कि क्या "फॉरेग्राउंड" सही है पर जांचने के लिए कमांड "एडीबी शेल डंप्स एक्टिविटी सर्विसेज" का उपयोग करें।
काला

1
या सिर्फ खाली Notification()कंस्ट्रक्टर को बुलाओ ।
johsin18

इसने मेरे लिए काम किया। पहली बार मुझे रात भर चलने के लिए अपनी सेवा मिली, इसलिए यह निश्चित रूप से अग्रभूमि में है (प्लस डंप्स का कहना है कि यह है) और कोई अधिसूचना नहीं है।
जेमीबी

ध्यान दें कि यह अब Android 4.3 (API 18) में काम नहीं करता है। OS, नोटिफिकेशन ड्रॉअर में प्लेसहोल्डर नोटिफिकेशन डालता है।
सैम

4

अग्रभूमि सेवा सूचना को अवरोधित करें

यहां ज्यादातर जवाब या तो काम नहीं करते हैं, अग्रभूमि सेवा को तोड़ते हैं , या Google Play नीतियों का उल्लंघन करते हैं

मज़बूती से और सुरक्षित रूप से अधिसूचना को छिपाने का एकमात्र तरीका उपयोगकर्ता को इसे रोकना है।

Android 4.1 - 7.1

एकमात्र तरीका यह है कि आप अपने ऐप से सभी सूचनाएं रोकें:

  1. उपयोगकर्ता को ऐप के विवरण स्क्रीन पर भेजें:

    Uri uri = Uri.fromParts("package", getPackageName(), null);
    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(uri);
    startActivity(intent);
    
  2. उपयोगकर्ता ब्लॉक ऐप के नोटिफिकेशन को देखें

ध्यान दें कि यह आपके ऐप के विस्फोटों को भी रोकता है।

Android 8.0 - 8.1

यह एंड्रॉइड ओ पर नोटिफिकेशन को ब्लॉक करने के लायक नहीं है क्योंकि ओएस बस इसे " पृष्ठभूमि में चल रहा है " या " बैटरी का उपयोग करके " अधिसूचना के साथ बदल देगा।

Android 9+

अपनी अन्य सूचनाओं को प्रभावित किए बिना सेवा अधिसूचना को अवरुद्ध करने के लिए एक अधिसूचना चैनल का उपयोग करें ।

  1. नोटिफिकेशन चैनल को सर्विस नोटिफिकेशन असाइन करें
  2. चैनल की सेटिंग नोटिफ़िकेशन के लिए उपयोगकर्ता भेजें

    Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
        .putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName())
        .putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId());
    startActivity(intent);
    
  3. उपयोगकर्ता ब्लॉक चैनल की सूचनाएं प्राप्त करें


2

संस्करण 4.3 (18) और ऊपर छिपी सेवा अधिसूचना संभव नहीं है, लेकिन आप आइकन को अक्षम कर सकते हैं, संस्करण 4.3 (18) और नीचे अधिसूचना को छुपाना संभव है

Notification noti = new Notification();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
    noti.priority = Notification.PRIORITY_MIN;
}
startForeground(R.string.app_name, noti);

हालांकि यह उत्तर संभवतः सही और उपयोगी है, यह पसंद किया जाता है यदि आप इसे समझाने के साथ-साथ कुछ स्पष्टीकरण शामिल करते हैं कि यह समस्या को हल करने में कैसे मदद करता है। यह भविष्य में विशेष रूप से उपयोगी हो जाता है, अगर कोई परिवर्तन (संभवतः असंबंधित) होता है जो इसे काम करना बंद कर देता है और उपयोगकर्ताओं को यह समझने की आवश्यकता है कि एक बार कैसे काम किया।
केविन ब्राउन

मुझे लगता है कि एंड्रॉइड 4.3 वास्तव में एपीआई 18 है। इसके अलावा, यह विधि केवल स्टेटस बार से आइकन छिपाती है; आइकन अभी भी अधिसूचना में मौजूद है।
सैम

अधिसूचना से आइकन छुपाने के लिए आप खाली छवि mBuilder.setSmallIcon (R.drawable.blank) जोड़ सकते हैं;
vlad sol

1
मैं किटकैट स्रोत को देख रहा हूं, और शून्य आईडी विधि से ऐसा नहीं लगता है कि यह काम कर सकता है। यदि आईडी शून्य है, तो सेवा रिकॉर्ड को अग्रभूमि में अपडेट नहीं किया जाता है।
जेफरी ब्लाटमैन

2

मैंने एंड्रॉइड 8.0 पर पाया है यह अभी भी एक अधिसूचना चैनल का उपयोग नहीं करके संभव है।

public class BootCompletedIntentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

                Intent notificationIntent = new Intent(context, BluetoothService.class);    
                context.startForegroundService(notificationIntent);

            } else {
                //...
            }

        }
    }
}

और BluetoothService.class में:

 @Override
    public void onCreate(){    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            Intent notificationIntent = new Intent(this, BluetoothService.class);

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

            Notification notification = new Notification.Builder(this)
                    .setContentTitle("Title")
                    .setContentText("App is running")
                    .setSmallIcon(R.drawable.notif)
                    .setContentIntent(pendingIntent)
                    .setTicker("Title")
                    .setPriority(Notification.PRIORITY_DEFAULT)
                    .build();

            startForeground(15, notification);

        }

    }

एक निरंतर अधिसूचना नहीं दिखाई गई है, हालांकि आप देखेंगे कि एंड्रॉइड 'x एप्लिकेशन पृष्ठभूमि की अधिसूचना में चल रहे हैं।


एंड्रॉइड 8.1 में: "स्टार्टफॉरग्राउंड के लिए खराब सूचना: java.lang.RuntimeException: सर्विस नोटिफिकेशन के लिए अमान्य चैनल"
T-igra

व्यक्तिगत रूप से, मुझे लगता है कि apps are running in the backgroundअधिसूचना ऐप-विशिष्ट अधिसूचना से भी बदतर है, इसलिए मुझे यकीन नहीं है कि यह दृष्टिकोण इसके लायक है।
सैम

-2

अपडेट: यह अब एंड्रॉइड 7.1 और उससे ऊपर के एंड्रॉइड में काम नहीं करता है


यहाँ आपके ऐप को oom_adj 1 बनाने का एक तरीका है (ANDROID 6.0 SDK एमुलेटर में परीक्षण किया गया) make एक अस्थायी सेवा जोड़ें, अपने मुख्य सेवा कॉल में startForgroundService(NOTIFICATION_ID, notificion)। और फिर startForgroundService(NOTIFICATION_ID, notificion)अस्थायी सेवा कॉल स्टॉपफोरगेडरसेवा (सच) में थोड़ी देर के बाद, फिर से चालू करने के लिए अस्थायी सेवा कॉल शुरू करें।


यह एकमात्र कार्यशील समाधान है जिससे मैं अवगत हूं। हालांकि, यह पहले से ही एक और उत्तर द्वारा कवर किया गया है ।
सैम

-3

आप अपने आवेदन को लगातार घोषित भी कर सकते हैं।

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:theme="@style/Theme"
    *android:persistent="true"* >
</application>

यह अनिवार्य रूप से आपके ऐप को एक उच्च मेमोरी प्राथमिकता पर सेट करता है, जिससे इसके मारे जाने की संभावना कम हो जाती है।


5
: यह गलत है, केवल सिस्टम एप्लिकेशन लगातार हो सकता है groups.google.com/forum/?fromgroups=#!topic/android-developers/...
Snicolas

-6

मैंने कुछ महीने पहले एक साधारण मीडिया प्लेयर को विकसित किया था। तो मेरा मानना ​​है कि अगर आप कुछ ऐसा कर रहे हैं:

Intent i = new Intent(this, someServiceclass.class);

startService (i);

तब तब सिस्टम को आपकी सेवा को मारने में सक्षम नहीं होना चाहिए।

संदर्भ : उस अनुच्छेद को पढ़ें जो चर्चा करता है कि सिस्टम कब सेवा बंद करता है


मैंने कुछ लेखों में पढ़ा। यदि बस startService () है तो सिस्टम को अधिक मेमोरी की आवश्यकता है। तो सिस्टम उस सेवा को मार देगा। यह सच है? मेरे पास सेवा में प्रयोग करने का समय नहीं है।
मुहम्मद रेसना रिजकी प्रणाम

1
मुहम्मद, यह सच है - स्टार्टफोरग्राउंड () का उद्देश्य पृष्ठभूमि की सेवाओं की तुलना में प्रभावी ढंग से सेवा को उच्चतर "मेमोरी प्राथमिकता" देना है ताकि यह लंबे समय तक जीवित रह सके। स्टार्टफोरग्राउंड () को एक अधिसूचना का उपयोग करना चाहिए ताकि उपयोगकर्ता अधिक निरंतर / कठिन-से-मारने वाली सेवा के बारे में अधिक जागरूक हो जो चल रहा है।
DustinB

यह बिल्कुल सही नहीं है; ऐसी सेवा करना व्यावहारिक रूप से असंभव है जिसे Android पर नहीं मारा जा सकता। एंड्रॉइड आसानी से मेमोरी को खाली करने के लिए गैर-अग्रभूमि सेवाओं को मारता है।
सैम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.