অ্যান্ড্রয়েড 8.0: java.lang.IllegalStateException: পরিষেবা ইন্টেন্ট শুরু করার অনুমতি নেই


359

অ্যাপ্লিকেশন আরম্ভের সময়, অ্যাপ্লিকেশন পরিষেবাটি শুরু করে যা কিছু নেটওয়ার্ক টাস্ক করা উচিত। এপিআই স্তরের 26 টি লক্ষ্যবস্তু করার পরে, আমার অ্যাপ্লিকেশনটি ব্যাকগ্রাউন্ডে Android 8.0 এ পরিষেবা শুরু করতে ব্যর্থ।

এর দ্বারা তৈরি: java.lang.IllegalStateException: পরিষেবা শুরু করার অনুমতি নেই ইনটেন্ট {সিএমপি = my.app.tt / com.my.service}: অ্যাপ্লিকেশন UidRecord এর পটভূমিতে রয়েছে {90372b1 u0a136 সিইএম নিষ্ক্রিয় প্রকস: 1 সেক (0,0 , 0)}

যেহেতু আমি এটি সম্পর্কিত বুঝতে পারি: পটভূমি সম্পাদনের সীমা

স্টার্ট সার্ভিস () পদ্ধতিটি এখন একটি ইলিজালস্টেটএক্সেপশন ছুড়ে দেয় যদি অ্যানড্রয়েড 8.0 টার্গেট করে এমন একটি অ্যাপ এমন পরিস্থিতিতে যদি সেই পদ্ধতিতে ব্যাকগ্রাউন্ড পরিষেবাদি তৈরির অনুমতি না পায় তবে সেটিকে ব্যবহার করার চেষ্টা করে।

" এমন পরিস্থিতিতে যখন এর অনুমতি নেই " - এর আসলে কী বোঝায় ?? এবং কীভাবে এটি ঠিক করবেন। আমি আমার পরিষেবাটিকে "অগ্রভাগ" হিসাবে সেট করতে চাই না


4
এর অর্থ হ'ল আপনার অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে থাকা অবস্থায় আপনি কোনও পরিষেবা শুরু করতে পারবেন না
টিম

22
রানটাইমের অনুমতি নিয়ে এটির কোনও
টিম

10
startForegroundService()পরিবর্তে ব্যবহার করুন startService()
ফ্রুগ্যাটো

2
আপনি টার্গেটএসডিকি ভার্সন 25 ব্যবহার করার চেষ্টা করতে পারেন তবে কম্পাইলএসডকে ভার্সন 26 দিয়ে সংকলন করুন Android আপনি Android 8 এবং নতুন সাপোর্টপোর্ট লাইব্রেরি থেকে নতুন ক্লাস ব্যবহার করতে পারেন তবে আপনার অ্যাপ্লিকেশনটি ব্যাকগ্রাউন্ড এক্সিকিউশন সীমা দ্বারা সীমাবদ্ধ থাকবে না।
ক্যাক্পার ডিজিউবেক

2
@KacperDziubek যে কাজ করা উচিত কিন্তু একটি অস্থায়ী সমাধান হিসেবে এটি 2018 শরতে লক্ষ্য SDK26 করা প্রয়োজন হবে
RightHandedMonkey

উত্তর:


194

অনুমোদিত পরিস্থিতিগুলি হ'ল অস্থায়ী শ্বেতলিস্ট যেখানে ব্যাকগ্রাউন্ড পরিষেবা অ্যান্ড্রয়েড ও এর আগের মতো আচরণ করে where

নির্দিষ্ট পরিস্থিতিতে, একটি পটভূমি অ্যাপ্লিকেশনটি বেশ কয়েক মিনিটের জন্য অস্থায়ী শ্বেত তালিকাতে রাখা হয়। কোনও অ্যাপ শ্বেতলিস্টে থাকা অবস্থায়, এটি সীমাবদ্ধতা ছাড়াই পরিষেবা চালু করতে পারে এবং এর পটভূমি পরিষেবাগুলি চালানোর অনুমতি দেওয়া হয়। কোনও অ্যাপ্লিকেশন শ্বেতলিস্টে রাখা হয় যখন এটি কোনও ব্যবহারকারীর কাছে দৃশ্যমান কোনও কাজ পরিচালনা করে যেমন:

  • একটি উচ্চ-অগ্রাধিকার ফায়ারবেস ক্লাউড মেসেজিং (এফসিএম) বার্তা হ্যান্ডলিং।
  • একটি সম্প্রচার যেমন কোনও এসএমএস / এমএমএস বার্তা গ্রহণ করা।
  • একটি বিজ্ঞপ্তি থেকে একটি পেন্ডিং ইন্টেন্ট কার্যকর করা হচ্ছে।
  • ভিপিএন অ্যাপ্লিকেশনটি নিজেকে অগ্রভাগে প্রচার করার আগে একটি ভিপিএন সার্ভিস শুরু করা।

