অ্যান্ড্রয়েডে কোনও পরিষেবা চলছে কিনা তা কীভাবে পরীক্ষা করবেন?


936

কোনও পটভূমি পরিষেবা চলছে কিনা তা আমি কীভাবে পরীক্ষা করব?

আমি এমন একটি অ্যান্ড্রয়েড ক্রিয়াকলাপ চাই যা পরিষেবার স্থিতি টগল করে - এটি আমাকে এটি চালু থাকলে এবং এটি চালু থাকলে বন্ধ করে দেয়।



17
: সঠিক উত্তরটি নিচে এবং এক চিহ্নিত stackoverflow.com/a/5921190/2369122
toidiu

1
@toidiu যদি ইতিমধ্যে getRunningTasks()এটির মতো অকার্যকর না হয়ে থাকে তবে সম্ভবত তা হবে।
কেভিন ক্রামউইদে

getSystemService () ফাংশন ব্যবহার করে আপনি সমস্ত চলমান পরিষেবাদি পুনরুদ্ধার করতে পারেন। এটি লুপ করুন এবং আপনার পরিষেবাটি তালিকায় বিদ্যমান রয়েছে যাচাই করে নিন এখানে আপনি একটি ছোট্ট নমুনা উইকি.
ওয়ার্কসিস /

উত্তর:


292

আমারও একই সমস্যা হয়েছিল খুব বেশিদিন আগে। যেহেতু আমার পরিষেবা স্থানীয় ছিল, আমি হ্যাকবডের দ্বারা এখানে বর্ণিত হিসাবে, রাষ্ট্রটি টগল করার জন্য কেবল পরিষেবা শ্রেণিতে একটি স্ট্যাটিক ক্ষেত্রটি ব্যবহার করে শেষ করেছি here

সম্পাদনা (রেকর্ডের জন্য):

হ্যাকবড দ্বারা প্রস্তাবিত সমাধানটি এখানে:

যদি আপনার ক্লায়েন্ট এবং সার্ভার কোড একই .apk অংশ এবং আপনি একটি কংক্রিট ইন্টেন্ট (সঠিক পরিষেবা শ্রেণি নির্দিষ্ট করে এমন) দিয়ে পরিষেবাটির সাথে আবদ্ধ হন, তবে এটি চলমান অবস্থায় আপনি কেবল আপনার পরিষেবাটি একটি বৈশ্বিক পরিবর্তনশীল সেট করতে পারেন that আপনার ক্লায়েন্ট চেক করতে পারেন।

ইচ্ছাকৃতভাবে কোনও পরিষেবা চলছে কিনা তা যাচাই করার জন্য আমাদের কাছে একটি এপিআই নেই কারণ প্রায় ব্যর্থ হয়েই যখন আপনি এমন কিছু করতে চান যখন আপনি নিজের কোডের রেস শর্ত নিয়ে শেষ করেন।


27
@ পেসারিয়র, আপনি যে সমাধানটি উল্লেখ করেছেন সেটির জন্য পরিষেবাটি শুরু করা দরকার এবং আমি মনে করি যে সর্বোত্তম নমনীয় সমাধানটি আপনাকে কোনও পরিষেবা শুরু না করে চলছে কিনা তা খতিয়ে দেখার অনুমতি দেওয়া উচিত।
টম

17
সিস্টেম যদি পরিষেবা বন্ধ করে দেয়, তবে কীভাবে আপনি এটি সনাক্ত করতে পারেন এবং আপনার পরিবর্তনশীল টগল করবেন?
jmng

23
অ্যাপটি মারা গেলে, যে পরিষেবাটি এটি শুরু করেছিল তাও মারা যায় তবে পরিষেবাটির কল onDestroy()হয় না। সুতরাং অসাধারণ আচরণের ফলে এমন দৃশ্যে স্থির পরিবর্তনশীল আপডেট করা যাবে না।
ফিজাল

5
@ ফাইজাল স্ট্যাটিক ভেরিয়েবলটিও কী আবার পুনরায় অন্তর্নিহিত হবে না, এইভাবে এটি আবার ডিফল্ট মানটিতে সেট করে যা নির্দেশ করে যে পরিষেবাটি আর চলছে না?
প্যাবলোক

12
@ ফাইজাল, লোকাল সার্ভিস পৃথক প্রক্রিয়া নয়, সুতরাং যদি পরিষেবাটি মারা যায় তবে অ্যাপ্লিকেশনটিও হত্যা করবে।
বিভক্ত

1674

আমি কোনও ক্রিয়াকলাপের ভিতরে থেকে নিম্নলিখিতটি ব্যবহার করি:

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

এবং আমি এটি ব্যবহার করে কল করি:

isMyServiceRunning(MyService.class)

এটি নির্ভরযোগ্যভাবে কাজ করে, কারণ এটি অ্যাক্টিভিটি ম্যানেজার # getRunningServices এর মাধ্যমে অ্যান্ড্রয়েড অপারেটিং সিস্টেম দ্বারা সরবরাহিত পরিষেবাদি সরবরাহ সম্পর্কিত তথ্যের উপর ভিত্তি করে ।

Ondestroy বা onSometing ইভেন্টগুলি বা বাইন্ডারগুলি বা স্ট্যাটিক ভেরিয়েবলগুলি ব্যবহার করে সমস্ত পন্থা নির্ভরযোগ্যতার সাথে কাজ করবে না কারণ একজন বিকাশকারী হিসাবে আপনি কখনই জানেন না, যখন অ্যান্ড্রয়েড আপনার প্রক্রিয়াটি নষ্ট করার সিদ্ধান্ত নেয় বা উল্লিখিত কলব্যাকগুলির মধ্যে কোনটি বলা হয় বা না। অ্যান্ড্রয়েড ডকুমেন্টেশনে লাইফসাইकल ইভেন্ট টেবিলের "কিলযোগ্য" কলামটি দয়া করে নোট করুন ।


85
এই সমাধানের জন্য ধন্যবাদ। আমি যুক্ত করতে চাই: পরিবর্তে "com.example.MyService" মাই সার্ভিস.ক্লাস.সেটনাম ()
পিটার.বার্তোস