উত্স: https://developer.android.com/about/versions/oreo/background.html

সুতরাং অন্য কথায় যদি আপনার ব্যাকগ্রাউন্ড পরিষেবাটি যদি হোয়াইটলিস্টের প্রয়োজনীয়তা পূরণ করে না তবে আপনাকে নতুন জবশেডুলার ব্যবহার করতে হবে । এটি মূলত একটি পটভূমি পরিষেবা হিসাবে একই, তবে এটি ধারাবাহিকভাবে ব্যাকগ্রাউন্ডে চালানোর পরিবর্তে বলা হয়ে থাকে।

আপনি যদি কোনও ইনসেন্ট সার্ভিস ব্যবহার করছেন তবে আপনি একটি জবআইটেন্ট সার্ভিসে পরিবর্তন করতে পারেন। নীচে @ কোসেভের উত্তর দেখুন


"হাই" প্রাইভির জিসিএম বার্তা পাওয়ার ঠিক পরে পরিষেবা শুরু করতে চাইলে আমি ক্রাশ পাচ্ছি। আমি এখনও জিসিএম ব্যবহার করি: "com.google.android.gms: play-Services-gcm: 11.4.2", 'com.google.firebase: ফায়ারবেস-ম্যাসেজিং: 11.4.2' নয়। যদিও এটি গুরুত্বপূর্ণ তা নিশ্চিত নয় ..
অ্যালেক্স র‌্যাডিশেভস্কি

"এটি মূলত একটি পটভূমি পরিষেবা হিসাবে একই, তবে এটি ধারাবাহিকভাবে ব্যাকগ্রাউন্ডে চালানোর পরিবর্তে পর্যায়ক্রমে ডাকা হয়" " - আপনি এটার অর্থ কী তা নিশ্চিত নন, কারণ অ্যান্ড্রয়েড পরিষেবাদি কখনও ধারাবাহিকভাবে কার্যকর করে নি। তারা শুরু করে, চালায়, তারপরে বন্ধ।
মেল্ল্বর

2
কি FirebaseInstanceIdService এবং তার onTokenRefreshপদ্ধতি একটি উচ্চ অগ্রাধিকার FCM বার্তা?
কর্ড রেহেন

@ পিএনএফএনএমএনএন, জিসিএমটাস্ক সার্ভিসেস সত্যই এফসিএম অনুসরণ করে না তাই তারা কাজ করে না।
অভিনব উপাধ্যায়

4
আপনি কি জবশেডুলার বা অন্যদের পরিবর্তে ওয়ার্কম্যানেজার (এখানে: ডেভেলপার.অ্যান্ড্রয়েড / টপিক / লাইব্রিজি / অর্কিটেকচার / ওয়ার্ক ম্যানেজার) ব্যবহার করবেন না ? আমি এর অর্থ: youtu.be/IrKoBFLwTN0
অ্যান্ড্রয়েড বিকাশকারী

254

আমি সমাধান পেয়েছি। প্রাক-8.0 ডিভাইসের জন্য, আপনাকে কেবল ব্যবহার করতে হবে startService(), তবে 7-পরবর্তী ডিভাইসের জন্য আপনাকে ব্যবহার করতে হবে startForgroundService()। পরিষেবাটি শুরু করার জন্য কোডের নমুনা এখানে।

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(new Intent(context, ServedService.class));
    } else {
        context.startService(new Intent(context, ServedService.class));
    }

এবং পরিষেবা শ্রেণিতে, বিজ্ঞপ্তির জন্য দয়া করে নীচের কোডটি যুক্ত করুন:

@Override
public void onCreate() {
    super.onCreate();
    startForeground(1,new Notification());
}

যেখানে হে অ্যান্ড্রয়েড সংস্করণ 26।


9
অগ্রভাগ পরিষেবা এমন একটি জিনিস যা ব্যবহারকারী সচেতন হবে এবং এর জন্য একটি বিজ্ঞপ্তি প্রয়োজন। এটি খুব দীর্ঘ সময় চলতে থাকলে এটিআএনআরও হবে। সুতরাং অ্যাপ্লিকেশনটি ইতিমধ্যে পটভূমিতে চলমান থাকলে এটি কোনও উপযুক্ত উত্তর নয়।
সাইমন এইচ

80
ContextCompat.startForegroundService(...)পরিবর্তে ব্যবহার করা যেতে পারে এমন একটি সমর্থন লিব রয়েছে।
jayeffkay

37
এটি কোনও সমাধান নয়।
জ্যাকসনএফএফরে