10
ব্যক্তিগতভাবে, আমি একটি স্থির ক্ষেত্র ব্যবহার করে চলেছি। যদিও getRunningServices () ব্যবহার করা একটি আরও দৃ solution় সমাধান, তবে আমি বিশ্বাস করি যে এই দুটি সমাধানে দৃust়তা এবং দক্ষতা / সরলতার মধ্যে একটি বাণিজ্য। যদি কোনও পরিষেবা চলছে কিনা তা আপনাকে ঘন ঘন পরীক্ষা করতে হয়, সম্ভাব্য 30+ চলমান পরিষেবাদিগুলির মধ্য থেকে লুপিং খুব আদর্শ নয়। সিস্টেম দ্বারা ধ্বংস হওয়া কোনও বিরল ক্ষেত্রে সম্ভবত চেষ্টা / ধরা ব্লক বা START_STICKY ব্যবহার করে পরিচালনা করা যেতে পারে।
ছদ্মবেশ

80
না এটি সঠিক উত্তর নয় কারণ এটি ডক্সেও লেখা আছে: "দ্রষ্টব্য: এই পদ্ধতিটি কেবল পরিষেবা পরিচালনার ধরণের ব্যবহারকারী ইন্টারফেসগুলি ডিবাগিং বা প্রয়োগের জন্য is" এটি নিয়ন্ত্রণ প্রবাহের জন্য নয়!

40
সার্ভার চলছে কিনা তা যাচাই করার জন্য লোকেদের সব কিছুর মধ্য দিয়ে যেতে হবে তা মার্জিত মনে হয়?
রুই মার্কস

79
অ্যান্ড্রয়েড হে শুরু করা , getRunningServicesঅবহিত করা হয়েছে। এই উত্তরের আরও নতুন সংস্করণে আপডেট দরকার।
পোস্টিং 91

75

বুঝেছি!

আপনার পরিষেবাটি সঠিকভাবে নিবন্ধিত হওয়ার জন্য আপনাকে অবশ্যই কল startService()করতে হবে এবং পাস করা BIND_AUTO_CREATEযথেষ্ট হবে না।

Intent bindIntent = new Intent(this,ServiceTask.class);
startService(bindIntent);
bindService(bindIntent,mConnection,0);

এবং এখন সার্ভিসটুল ক্লাস:

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(String serviceClassName){
        final ActivityManager activityManager = (ActivityManager)Application.getContext().getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            if (runningServiceInfo.service.getClassName().equals(serviceClassName)){
                return true;
            }
        }
        return false;
     }
}

এটি কেবল সিস্টেম পরিষেবাদির তালিকা তৈরি করবে, না ?! সুতরাং আমার স্থানীয় পরিষেবা তালিকা থেকে বাদ দেওয়া হয়েছে এবং আমি মিথ্যা হয়ে যাব; (
ইওকস

এটি বাহ্যিক পরিষেবাগুলির সাথে কাজ করে, কারণ স্থানীয় পরিষেবাগুলি যদি আপনি চালাচ্ছেন তবে তা স্পষ্ট is
কেভিন পার্কার

11
দুঃখিত তবে আমি বলার দরকার যে এটি নির্বোধ উত্তর..এটি কেন স্পষ্ট?
ইওকস

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

1
এই ধারণাটি দেওয়া ভুল যে একটি সীমাবদ্ধ পরিষেবাটিও শুরু করা উচিত। কোন। বাইন্ড অটো তৈরি ঠিক যা বলে তা তাই করে। পরিষেবাটি এখনও চালু না থাকলে এটি পরিষেবাটি তৈরি করবে (এবং তাই "শুরু") করবে।
শ্রীদেবী জে

57

একটি ছোট পরিপূরক হ'ল:

আমার লক্ষ্যটি হ'ল কোনও পরিষেবা বাস্তবে চালিত না হলে এটি চলমান না থাকলে এটি চলমান।

বাইন্ড সার্ভিস কল করা বা পরিষেবাটি ধরা পড়তে পারে এমন অভিপ্রায় কল করা কোনও ভাল ধারণা নয় কারণ এটি যদি কাজটি চালু না থাকে তবে পরিষেবাটি শুরু করবে।

সুতরাং, অলৌকিক 2 কে পরামর্শ অনুসারে, পরিষেবাটি ক্লাস শুরু হয়েছে কিনা তা জানতে সার্ভিস ক্লাসে একটি স্থির ক্ষেত্র রাখাই ভাল।

এটিকে আরও পরিচ্ছন্ন করার জন্য, আমি একটি খুব অলস আনার সাথে একটি সিঙ্গলটনে পরিষেবাটি রূপান্তর করার পরামর্শ দিচ্ছি: যা স্থির পদ্ধতির মাধ্যমে সিঙ্গেলটন দৃষ্টান্তগুলিতে কোনও তাত্পর্য নেই । আপনার পরিষেবা / সিঙ্গলটনের স্থিতিশীল getInstance পদ্ধতিটি তৈরি করা হয়েছে কেবলমাত্র সিঙ্গলটনের উদাহরণটি দেয়। তবে এটি সত্যই সিঙ্গলটন নিজেই শুরু বা প্রবর্তন করে না। পরিষেবাটি কেবল সাধারণ পরিষেবা শুরু পদ্ধতিগুলির মাধ্যমে শুরু হয়।

বিভ্রান্তিকর getInstance পদ্ধতিটির মতো isInstanceCreated() : booleanপদ্ধতির মতো নতুন নামকরণের জন্য সিঙ্গলটন ডিজাইনের প্যাটার্নটি পরিবর্তন করতে আরও ক্লিনার হবে ।

কোডটি দেখতে পাবেন:

public class MyService extends Service
{
   private static MyService instance = null;

   public static boolean isInstanceCreated() {
      return instance != null;
   }//met

   @Override
   public void onCreate()
   {
      instance = this;
      ....
   }//met

   @Override
   public void onDestroy()
   {
      instance = null;
      ...
   }//met
}//class

এই সমাধানটি মার্জিত, তবে কেবলমাত্র যদি আপনার কাছে পরিষেবা শ্রেণিতে অ্যাক্সেস থাকে এবং কেবলমাত্র ক্লাসের জন্য সেবার অ্যাপ্লিকেশন / প্যাকেজটি আলাদা থাকে তবে তা প্রাসঙ্গিক। যদি আপনার ক্লাসগুলি পরিষেবা অ্যাপ্লিকেশন / প্যাকেজের বাইরে থাকে তবে আপনি পিটার-জান ভ্যান রোবেসের আন্ডারলাইনড সীমাবদ্ধতার সাথে অ্যাক্টিভিটি ম্যানেজারটিকে জিজ্ঞাসা করতে পারেন।


32
এটি ত্রুটিযুক্ত। onDestroy কল করার নিশ্চয়তা নেই।
পেসারিয়ার 5'12

8
যখন সিস্টেমটি মেমরি কম থাকে, তখন আপনার পরিষেবাটি আপনার অনড্রেস্ট্রয়কে কল না করেই স্বয়ংক্রিয়ভাবে মারা যাবে, যার কারণেই আমি বলছি যে এটি ত্রুটিযুক্ত।
পেসেরিয়র

17
@ পেসারিয়ার, তবে যদি সিস্টেমটি প্রক্রিয়াটিকে হত্যা করে, তবে উদাহরণের পতাকা এখনও পুনরায় সেট হয়ে যাবে। আমি অনুমান করছি যে পরবর্তী যখন রিসিভারটি লোড হয়ে যায় (সিস্টেমটি পরিষেবাটি মেরে ফেলবে) স্থির পতাকাটি 'উদাহরণ' বাতিল হয়ে যাবে।
টম

2
মাই সার্ভিসরানিং-এ সমস্ত পরিষেবাগুলির মধ্যে পুনরাবৃত্তির চেয়ে কমপক্ষে আরও ভাল যা প্রতিটি ডিভাইস ঘোরানোর সময় জিনিসগুলিকে সত্যিকার অর্থে বিলম্বিত করে :)
গুনার ফারসগ্রেন - মোবিমেশন