17
আমিও একমত যে এটি কোনও সমাধান নয়। এটি একটি কার্যক্ষম এবং এটি সাহায্য করে তবে ওরিওর পটভূমির সীমাটি একটি কারণে প্রবর্তিত হয়েছিল। এই সীমাগুলি এইভাবে বাইপাস করা অবশ্যই সঠিক পদ্ধতির নয় (যদিও এটি কাজ করে)। সবচেয়ে ভাল উপায় হ'ল জবশেডুলার ব্যবহার করা (স্বীকৃত উত্তরটি দেখুন)।
ভ্রতিস্লাভ জিন্দ্রা

6
আমার মনে হয় না যদি আপনার অবশ্যই খালি অগ্রভাগের বিজ্ঞপ্তি প্রদর্শন করা হয় তবে এটি একটি ভাল ব্যবহারকারীর অভিজ্ঞতা হবে। আপনার অবশ্যই তা বিবেচনা করা উচিত। - অ্যান্ড্রয়েড 8.0 অগ্রভাগে একটি নতুন পরিষেবা শুরু করতে নতুন পদ্ধতি স্টার্টফোরগ্রাউন্ড সার্ভিসেস () উপস্থাপন করেছে। সিস্টেম পরিষেবাটি তৈরি করার পরে, অ্যাপ্লিকেশনটির কাছে পরিষেবাটির স্টার্টফোরগ্রাউন্ড () পদ্ধতিতে নতুন পরিষেবার ব্যবহারকারী-দৃশ্যমান বিজ্ঞপ্তিটি কল করতে পাঁচ সেকেন্ড রয়েছে has অ্যাপ্লিকেশন যদি সময়সীমার মধ্যে স্টার্টফোরগ্রাউন্ড () কল না করে, সিস্টেম পরিষেবাটি বন্ধ করে দেয় এবং অ্যাপটিকে এএনআর হিসাবে ঘোষণা করে।
হিলিজেজ

85

সবচেয়ে ভাল উপায় হ'ল জবআইন্টেন্ট সার্ভিস ব্যবহার করা যা ওরিওর জন্য নতুন জবশেডুলার বা উপলভ্য না হলে পুরানো পরিষেবাদি ব্যবহার করে।

আপনার ম্যানিফেস্টে ঘোষণা করুন:

<service android:name=".YourService"
         android:permission="android.permission.BIND_JOB_SERVICE"/>

এবং আপনার পরিষেবাতে আপনাকে হ্যান্ডলআইরেক্টকে হ্যান্ডল ওয়ার্কের সাথে প্রতিস্থাপন করতে হবে:

public class YourService extends JobIntentService {

    public static final int JOB_ID = 1;

    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, YourService.class, JOB_ID, work);
    }

    @Override
    protected void onHandleWork(@NonNull Intent intent) {
        // your code
    }

}

তারপরে আপনি আপনার পরিষেবাটি এর সাথে শুরু করুন:

YourService.enqueueWork(context, new Intent());


স্থির পদ্ধতির অভ্যন্তরে আপনি কীভাবে একটি অ স্থিতিকাল পদ্ধতিতে কল করতে সক্ষম হন? আপনি দয়া করে ব্যাখ্যা করতে পারেন?
ম্যাডি

@ ম্যাডি enqueueWork(...)একটি স্থির পদ্ধতিও।
hgoebl

2
আপনি কোথায় আপনার সার্ভিস.ইনেকিউ ওয়ার্ক (প্রসঙ্গ, নতুন উদ্দিষ্ট ()) বলবেন; ? ব্রডকাস্ট রিসিভার থেকে?
TheLearner

আমি বিশ্বাস করি না যে এটিই সবচেয়ে সহজ সমাধান। ওয়ার্ক ম্যানেজার সম্পর্কে নীচে আমার মন্তব্য দেখুন। এটি যখন উপযুক্ত হবে তখন জবআইন্টেন্টসেসওয়ার ব্যবহার করে তবে এতে অনেক কম বয়লার প্লেট রয়েছে।
টলে

36

সেবা একটি ব্যাকগ্রাউন্ড থ্রেড ব্যাপ্ত দ্বারা চলতে থাকে তবে দয়া IntentService, আপনি প্রতিস্থাপন করতে পারেন IntentServiceসঙ্গে JobIntentServiceযা অ্যান্ড্রয়েড সাপোর্ট লাইব্রেরির অংশ হিসাবে প্রদান করা হয়

ব্যবহারের সুবিধাটি JobIntentServiceহ'ল, এটি IntentServiceপ্রাক-ও ডিভাইসগুলিতে ও ও ও উচ্চতর হিসাবে আচরণ করে , এটি এটিকে একটি কাজ হিসাবে প্রেরণ করে