1
আপনার উদাহরণ পরিবর্তনশীলটিকে চূড়ান্ত হিসাবে ঘোষণা করা উচিত নয়, অন্যথায় এটি অনক্রিয়েট () বা অনডাস্ট্রয়ে () পদ্ধতি দ্বারা সেট বা বাতিল করা যাবে না।
k2col

27

আপনি এটি ব্যবহার করতে পারেন (আমি এখনও এটি চেষ্টা করিনি, তবে আমি আশা করি এটি কাজ করে):

if(startService(someIntent) != null) {
    Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}
else {
    Toast.makeText(getBaseContext(), "There is no service running, starting service..", Toast.LENGTH_SHORT).show();
}

ইতিমধ্যে চলমান পরিষেবা থাকলে স্টার্টসোভার পদ্ধতিটি একটি কম্পোনেন্টনাম অবজেক্ট দেয়। যদি তা না হয় তবে নাল ফিরে আসবে।

দেখুন প্রকাশ্য বিমূর্ত ComponentName startService (ইন্টেন্ট পরিষেবা)

এটি আমার মনে হয় যাচাই করার মতো নয়, কারণ এটি পরিষেবাটি শুরু করছে, যাতে আপনি stopService(someIntent);কোডের আওতায় যোগ করতে পারেন ।


11
ডক্স ঠিক কী বলে না। আপনার লিঙ্ক অনুসারে: "রিটার্নস যদি পরিষেবাটি শুরু করা হয় বা ইতিমধ্যে চলমান থাকে তবে প্রকৃত পরিষেবাটির যে অংশটির নাম শুরু হয়েছিল তা ফেরত দেওয়া হয়; অন্যথায় যদি পরিষেবাটি বিদ্যমান না থাকে তবে ফিরে আসবে" "
গ্যাব্রিয়েল

ভাল চিন্তা ... কিন্তু বর্তমান পরিস্থিতিতে ফিট করে না।
কোড_লাইফ

5
এটি যথাযথ উপায় নয়, কারণ যখন আইডিই ট্রিগার if(startService(someIntent) != null)এটি পরীক্ষা করে IsserviceRunningতবে এটি নতুন পরিষেবাও খেলবে।
চিন্তন খেতিয়া

যেমনটি বলা হয়েছে, আপনি যদি এই নিয়ন্ত্রণের পরে পরিষেবাটি বন্ধ করেন তবে এটি এই সমস্যার পক্ষে কার্যকর হবে। তবে কেন কিছুই শুরু করে কোনও পরিষেবা বন্ধ করবেন?
ট্যানার

6
এই পরিষেবা শুরু হবে, তাই না? এটি আরম্ভ করার পরিবর্তে কেবল পরিষেবার স্থিতি পরীক্ষা করতে চান ...
র‌্যাপটার

26
/**
 * Check if the service is Running 
 * @param serviceClass the class of the Service
 *
 * @return true if the service is running otherwise false
 */
public boolean checkServiceRunning(Class<?> serviceClass){
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
    {
        if (serviceClass.getName().equals(service.service.getClassName()))
        {
            return true;
        }
    }
    return false;
}

21

অ্যান্ড্রয়েড ডক্স থেকে একটি এক্সট্র্যাক্ট :

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

এই হ্যাকটিকে "পিনিং" হিসাবে ভাবুনService । যেহেতু আমরা সমকালীনভাবে সম্প্রচার করতে পারি, তাই আমরা ইউআই থ্রেডে সিঙ্ক্রোনালি সম্প্রচার করতে এবং ফলাফল পেতে পারি ।

Service

@Override
public void onCreate() {
   LocalBroadcastManager
     .getInstance(this)
     .registerReceiver(new ServiceEchoReceiver(), new IntentFilter("ping"));
     //do not forget to deregister the receiver when the service is destroyed to avoid
     //any potential memory leaks 
}

private class ServiceEchoReceiver extends BroadcastReceiver {
    public void onReceive (Context context, Intent intent) {
      LocalBroadcastManager
         .getInstance(this)
         .sendBroadcastSync(new Intent("pong"));
    }
}

Activity

    bool serviceRunning = false;

    protected void onCreate (Bundle savedInstanceState){
        LocalBroadcastManager.getInstance(this).registerReceiver(pong, new IntentFilter("pong"));
        LocalBroadcastManager.getInstance(this).sendBroadcastSync(new Intent("ping"));
        if(!serviceRunning){
           //run the service
        }
    }

    private BroadcastReceiver pong = new BroadcastReceiver(){
        public void onReceive (Context context, Intent intent) {
          serviceRunning = true;   
        }
    }

অনেক অ্যাপ্লিকেশনে বিজয়ী অবশ্যই, পরিষেবাটিতে একটি স্ট্যাটিক বুলিয়ান ক্ষেত্র যা সেট এবং trueইন সেট Service.onCreate()করা falseহয়েছে Service.onDestroy()কারণ এটি অনেক সহজ।


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

13

আমি উপরে উপস্থাপিত সমাধানগুলির মধ্যে কিছুটা সংশোধন করেছি, তবে একই পদ্ধতি থেকে আসা স্ট্রিংগুলির তুলনা নিশ্চিত করার জন্য জেনেরিক স্ট্রিং নামের পরিবর্তে ক্লাস পাস করছি class.getName()

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(Context context,Class<?> serviceClass){
        final ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            Log.d(Constants.TAG, String.format("Service:%s", runningServiceInfo.service.getClassName()));
            if (runningServiceInfo.service.getClassName().equals(serviceClass.getName())){
                return true;
            }
        }
        return false;
    }
}

এবং তারপর

Boolean isServiceRunning = ServiceTools.isServiceRunning(
                    MainActivity.this.getApplicationContext(),
                    BackgroundIntentService.class);

আরও কঠোর দিক হতে আপনি ক্লাস Class<? extends Service>
পরমকে

11

কোনও পরিষেবা চলছে কিনা তা পরীক্ষা করার সঠিক উপায়টি কেবল এটি জিজ্ঞাসা করা। আপনার ক্রিয়াকলাপের পিংগুলিতে প্রতিক্রিয়া জানিয়ে আপনার পরিষেবাতে এমন একটি ব্রডকাস্টার্সিভার কার্যকর করুন। পরিষেবাটি শুরু হওয়ার সাথে সাথে ব্রডকাস্টার্সিভারটি নিবন্ধন করুন এবং পরিষেবাটি নষ্ট হয়ে গেলে এটি নিবন্ধভুক্ত করুন। আপনার ক্রিয়াকলাপ (বা কোনও উপাদান) থেকে পরিষেবাটিতে স্থানীয় সম্প্রচারের উদ্দেশ্য পাঠান এবং যদি এটি প্রতিক্রিয়া জানায় তবে আপনি জানেন যে এটি চলছে। নীচের কোডটিতে ACTION_PING এবং ACTION_PONG এর মধ্যে সূক্ষ্ম পার্থক্যটি নোট করুন।

public class PingableService extends Service
{
    public static final String ACTION_PING = PingableService.class.getName() + ".PING";
    public static final String ACTION_PONG = PingableService.class.getName() + ".PONG";

    public int onStartCommand (Intent intent, int flags, int startId)
    {
        LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(ACTION_PING));
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy ()
    {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        super.onDestroy();
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive (Context context, Intent intent)
        {
            if (intent.getAction().equals(ACTION_PING))
            {
                LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
                manager.sendBroadcast(new Intent(ACTION_PONG));
            }
        }
    };
}


public class MyActivity extends Activity
{
    private boolean isSvcRunning = false;

    @Override
    protected void onStart()
    {
        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
        manager.registerReceiver(mReceiver, new IntentFilter(PingableService.ACTION_PONG));
        // the service will respond to this broadcast only if it's running
        manager.sendBroadcast(new Intent(PingableService.ACTION_PING));
        super.onStart();
    }

    @Override
    protected void onStop()
    {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        super.onStop();
    }

    protected BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive (Context context, Intent intent)
        {
            // here you receive the response from the service
            if (intent.getAction().equals(PingableService.ACTION_PONG))
            {
                isSvcRunning = true;
            }
        }
    };
}

1
আমি আসলে এই পদ্ধতির পছন্দ। এটি সামান্য ভারী কোড অনুসারে তবে সর্বদা কার্যকর হবে। আমি শীঘ্রই যে কোনও সময় সম্প্রচারের উদ্দেশ্যগুলি
হ্রাস করা

8

আমি কেবল @ স্নিকোলাসের উত্তরে একটি নোট যুক্ত করতে চাই। কল না করে / ছাড়াই স্টপ পরিষেবা চেক করতে নিম্নলিখিত পদক্ষেপগুলি ব্যবহার করা যেতে পারে onDestroy()

  1. onDestroy() বলা হয়েছে: সেটিংসে যান -> অ্যাপ্লিকেশন -> চলমান পরিষেবাদি -> আপনার পরিষেবাটি নির্বাচন করুন এবং বন্ধ করুন।

  2. onDestroy()কল করা নেই: সেটিংসে যান -> অ্যাপ্লিকেশন -> অ্যাপ্লিকেশনগুলি পরিচালনা করুন -> আপনার অ্যাপ্লিকেশনটি যেখানে আপনার পরিষেবা চলছে সেগুলি নির্বাচন করুন এবং "ফোর্স স্টপ" নির্বাচন করুন। তবে, আপনার আবেদন এখানে যেমন বন্ধ হয়ে গেছে, তাই অবশ্যই পরিষেবাগুলির উদাহরণগুলিও বন্ধ হয়ে যাবে।

পরিশেষে, আমি উল্লেখ করতে চাই যে সিঙ্গেলটন শ্রেণিতে একটি স্ট্যাটিক ভেরিয়েবল ব্যবহার করে সেখানে উল্লিখিত পদ্ধতির বিষয়টি আমার পক্ষে কাজ করছে।


7

onDestroy সর্বদা পরিষেবাতে ডাকা হয় না তাই এটি অকেজো!