JobSchedulerপর্যায়ক্রমিক / অন কাজের চাকরির জন্যও ব্যবহার করা যেতে পারে। তবে, JobSchedulerএপিআই হিসাবে পশ্চাদপটে সামঞ্জস্যতা হ্যান্ডেল করা নিশ্চিত করুন কেবলমাত্র 21 21 থেকে পাওয়া যায়


1
জবআইনটেন্ট সার্ভিসের সমস্যাটি হ'ল অ্যান্ড্রয়েড আপনার কাজের বদলে নির্বিচারে সময়সূচী করতে পারে এবং এটি কোনও ইনটেন্টস সার্ভিসের বিপরীতে চারপাশে কিছু ঝাঁকুনি দেওয়া ছাড়া স্পষ্টভাবে শুরু করা যায় না। দেখুন stackoverflow.com/questions/52479262/...
kilokahn

15

ইন Oreo অ্যান্ড্রয়েড সংজ্ঞায়িত পটভূমি পরিষেবাগুলিতে সীমা

ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে, অ্যান্ড্রয়েড 8.0 (এপিআই স্তর 26) পটভূমিতে চলাকালীন অ্যাপগুলি কী করতে পারে তার সীমাবদ্ধতা আরোপ করে।

তবুও যদি আপনার সর্বদা চলমান পরিষেবা প্রয়োজন হয় তবে আপনি অগ্রভাগ পরিষেবাটি ব্যবহার করতে পারেন।

পটভূমি পরিষেবা সীমাবদ্ধতা: একটি অ্যাপ্লিকেশন অলস থাকা অবস্থায়, ব্যাকগ্রাউন্ড পরিষেবাদির ব্যবহারের সীমাবদ্ধতা রয়েছে। এটি অগ্রভাগের পরিষেবাগুলিতে প্রযোজ্য নয় যা ব্যবহারকারীর কাছে আরও লক্ষণীয়।

সুতরাং আপনি একটি অগ্রভাগ পরিষেবা করতে পারেন । আপনার পরিষেবাটি চলমান থাকলে আপনাকে ব্যবহারকারীকে একটি বিজ্ঞপ্তি দেখাতে হবে । এই উত্তরটি দেখুন (আরও অনেকে আছেন)

একটি সমাধান যদি -

আপনি আপনার পরিষেবার জন্য একটি বিজ্ঞপ্তি চান না?

আপনি পর্যায়ক্রমিক কাজটি করতে পারেন, ১. এটি আপনার পরিষেবা শুরু করে, ২. পরিষেবাটি তার কাজ করবে এবং ৩. নিজেই থামবে s এটির মাধ্যমে আপনার অ্যাপ্লিকেশনটি ব্যাটারি নিকাশ হিসাবে বিবেচিত হবে না।

আপনি অ্যালার্ম ম্যানেজার , জব শিডিউলার , এভারনোট-জবস বা ওয়ার্ক ম্যানেজারের সাথে পর্যায়ক্রমে টাস্ক ব্যবহার করতে পারেন ।

আমি ওয়ার্ক-ম্যানেজারের সাথে চিরতরে চলমান পরিষেবাটি পরীক্ষা করেছি।


ওয়ার্ক ম্যানেজারটিকে যাওয়ার সবচেয়ে ভাল উপায় বলে মনে হয়, ধরে নেওয়া কাজটি তত্ক্ষণাত্ কার্যকর করতে হবে না। এটি এপিআই 14 এর সাথে সামঞ্জস্যপূর্ণ, এপিআই 23+ সহ ডিভাইসগুলিতে জবশেডুলার এবং এপিআই 14-22 সহ ডিভাইসগুলিতে ব্রডকাস্ট্রিজিভার + অ্যালার্ম ম্যানেজারের সংমিশ্রণ
জেমস অ্যালেন

ওয়ার্ক ম্যানেজার সম্পর্কে মূল বিষয়টি হ'ল ওয়ার্ক
Touhid udoy

13

হ্যাঁ, কারণ আপনি এপিআই 26-তে আর কোনও পটভূমিতে পরিষেবা শুরু করতে পারবেন না So

আপনি ব্যবহার করতে হবে

ContextCompat.startForegroundService(...)

এবং ফাঁস প্রক্রিয়া করার সময় একটি বিজ্ঞপ্তি পোস্ট করুন।


1
ওপি বিশেষত বলেছে যে তিনি অগ্রভাগ হিসাবে চান না। এটি একটি মন্তব্য হিসাবে বা আরও সম্পূর্ণ উত্তরের অংশ হিসাবে রাখা উচিত।
রিকার্ডো এ।

7

@ কোসেভ তার উত্তরে যেমন বলেছিলেন আপনি জবআইন্টেন্ট সার্ভিস ব্যবহার করতে পারেন। তবে আমি একটি বিকল্প সমাধান ব্যবহার করি - আমি IllegalStateException ধরি এবং অগ্রভাগ হিসাবে পরিষেবাটি শুরু করি। উদাহরণস্বরূপ, এই ফাংশনটি আমার পরিষেবা শুরু করে:

@JvmStatic
protected fun startService(intentAction: String, serviceType: Class<*>, intentExtraSetup: (Intent) -> Unit) {
    val context = App.context
    val intent = Intent(context, serviceType)
    intent.action = intentAction
    intentExtraSetup(intent)
    intent.putExtra(NEED_FOREGROUND_KEY, false)

    try {
        context.startService(intent)
    }
    catch (ex: IllegalStateException) {
        intent.putExtra(NEED_FOREGROUND_KEY, true)
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent)
        }
        else {
            context.startService(intent)
        }
    }
}

এবং যখন আমি অভিপ্রায় প্রক্রিয়াকরণ করি তখন আমি এ জাতীয় কাজটি করি:

override fun onHandleIntent(intent: Intent?) {
    val needToMoveToForeground = intent?.getBooleanExtra(NEED_FOREGROUND_KEY, false) ?: false
    if(needToMoveToForeground) {
        val notification = notificationService.createSyncServiceNotification()
        startForeground(notification.second, notification.first)

        isInForeground = true
    }

    intent?.let {
        getTask(it)?.process()
    }
}

আমি আপনার চেষ্টা ধরার সমাধান পছন্দ। আমার জন্য তা একটি সমাধান পাওয়া যাবে কারণ মাঝে মাঝে context.startServiceব্যাকগ্রাউন্ডে কাজ করে - না কখনো কখনো - শুধুমাত্র সবচেয়ে ভালো উপায় মত এই সৌন্দর্য অন্যথায় আপনি আপনার প্রধান বর্গ আরও কোড বাস্তবায়ন করতে হবে extending Applicationএবং implementing ActivityLifecycleCallbacksএবং ট্র্যাক রাখতে কিনা অ্যাপ্লিকেশন ফোরগ্রাউন্ড বা পটভূমিতে রয়েছে এবং আপনার অভিপ্রায় শুরু সেই অনুযায়ী।
পিয়েরে

এই ব্যতিক্রম ধরা যেতে পারে?
thecr0w

5

ফায়ারবেস রিলিজ নোটগুলি থেকে তারা জানিয়েছে যে অ্যান্ড্রয়েড ওয়ের জন্য সমর্থনটি প্রথম প্রকাশিত হয়েছিল 10.2.1 এ (যদিও আমি সাম্প্রতিক সংস্করণটি ব্যবহার করার পরামর্শ দিই)।

অ্যান্ড্রয়েড ও এর জন্য নতুন ফায়ারবেস মেসেজিং নির্ভরতা যুক্ত করুন

compile 'com.google.firebase:firebase-messaging:11.6.2'

প্রয়োজনে গুগল প্লে পরিষেবাদি এবং গুগল স্টোরগুলি আপগ্রেড করুন।


এটি প্রশ্নের উত্তর দেয় না বা ফায়ারবেসের সাথে এই প্রশ্নের কোনও যোগসূত্র নেই। এটি একটি মন্তব্য হিসাবে রাখা উচিত।
রিকার্ডো এ।

5

অ্যাপ্লিকেশনটি ব্যাকগ্রাউন্ডে থাকা অবস্থায় যদি কোনও অভিপ্রায় আগে ঠিকঠাক কাজ করে থাকে তবে অ্যান্ড্রয়েড 8 এবং তারপরের থেকে এটি আর হবে না। অ্যাপটি ব্যাকগ্রাউন্ডে থাকা অবস্থায় কেবল কিছু প্রসেসিং করতে হয় এমন অভিপ্রায়কে উল্লেখ করে।

নীচের পদক্ষেপগুলি অনুসরণ করতে হবে:

  1. উপরে উল্লিখিত অভিপ্রায়টির JobIntentServiceপরিবর্তে ব্যবহার করা উচিত IntentService
  2. যে শ্রেণিটি প্রসারিত JobIntentServiceহবে তাদের onHandleWork(@NonNull Intent intent)পদ্ধতিটি প্রয়োগ করা উচিত এবং পদ্ধতির নীচে থাকা উচিত, যা onHandleWorkপদ্ধতিটি আহ্বান করবে :

    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, xyz.class, 123, work);
    }
  3. enqueueWork(Context, intent)আপনার উদ্দেশ্যটি সংজ্ঞায়িত করা হয়েছে এমন শ্রেণী থেকে কল করুন ।

    কোডের উদাহরণ:

    Public class A {
    ...
    ...
        Intent intent = new Intent(Context, B.class);
        //startService(intent); 
        B.enqueueWork(Context, intent);
    }

নীচের শ্রেণিটি পূর্বে পরিষেবা শ্রেণিকে প্রসারিত করছিল

Public Class B extends JobIntentService{
...

    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, B.class, JobId, work);
    }

    protected void onHandleWork(@NonNull Intent intent) {
        ...
        ...
    }
}
  1. com.android.support:support-compatপ্রয়োজন JobIntentService- আমি ব্যবহার করি 26.1.0 V

  2. সর্বাধিক গুরুত্বপূর্ণ ফায়ারবেস লাইব্রেরি সংস্করণ অন্তত 10.2.1ছিল তা নিশ্চিত করা , আমার সাথে সমস্যা ছিল 10.2.0- আপনার যদি কোনও থাকে!

  3. আপনার ম্যানিফেস্টে পরিষেবা শ্রেণীর জন্য নীচের অনুমতি থাকা উচিত:

    service android:name=".B"
    android:exported="false"
    android:permission="android.permission.BIND_JOB_SERVICE"

আশাকরি এটা সাহায্য করবে.


4

আমি প্রচুর প্রতিক্রিয়া দেখি যা কেবলমাত্র একটি ফোরগ্রাউন্ড সার্ভিস ব্যবহার করার পরামর্শ দেয়। একটি ফোরগ্রাউন্ড সার্ভিস ব্যবহার করার জন্য এটির সাথে যুক্ত একটি বিজ্ঞপ্তি থাকতে হবে। ব্যবহারকারীরা এই বিজ্ঞপ্তিটি দেখতে পাবেন। পরিস্থিতির উপর নির্ভর করে তারা আপনার অ্যাপ্লিকেশনটিতে বিরক্ত হয়ে এটি আনইনস্টল করতে পারে।

সবচেয়ে সহজ সমাধানটি হ'ল ওয়ার্ক ম্যানেজার নামে নতুন আর্কিটেকচার উপাদান ব্যবহার করা। আপনি এখানে ডকুমেন্টেশন চেক আউট করতে পারেন: https://developer.android.com/topic/libraries/architecture/workmanager/

আপনি কেবল আপনার কর্মী শ্রেণীর সংজ্ঞা দিন যা কর্মীর প্রসারিত করে।

public class CompressWorker extends Worker {

    public CompressWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Worker.Result doWork() {

        // Do the work here--in this case, compress the stored images.
        // In this example no parameters are passed; the task is
        // assumed to be "compress the whole library."
        myCompress();

        // Indicate success or failure with your return value:
        return Result.SUCCESS;

        // (Returning RETRY tells WorkManager to try this task again
        // later; FAILURE says not to try again.)
    }
}

আপনি যখন এটি চালাতে চান তারপরে আপনি সময় নির্ধারণ করুন।

    OneTimeWorkRequest compressionWork = 
        new OneTimeWorkRequest.Builder(CompressWorker.class)
            .build();
    WorkManager.getInstance().enqueue(compressionWork);

সহজ! আপনি কর্মীদের কনফিগার করতে পারেন এমন অনেকগুলি উপায় রয়েছে। এটি পুনরাবৃত্ত চাকরিগুলিকে সমর্থন করে এবং আপনার যদি প্রয়োজন হয় তবে আপনি শৃঙ্খলার মতো জটিল জিনিসও করতে পারেন। আশাকরি এটা সাহায্য করবে.


3
বর্তমানে ওয়ার্ক ম্যানেজারটি এখনও আলফা।
pzulw

3
মার্চ 05, 2019 - ওয়ার্কম্যানেজার 1.0.0 স্থিতিশীল প্রকাশ।
phnmnn

চৌরাস্তা বা জবআইটেন্ট সার্ভিস ব্যবহার না করে ওয়ার্ক ম্যানেজার ব্যবহার করা উচিত
sivaBE35

1
WorkManager is intended for tasks that are deferrable—that is, not required to run immediately... এটি সবচেয়ে সহজ হতে পারে তবে, আমার অ্যাপ্লিকেশনটির এমন একটি পটভূমি পরিষেবা দরকার যা ব্যবহারকারীদের অনুরোধগুলি তাত্ক্ষণিকভাবে কার্যকর করে!
কেউ কোথাও

আপনার যদি এই কাজটি অবিলম্বে শেষ করার প্রয়োজন হয়, তবে আপনার অগ্রভাগের পরিষেবাটি ব্যবহার করা উচিত। ব্যবহারকারী একটি বিজ্ঞপ্তি দেখতে পাবেন এবং আপনি কাজ করছেন তা জানতে পারবেন। কী ব্যবহার করবেন তা সিদ্ধান্ত নিতে যদি আপনার সহায়তা প্রয়োজন হয় তবে ডক্সটি পরীক্ষা করে দেখুন। ব্যাকগ্রাউন্ড প্রসেসিংয়ের জন্য তাদের কাছে বেশ ভাল গাইড রয়েছে। developer.android.com/guide/background
টেবিল