উদাহরণস্বরূপ: Eclipse থেকে এক পরিবর্তন নিয়ে আবার অ্যাপ্লিকেশনটি চালান। অ্যাপ্লিকেশনটি জোরপূর্বক SIG: 9 ব্যবহার করে বেরিয়েছে।


6

সবার আগে আপনি অ্যাক্টিভিটি ম্যানেজারটি ব্যবহার করে পরিষেবাতে পৌঁছানোর চেষ্টা করবেন না। ( এখানে আলোচনা করা হয়েছে )

পরিষেবাগুলি নিজেরাই চলতে পারে, কোনও ক্রিয়াকলাপ বা উভয়ের জন্য আবদ্ধ হতে পারে। আপনার পরিষেবাটি চলছে কিনা তা একটি কার্যকলাপে পরীক্ষা করার উপায়টি এমন একটি ইন্টারফেস (যা বাইন্ডারকে প্রসারিত করে) তৈরি করে যেখানে আপনি যে পদ্ধতি এবং কার্যকলাপ, উভয়ই বোঝে সেই পদ্ধতিগুলি ঘোষণা করেন। আপনি নিজের ইন্টারফেস তৈরি করে এটি করতে পারেন যেখানে আপনি উদাহরণস্বরূপ "isServiceRunning ()" ঘোষণা করেন। তারপরে আপনি আপনার ক্রিয়াকলাপটিকে আপনার সেবায় বাঁধতে পারেন, পদ্ধতিটি চালিয়ে যাবেন সার্ভিসরানিং (), পরিষেবাটি এটি চলছে কিনা তা খতিয়ে দেখবে এবং আপনার ক্রিয়াকলাপটিতে একটি বুলিয়ান দেয়।

আপনি আপনার পরিষেবা বন্ধ করতে বা অন্য উপায়ে এটির সাথে ইন্টারঅ্যাক্ট করার জন্যও এই পদ্ধতিটি ব্যবহার করতে পারেন।

আমি এই অ্যাপ্লিকেশনটিতে এই দৃশ্যটি কীভাবে প্রয়োগ করতে পারি তা শিখতে এই টিউটোরিয়ালটি ব্যবহার করেছি।


3
'12 / 26/07 'এ সেই আলোচনা অনুষ্ঠিত হয়েছিল। হয় এই বছরের জুলাই (অর্থাত্ ভবিষ্যতে), বা এটি অ্যান্ড্রয়েড এমনকি সর্বসাধারণের আগে। যেভাবেই এটি আমাকে বিশ্বাস করে না।
টম

যে আলোচনা হয় 26 ডিসেম্বর, 2007 তারা একটি প্রাক রিলিজ সংস্করণ আমি মনে করি (আলোচনা করছে থেকে developer.android.com/sdk/OLD_RELEASENOTES.html#m3-rc37a ) যা 14 ডিসেম্বর, 2007 মুক্তি পায়
ingh.am

6

আবার, অন্য একটি বিকল্প যা লোকেরা ক্লিনার খুঁজে পেতে পারে যদি তারা মুলতুবি থাকা উদ্দেশ্যগুলি ব্যবহার করে (উদাহরণস্বরূপ AlarmManager:

public static boolean isRunning(Class<? extends Service> serviceClass) {
    final Intent intent = new Intent(context, serviceClass);
    return (PendingIntent.getService(context, CODE, intent, PendingIntent.FLAG_NO_CREATE) != null);
}

CODEআপনার ক্লাসে ব্যক্তিগতভাবে আপনার পরিষেবার সাথে সম্পর্কিত মুলতুবি থাকা উদ্দেশ্যগুলি সনাক্ত করতে আপনি যে স্থিরতাটি স্থির করেন Where


1
সংযুক্ত বা আপনার পূর্ববর্তী উত্তর আপডেট করুন। দয়া করে প্রতি পোস্টে একাধিক উত্তর পোস্ট করা থেকে বিরত থাকুন।
চুওংপাম

এই উত্তরটি কীভাবে প্রসারিত করা যেতে পারে, অর্থাত কীভাবে কোনও এই কোডটির সাথে কোডের মান যুক্ত করে?
ডেভ নোটেজ

প্রসঙ্গ কোথায় পাবেন?
তুলসী

6

নীচে একটি মার্জিত হ্যাক যা সমস্তকে কভার করে Ifs। এটি কেবল স্থানীয় পরিষেবার জন্য।

    public final class AService extends Service {

        private static AService mInstance = null;

        public static boolean isServiceCreated() {
            try {
                // If instance was not cleared but the service was destroyed an Exception will be thrown
                return mInstance != null && mInstance.ping();
            } catch (NullPointerException e) {
                // destroyed/not-started
                return false;
            }
        }

        /**
         * Simply returns true. If the service is still active, this method will be accessible.
         * @return
         */
        private boolean ping() {
            return true;
        }

        @Override
        public void onCreate() {
            mInstance = this;
        }

        @Override
        public void onDestroy() {
            mInstance = null;
        }
    }

এবং তারপরে পরে:

    if(AService.isServiceCreated()){
        ...
    }else{
        startService(...);
    }

এটির সাথে একমাত্র সমস্যাটি যদি পরিষেবাটি একটি স্টিকি পরিষেবা হয় এবং এটি নিজেই পুনরায় চালু হয়। ISSCCated () তে কল করার পরে পরিষেবাটি আবার শুরু হওয়ার পরে মিথ্যা ফিরে আসবে কারণ মিস্ট্যান্সটি বাতিল হয়ে যাবে।
মীরা_কোল

1
পরিষেবাটি আবার চালু হয়ে গেলে কি অনক্রিটকে ডাকা হবে না?
TheRealChx101

6

জামারিন সি # সংস্করণ:

private bool isMyServiceRunning(System.Type cls)
{
    ActivityManager manager = (ActivityManager)GetSystemService(Context.ActivityService);

    foreach (var service in manager.GetRunningServices(int.MaxValue)) {
        if (service.Service.ClassName.Equals(Java.Lang.Class.FromType(cls).CanonicalName)) {
            return true;
        }
    }
    return false;
}

আপনার জন্য'Context` প্রয়োজন GetSystemService
টেস্ট

5

এখানে প্রদত্ত ব্যবহার-মামলার জন্য আমরা কেবল stopService()পদ্ধতির রিটার্ন মানটি ব্যবহার করতে পারি । trueযদি সেখানে নির্দিষ্ট পরিষেবা উপস্থিত থাকে এবং এটি মারা যায় তবে এটি ফিরে আসে । অন্যথায় এটি ফিরে আসে false। সুতরাং আপনি যদি ফলাফলটি falseনা পান তবে পরিষেবাটি পুনরায় চালু করতে পারেন এটির আশ্বাস দেওয়া হয় যে বর্তমান পরিষেবাটি বন্ধ হয়ে গেছে। :) এটা ভালো হতে যদি আপনি কটাক্ষপাত হবে এই


5

কোটলিন ব্যবহার করে আরেকটি পদ্ধতি। অন্যান্য ব্যবহারকারীদের উত্তরে অনুপ্রাণিত

fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
    val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    return manager.getRunningServices(Integer.MAX_VALUE)
            .any { it.service.className == serviceClass.name }
}

কোটলিন এক্সটেনশন হিসাবে

fun Context.isMyServiceRunning(serviceClass: Class<*>): Boolean {
    val manager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    return manager.getRunningServices(Integer.MAX_VALUE)
            .any { it.service.className == serviceClass.name }
}

ব্যবহার

context.isMyServiceRunning(MyService::class.java)

4

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

companion object{
     var isRuning = false

}

পরিষেবা তৈরি এবং ধ্বংস হয়ে গেলে এর মান পরিবর্তন করুন

 override fun onCreate() {
        super.onCreate()
        isRuning = true
    }

override fun onDestroy() {
    super.onDestroy()
    isRuning = false
    }

3

আপনার পরিষেবাতে সাব-ক্লাসে পরিষেবার স্থিতি নীচে প্রদর্শিত হিসাবে দেখতে একটি স্ট্যাটিক বুলিয়ান ব্যবহার করুন।

MyService.kt

class MyService : Service() {
    override fun onCreate() {
        super.onCreate()
        isServiceStarted = true
    }
    override fun onDestroy() {
        super.onDestroy()
        isServiceStarted = false
    }
    companion object {
        var isServiceStarted = false
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val serviceStarted = FileObserverService.isServiceStarted
        if (!serviceStarted) {
            val startFileObserverService = Intent(this, FileObserverService::class.java)
            ContextCompat.startForegroundService(this, startFileObserverService)
        }
    }
}

3

কোটলিনের জন্য, আপনি নীচের কোডটি ব্যবহার করতে পারেন।

fun isMyServiceRunning(calssObj: Class<SERVICE_CALL_NAME>): Boolean {
    val manager = requireActivity().getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (calssObj.getName().equals(service.service.getClassName())) {
            return true
        }
    }
    return false
}

এটি পরীক্ষার লেখার জন্য দুর্দান্ত উত্তর, যেহেতু আপনি এটি আপনার কাজের কোড পরিবর্তন না করে ব্যবহার করতে পারেন।
রবার্ট লিবারাতোর

2

GeekQ এর প্রতিক্রিয়া কিন্তু কোটলিন ক্লাসে। ধন্যবাদ geekQ

fun isMyServiceRunning(serviceClass : Class<*> ) : Boolean{
    var manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.name.equals(service.service.className)) {
            return true
        }
    }
    return false
}

কল

isMyServiceRunning(NewService::class.java)

6
ActivityManager.getRunningServicesযেহেতু অ্যান্ড্রয়েড হে অননুমোদিত
ড্যানিয়েল Shatz

1

একই শ্রেণীর নাম সহ বেশ কয়েকটি পরিষেবা থাকতে পারে।

আমি সবেমাত্র দুটি অ্যাপ তৈরি করেছি। প্রথম অ্যাপ্লিকেশনটির প্যাকেজের নাম com.example.mock। আমি loremঅ্যাপটিতে কল করা একটি সাবপ্যাকেজ এবং একটি পরিষেবা কল করেছি Mock2Service। সুতরাং এটির পুরোপুরি যোগ্য নাম com.example.mock.lorem.Mock2Service

তারপরে আমি দ্বিতীয় অ্যাপ এবং একটি পরিষেবা তৈরি করেছি Mock2Service। দ্বিতীয় অ্যাপের প্যাকেজের নাম com.example.mock.lorem। পরিষেবার সম্পূর্ণরূপে যোগ্য নামও com.example.mock.lorem.Mock2Service

এখানে আমার লগক্যাট আউটপুট।

03-27 12:02:19.985: D/TAG(32155): Mock-01: com.example.mock.lorem.Mock2Service
03-27 12:02:33.755: D/TAG(32277): Mock-02: com.example.mock.lorem.Mock2Service

ভালো ধারণা তুলনা হয় ComponentNameদৃষ্টান্ত কারণ equals()এর ComponentNameপ্যাকেজের নাম এবং ক্লাস নাম উভয় তুলনা করা হয়। এবং কোনও ডিভাইসে একই প্যাকেজের নাম ইনস্টল থাকা দুটি অ্যাপ থাকতে পারে না।

এর সমান () পদ্ধতি ComponentName

@Override
public boolean equals(Object obj) {
    try {
        if (obj != null) {
            ComponentName other = (ComponentName)obj;
            // Note: no null checks, because mPackage and mClass can
            // never be null.
            return mPackage.equals(other.mPackage)
                    && mClass.equals(other.mClass);
        }
    } catch (ClassCastException e) {
    }
    return false;
}

উপাদানের নাম


1

দয়া করে এই কোডটি ব্যবহার করুন।

if (isMyServiceRunning(MainActivity.this, xyzService.class)) { // Service class name
    // Service running
} else {
    // Service Stop
}