4

জবশেডুলার ব্যবহার করে বিকল্প সমাধান, এটি নিয়মিত বিরতিতে পটভূমিতে পরিষেবা শুরু করতে পারে।

প্রথমে Util.java নামে ক্লাস তৈরি করুন

import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;

public class Util {
// schedule the start of the service every 10 - 30 seconds
public static void schedulerJob(Context context) {
    ComponentName serviceComponent = new ComponentName(context,TestJobService.class);
    JobInfo.Builder builder = new JobInfo.Builder(0,serviceComponent);
    builder.setMinimumLatency(1*1000);    // wait at least
    builder.setOverrideDeadline(3*1000);  //delay time
    builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);  // require unmetered network
    builder.setRequiresCharging(false);  // we don't care if the device is charging or not
    builder.setRequiresDeviceIdle(true); // device should be idle
    System.out.println("(scheduler Job");

    JobScheduler jobScheduler = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        jobScheduler = context.getSystemService(JobScheduler.class);
    }
    jobScheduler.schedule(builder.build());
   }
  }

তারপরে, চাকরির পরিষেবাটি ক্লাসটিকে টেস্টজবসওয়ার্স.জাভা হিসাবে নামকরণ করুন

import android.app.job.JobParameters;
import android.app.job.JobService;
import android.widget.Toast;

  /**
   * JobService to be scheduled by the JobScheduler.
   * start another service
   */ 
public class TestJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
    Util.schedulerJob(getApplicationContext()); // reschedule the job
    Toast.makeText(this, "Bg Service", Toast.LENGTH_SHORT).show();
    return true;
}

@Override
public boolean onStopJob(JobParameters params) {
    return true;
  }
 }

এর পরে ব্রডকাস্ট রিসিভার ক্লাস সার্ভিস রিসিভার.জভা নামে

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

 public class ServiceReceiver extends BroadcastReceiver {
 @Override
public void onReceive(Context context, Intent intent) {
    Util.schedulerJob(context);
 }
}

পরিষেবা এবং রিসিভার ক্লাস কোড সহ ম্যানিফেস্ট ফাইল আপডেট করুন

<receiver android:name=".ServiceReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    <service
        android:name=".TestJobService"
        android:label="Word service"
        android:permission="android.permission.BIND_JOB_SERVICE" >

    </service>

যা ডিফল্টভাবে তৈরি করা হয় mainActivity.java ফাইলে বাম main_intent লঞ্চার, এবং পরিবর্তন MainActivity.java ফাইল হয়

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Util.schedulerJob(getApplicationContext());
  }
 }

WOOAAH !! পটভূমি পরিষেবাটি অগ্রভাগ পরিষেবা ব্যতীত শুরু হয়


2

আপনি যদি 8.0 তে আপনার কোড চালাচ্ছেন তবে অ্যাপ্লিকেশনটি ক্রাশ হবে। তাই অগ্রভাগে পরিষেবাটি শুরু করুন। 8.0 এর নীচে থাকলে এটি ব্যবহার করুন:

Intent serviceIntent = new Intent(context, RingtonePlayingService.class);
context.startService(serviceIntent);

যদি উপরে বা 8.0 থাকে তবে এটি ব্যবহার করুন:

Intent serviceIntent = new Intent(context, RingtonePlayingService.class);
ContextCompat.startForegroundService(context, serviceIntent );

কেবলমাত্র সেই ক্ষেত্রে ফরগ্রাউন্ড পরিষেবাদি ব্যবহার করার পরামর্শ দেওয়া হচ্ছে যেখানে কোনও পরিষেবা চলছে সে সম্পর্কে ব্যবহারকারীদের সচেতন হওয়া দরকার। সাধারণ উদাহরণটি পটভূমিতে সংগীত বাজানোর জন্য। অন্যান্য ক্ষেত্রেও তা বোঝা যায়, তবে আপনার কেবলমাত্র সমস্ত পরিষেবা ফোরগ্রাউন্ড পরিষেবাদিতে রূপান্তর করা উচিত নয়। Google এর স্থপতি উপাদানগুলি থেকে ওয়ার্ক ম্যানেজারটি ব্যবহার করার জন্য আপনার পরিষেবাগুলিকে রূপান্তর করার বিষয়ে বিবেচনা করুন যখন আপনাকে যখন ব্যাকগ্রাউন্ডে কিছু কাজ করার দরকার হয় এবং গ্যারান্টিযুক্ত হয়ে যায় যে এটি চলবে।
টেল