public static boolean isMyServiceRunning(Activity activity, Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

0

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

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


0

যদি পরিষেবাটি অন্য কোনও প্রক্রিয়ার অন্তর্ভুক্ত হয় বা এপিপি ক্রিয়াকলাপের উপর ভিত্তি করে সমাধানটি ব্যবহার করে।

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

আপনি আপনার পরিষেবা থেকে সম্প্রচারের বিজ্ঞপ্তি প্রেরণের মতো আরও তথ্যের সাথে চলছে তা নির্দেশ করেও পাঠাতে পারেন।


0

ইন সার্ভিসক্লাসের ভিতরে সংজ্ঞা দেওয়া:

 public static Boolean serviceRunning = false;

তারপরে অন স্টার্টকমন্ডে (...)

 public int onStartCommand(Intent intent, int flags, int startId) {

    serviceRunning = true;
    ...
}

 @Override
public void onDestroy()
{
    serviceRunning = false;

} 

তারপরে, যে if(TheServiceClass.serviceRunning == true)কোনও ক্লাস থেকে কল করুন ।


4
যদি আপনার পরিষেবা অ্যান্ড্রয়েড দ্বারা নিহত হয় তবে এটি কাজ করে না।
হাইজেনবার্গ

@ হাইজেনবার্গ আমি নিজেই এটি অভিজ্ঞতা পেয়েছি। আপনি জানেন না কেন?
টিম

@ হাইজেনবার্গ যখন আমার অ্যাপ্লিকেশনটিকে ওএস দ্বারা হত্যা করা হয়, পরিষেবাটি পুনরায় আরম্ভ করে এবং স্ট্যাটিক বুলকে সত্যে সেট করে তবে এটি মিথ্যা প্রতিবেদন করার পরে
টিম

আপনি কল করলে এটি কাজ করবে না stopService। কমপক্ষে ইনটেন্ট পরিষেবাগুলির জন্য। onDestroy()তাত্ক্ষণিকভাবে ডাকা হবে, তবে onHandleIntent()এখনও চলবে
serggl

1
@ হাইজেনবার্গ কম স্মৃতিশক্তির কারণে এই পরিষেবাটি মেরে ফেলাও কি প্রক্রিয়াটি হত্যার অর্থ?
অ্যান্ড্রয়েড বিকাশকারী 21

0

সাধারণ ব্যবহারের বাইন্ডটি অটো তৈরি করবেন না - পিএস দেখুন। এবং আপডেট ...

public abstract class Context {

 ... 

  /*
  * @return {true} If you have successfully bound to the service, 
  *  {false} is returned if the connection is not made 
  *  so you will not receive the service object.
  */
  public abstract boolean bindService(@RequiresPermission Intent service,
        @NonNull ServiceConnection conn, @BindServiceFlags int flags);

উদাহরণ:

    Intent bindIntent = new Intent(context, Class<Service>);
    boolean bindResult = context.bindService(bindIntent, ServiceConnection, 0);

কেন ব্যবহার করছেন না? getRunningServices ()

List<ActivityManager.RunningServiceInfo> getRunningServices (int maxNum)
Return a list of the services that are currently running.

দ্রষ্টব্য: এই পদ্ধতিটি কেবল পরিষেবা পরিচালনার ধরণের ব্যবহারকারী ইন্টারফেসগুলি ডিবাগিং বা প্রয়োগের জন্য is


পুনশ্চ. অ্যান্ড্রয়েড ডকুমেন্টেশন বিভ্রান্ত করছে যে কোনও সন্দেহ দূর করতে আমি গুগল ট্র্যাকারে একটি সমস্যা খুলেছি:

https://issuetracker.google.com/issues/68908332

যেহেতু আমরা দেখতে পাই বাঁধাই পরিষেবাটি আসলে পরিষেবা ক্যাশে বাইন্ডারগুলির মাধ্যমে অ্যাক্টিভিটি ম্যানেজার বাইন্ডারের মাধ্যমে একটি লেনদেনের জন্য আহ্বান জানায় - আমি জানতে পারি কোন বাঁধাইয়ের জন্য দায়ী কোন পরিষেবা তবে আমরা দেখতে পাচ্ছি যে বাইন্ডের ফলাফলটি হ'ল:

int res = ActivityManagerNative.getDefault().bindService(...);
return res != 0;

লেনদেন বাইন্ডারের মাধ্যমে করা হয়:

ServiceManager.getService("activity");

পরবর্তী:

  public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return getIServiceManager().getService(name);

এটি এর মাধ্যমে অ্যাক্টিভিটি থ্রেডে সেট করা আছে:

 public final void bindApplication(...) {

        if (services != null) {
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }

এটিকে এক্টিভিটি ম্যানেজারসেবা পদ্ধতিতে বলা হয়:

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
    ...
    thread.bindApplication(... , getCommonServicesLocked(),...)

তারপর:

 private HashMap<String, IBinder> getCommonServicesLocked() {

তবে কোনও "ক্রিয়াকলাপ" নেই কেবল উইন্ডো প্যাকেজ এবং অ্যালার্ম ..

সুতরাং আমাদের ফিরে কল করা প্রয়োজন:

 return getIServiceManager().getService(name);

    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

এটি কল মাধ্যমে কল করে:

    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

যা বাড়ে :

BinderInternal.getContextObject()

এবং এটি স্থানীয় পদ্ধতি ....

  /**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();

আমার কাছে এখন আর সি খনন করার সময় নেই যাতে আমি বিশ্রাম কলটি ছড়িয়ে না দেওয়া পর্যন্ত আমি আমার উত্তর স্থগিত করি।

তবে পরিষেবাটি চলছে কিনা তা যাচাই করার সর্বোত্তম উপায় হ'ল বাঁধাই তৈরি করা (যদি বাইন্ড তৈরি না করা পরিষেবাটি বিদ্যমান না থাকে) - এবং বাইন্ডের মাধ্যমে পরিষেবাটিকে তার রাজ্য সম্পর্কে জিজ্ঞাসা করুন (এটিতে স্টোরের অভ্যন্তরীণ পতাকা ব্যবহার করে)।

আপডেট 23.06.2018

আমি আকর্ষণীয় পেয়েছি:

/**
 * Provide a binder to an already-bound service.  This method is synchronous
 * and will not start the target service if it is not present, so it is safe
 * to call from {@link #onReceive}.
 *
 * For peekService() to return a non null {@link android.os.IBinder} interface
 * the service must have published it before. In other words some component
 * must have called {@link android.content.Context#bindService(Intent, ServiceConnection, int)} on it.
 *
 * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)}
 * @param service Identifies the already-bound service you wish to use. See
 * {@link android.content.Context#bindService(Intent, ServiceConnection, int)}
 * for more information.
 */
public IBinder peekService(Context myContext, Intent service) {
    IActivityManager am = ActivityManager.getService();
    IBinder binder = null;
    try {
        service.prepareToLeaveProcess(myContext);
        binder = am.peekService(service, service.resolveTypeIfNeeded(
                myContext.getContentResolver()), myContext.getOpPackageName());
    } catch (RemoteException e) {
    }
    return binder;
}

সংক্ষেপে :)

"ইতিমধ্যে সীমাবদ্ধ পরিষেবাকে একটি বাইন্ডার সরবরাহ করুন This এই পদ্ধতিটি সিঙ্ক্রোনাস এবং এটি উপস্থিত না থাকলে লক্ষ্য পরিষেবাটি শুরু করবে না।"

পাবলিক আইবাইন্ডার পিক সার্ভিস (ইনটেন্ট সার্ভিস, স্ট্রিং রিলিজড টাইপ, স্ট্রিং কলিংপ্যাকেজ) রিমোটএক্সেপশন ছুড়ে ফেলে;

*

public static IBinder peekService(IBinder remote, Intent service, String resolvedType)
             throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken("android.app.IActivityManager");
    service.writeToParcel(data, 0);
    data.writeString(resolvedType);
    remote.transact(android.os.IBinder.FIRST_CALL_TRANSACTION+84, data, reply, 0);
    reply.readException();
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}

*


bindResult (বিনড সার্ভিস পদ্ধতির রিটার্ন মান) পরিষেবা চালু না থাকলে মিথ্যা হিসাবে আসে না।
সংগীত সিভান

0

ActivityManager::getRunningServicesভিত্তিক উত্তরের আমার কোটলিন রূপান্তর । এই ক্রিয়াকলাপটি একটি ক্রিয়াকলাপে রাখুন-

private fun isMyServiceRunning(serviceClass: Class<out Service>) =
    (getSystemService(ACTIVITY_SERVICE) as ActivityManager)
        .getRunningServices(Int.MAX_VALUE)
        ?.map { it.service.className }
        ?.contains(serviceClass.name) ?: false

-2

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

1. Open Settings in your Android device.
2. Find Developer Options.
3. Find Running Services option.
4. Find your app icon.
5. You will then see all the service that belongs to your app running in the background.

-5

এটি সহজ ছেলেদের নিন ... :)

আমি মনে করি যে SharedPreferencesপরিষেবাটি চালু আছে কিনা তা সর্বাধিক উপযুক্ত সমাধানটি একটি মূল-মান জুটি রাখে ।

যুক্তি খুব সোজা; আপনার পরিষেবা শ্রেণিতে যে কোনও পছন্দসই অবস্থানে; একটি বুলিয়ান মান রাখুন যা পরিষেবাটি চলছে কিনা তা নিয়ে আপনার জন্য পতাকা হিসাবে কাজ করবে। তারপরে আপনি নিজের অ্যাপ্লিকেশনটিতে এই মানটি যেদিকেই চান পড়ুন।

আমি আমার অ্যাপটিতে একটি নমুনা কোড ব্যবহার করছি যা নীচে রয়েছে:

আমার পরিষেবা শ্রেণিতে (অডিও স্ট্রিমের জন্য একটি পরিষেবা), পরিষেবাটি শেষ হলে আমি নিম্নলিখিত কোডটি কার্যকর করি;

private void updatePlayerStatus(boolean isRadioPlaying)
{
        SharedPreferences sharedPref = this.getSharedPreferences(getString(R.string.str_shared_file_name), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putBoolean(getString(R.string.str_shared_file_radio_status_key), isRadioPlaying);
        editor.commit();
}

তারপরে আমার আবেদনের যে কোনও ক্রিয়াকলাপে, আমি নীচের কোডটির সাহায্যে পরিষেবার স্থিতি পরীক্ষা করছি;

private boolean isRadioRunning() {
        SharedPreferences sharedPref = this.getSharedPreferences(getString(R.string.str_shared_file_name), Context.MODE_PRIVATE);

        return sharedPref.getBoolean(getString(R.string.str_shared_file_radio_status_key), false);
}

কোনও বিশেষ অনুমতি নেই, কোনও লুপ নেই ... সহজ উপায়, পরিষ্কার সমাধান :)

আপনার যদি অতিরিক্ত তথ্য প্রয়োজন হয় তবে দয়া করে লিঙ্কটি উল্লেখ করুন

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


19
কেবলমাত্র যে তারা যখন পরিষেবাটি মেরে তখন কেউই আপনার জন্য মূল্য আপডেট করে না
গুনার ফারসগ্রেন - মোবিমেশন

যখন ডেডট্রয়ে () সার্ভিসটি হত্যা করবেন তখন ট্রিগার হবে এবং এটি তার রাষ্ট্র আপডেট করা সম্ভব
জংজ পুয়াংপুট

5
@ জংজপুয়াংপুট, onDestroyপরিষেবাটি মারা যাওয়ার সময় সর্বদা ডাকা হয় না। উদাহরণস্বরূপ, আমি আমার পরিষেবাদিগুলি কল না করে লো মেমোরি পরিস্থিতিতে নিহত দেখেছি onDestroy
স্যাম

@ স্যাম তাহলে কি ডাকবে?
রুচির বড়োনিয়া

2
@ রুচিরবারোনিয়া যতদূর আমার মনে আছে, আপনার জিনিসগুলি মারা গেলে আপনি কেবল অবহিত হন না। আমি বিশ্বাস করি অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলিকে প্রয়োজনমতো হত্যা করার জন্য ডিজাইন করা হয়েছে এবং অ্যাপ্লিকেশনগুলি বিনা বিজ্ঞপ্তি ছাড়াই যে কোনও সময়ে নিহত হওয়ার আশা করার জন্য তৈরি করা উচিত।
স্যাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.