স্টার্টফোরগ্রাউন্ডসেবার জন্য অন্যথায় অনুমতি প্রয়োজন java.lang.SecurityException: Permission Denial: startForeground from pid=13708, uid=10087 requires android.permission.FOREGROUND_SERVICEস্ট্যাকওভারফ্লো
কেউ কোথাও

1

আপনি যদি ইন্টিগ্রেটেড ফায়ারবেস মেসেজিং পুশ বিজ্ঞপ্তিটি রেখে থাকেন তবে

ব্যাকগ্রাউন্ড এক্সিকিউশন সীমাবদ্ধতার কারণে অ্যান্ড্রয়েড ও (অ্যান্ড্রয়েড 8.0) এর জন্য নতুন / আপডেট ফায়ারবেস মেসেজিং নির্ভরতা যুক্ত করুন ।

compile 'com.google.firebase:firebase-messaging:11.4.0'

প্রয়োজনে গুগল প্লে পরিষেবাদি এবং গুগল স্টোরগুলি আপগ্রেড করুন।

হালনাগাদ:

 compile 'com.google.firebase:firebase-messaging:11.4.2'

0

startForegroundService()পরিবর্তে ব্যবহার করুন startService() এবং startForeground(1,new Notification());পরিষেবা শুরু করার 5 সেকেন্ডের মধ্যে আপনার পরিষেবাতে তৈরি করতে ভুলবেন না ।


2
দেখে মনে হচ্ছে অ্যান্ড্রয়েড 8.1 থেকে নতুন নোটিফিকেশন () কাজ করে না; : আপনি বিজ্ঞপ্তির জন্য চ্যানেল তৈরি করা উচিত stackoverflow.com/a/47533338/1048087
Prizoff

0

এই উত্তরে বিতর্কিত ভোটের কারণে (এই সম্পাদনা অনুসারে + 4 / -4), দয়া করে অন্য উত্তরগুলির প্রথম দিকে তাকান এবং এটি কেবলমাত্র সর্বশেষ ফলাফল হিসাবে ব্যবহার করুন । আমি কেবল এটি একবার নেটওয়ার্কিং অ্যাপের জন্য ব্যবহার করেছি যা মূল হিসাবে চালিত হয় এবং আমি সাধারণ মতের সাথে একমত যে এই পরিস্থিতিতেটি সাধারণ পরিস্থিতিতে ব্যবহার করা উচিত নয়।

নীচে মূল উত্তর:

অন্যান্য উত্তরগুলি সমস্ত সঠিক, তবে আমি এটি উল্লেখ করতে চাই যে এটিকে ঘুরিয়ে নেওয়ার আরেকটি উপায় হ'ল ব্যবহারকারীকে আপনার অ্যাপের জন্য ব্যাটারি অপ্টিমাইজেশন অক্ষম করতে বলা (আপনার অ্যাপটি সিস্টেম সম্পর্কিত না হলে এটি সাধারণত একটি ভাল ধারণা নয়)। গুগল প্লেতে আপনার অ্যাপ্লিকেশনটি নিষিদ্ধ না করে কীভাবে ব্যাটারি অপ্টিমাইজেশানগুলি থেকে বেরিয়ে আসার অনুরোধ করবেন এই উত্তরটি দেখুন ।

এর মাধ্যমে ক্র্যাশগুলি রোধ করতে আপনার রিসিভারে ব্যাটারি অপ্টিমাইজেশন বন্ধ আছে কিনা তাও আপনার পরীক্ষা করা উচিত:

if (Build.VERSION.SDK_INT < 26 || getSystemService<PowerManager>()
        ?.isIgnoringBatteryOptimizations(packageName) != false) {
    startService(Intent(context, MyService::class.java))
} // else calling startService will result in crash

1
আপনার ব্যবহারকারীদের যতটা সম্ভব ব্যাটারি ব্যবহার করে ফ্রি পাস দেওয়ার জন্য জিজ্ঞাসা করা ভাল সমাধান নয়। আপনার কোডটিকে আরও ব্যাটারি বান্ধব সমাধানে রূপান্তর করতে বিবেচনা করুন। আপনার ব্যবহারকারীরা আপনাকে ধন্যবাদ জানাতে হবে।
সন্ধে

5
@ টএল প্রতিটি পটভূমি পরিষেবা ব্যবহার JobSchedulerএবং স্টাফ ব্যাটারি বান্ধব করা যায় না । কিছু অ্যাপ্লিকেশানের সাধারণ সিঙ্কিং অ্যাপ্লিকেশনগুলির চেয়ে কম স্তরে কাজ করা দরকার। এটি কার্যকর বিকল্প যখন এটি কাজ করে না।
মাইগড

-17

অন ​​স্টার্টকমন্ডে ব্যবহার করবেন না:

return START_NOT_STICKY

শুধু এটিকে পরিবর্তন করুন:

return START_STICKY

এবং এটি কাজ করবে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.