অ্যান্ড্রয়েডে অগ্রভাগের পরিষেবার জন্য আমি কীভাবে বিজ্ঞপ্তি পাঠ্য আপডেট করব?


133

অ্যান্ড্রয়েডে আমার অগ্রভাগের পরিষেবা সেটআপ রয়েছে। আমি বিজ্ঞপ্তি পাঠ্য আপডেট করতে চাই। আমি নীচে প্রদর্শিত হিসাবে পরিষেবা তৈরি করছি।

এই অগ্রভাগ পরিষেবাটির মধ্যে সেটআপ করা বিজ্ঞপ্তি পাঠ্য কীভাবে আপডেট করব? বিজ্ঞপ্তি আপডেট করার জন্য সেরা অনুশীলন কী? যে কোনও নমুনা কোড প্রশংসা করা হবে।

public class NotificationService extends Service {

    private static final int ONGOING_NOTIFICATION = 1;

    private Notification notification;

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

        this.notification = new Notification(R.drawable.statusbar, getText(R.string.app_name), System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, AbList.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        this.notification.setLatestEventInfo(this, getText(R.string.app_name), "Update This Text", pendingIntent);

        startForeground(ONGOING_NOTIFICATION, this.notification);

    }

আমি নীচে দেখানো হিসাবে আমার মূল কার্যকলাপে পরিষেবাটি তৈরি করছি:

    // Start Notification Service
    Intent serviceIntent = new Intent(this, NotificationService.class);
    startService(serviceIntent);

উত্তর:


61

আমি ভাবব যে startForeground()একই অনন্য আইডি এবং Notificationনতুন তথ্য সহ একটি আবার কল করা কার্যকর হবে, যদিও আমি এই দৃশ্যের চেষ্টা করি নি।

আপডেট: মন্তব্যের উপর ভিত্তি করে আপনার বিজ্ঞপ্তিটি আপডেট করতে NotifcationManager ব্যবহার করা উচিত এবং আপনার পরিষেবাটি অগ্রভাগের মোডে অবিরত থাকবে। নীচের উত্তরটি দেখুন।


1
আপনি কীভাবে আমাকে আমার ক্রিয়াকলাপ থেকে এটি কল করবেন তার একটি উদাহরণ দিতে পারেন? আমার অগ্রভাগ পরিষেবাটিতে কীভাবে কল করতে হবে তার কোনও ভাল নমুনা আমি খুঁজে পাচ্ছি না।
লুক

1
@ লুক: কোনও পরিষেবা ব্যবহারের জন্য অনেকগুলি নিদর্শন রয়েছে এবং আপনার কী অনুসরণ করা হচ্ছে তা আমার কোনও ধারণা নেই। আপনি যদি startService()পরিষেবাটিতে কোনও আদেশ startService()পাঠানোর জন্য ফোন দিচ্ছেন, তবে এটির পাঠ্য আপডেট করার জন্য এটি বলার জন্য কেবল আবার কল করুন। অথবা, আপনি যদি কল দিচ্ছেন bindService()তবে পরিষেবাটির পাঠ্য আপডেট করার জন্য আপনার API এ একটি পদ্ধতি যুক্ত করুন। অথবা, পরিষেবাটি নিজেই সেই সিদ্ধান্তটি গ্রহণ করা উচিত কিনা তা পাঠ্য আপডেট করার বিষয়ে বিবেচনা করুন। অথবা, সম্ভবত পাঠ্যটি এমন একটি SharedPeferenceযা পরিষেবাটিতে শ্রোতা রয়েছে। বিমূর্তে আপনাকে সঠিক পরামর্শ দেওয়া অসম্ভব।
কমন্সওয়্যার

9
আরও স্পষ্ট করার জন্য: আপনি cancel()দ্বারা বিজ্ঞপ্তি সেট করতে পারবেন না startForeground()। আপনি পরিষেবার নিজেই (ব্যবহারের ফোরগ্রাউন্ড অবস্থা অপসারণ করতে হবে stopForeground()। যদি আপনি টিকার আবার পাঠ প্রদর্শিত করতে চান তাহলে আমি ঘন্টার কারণ এই উত্তরগুলোর আমাকে বিশ্বাস করা সম্ভব আসলে ছিল নেতৃত্বে হারিয়ে গেছে।
slinden77

4
আমি এই উত্তরটিকে স্পষ্টত ভুল বলে মেনে নিয়েছি : বিকাশকারী.অ্যান্ড্রয়েড / ট্রেনিং / নোটিফাইজার / ম্যানেজিং এইচটিএমএল দয়া করে @ কমন্সওয়্যার এই উত্তরটি সরিয়ে নেওয়ার বিষয়টি বিবেচনা করুন, কারণ আপনার উচ্চ খ্যাতিমান স্কোর এই উত্তরটিকে "পবিত্র সত্য" হিসাবে তোলে নৈমিত্তিক ব্রাউজার ধন্যবাদ।
এইচওয়াইএস

2
আমার জন্য কাজ করেনি (যদিও আমি আগের প্রকল্পে এই একই পদ্ধতিটি ব্যবহার করে মনে করি)। NotificationManagerআমি প্রত্যাশা হিসাবে কাজ করে ।
ব্যবহারকারী 149408

224

আপনি যখন স্টার্টফোরগ্রাউন্ড () দ্বারা সেট করে একটি বিজ্ঞপ্তি আপডেট করতে চান, কেবল একটি নতুন বিজ্ঞপ্তি তৈরি করুন এবং তারপরে এটি সূচিত করার জন্য নোটিফিকেশন ম্যানেজারটি ব্যবহার করুন।

মূল বিষয় হ'ল একই বিজ্ঞপ্তি আইডি ব্যবহার করা।

আমি বিজ্ঞপ্তি আপডেট করতে বারবার স্টার্টফোরগ্রাউন্ডে () কল করার দৃশ্যের পরীক্ষা করিনি, তবে আমি মনে করি যে বিজ্ঞপ্তি ম্যানেজ.নোটিফাইটি ব্যবহার করা আরও ভাল হবে।

বিজ্ঞপ্তি আপডেট করা পরিষেবাটিকে অগ্রভাগের স্থিতি থেকে সরিয়ে দেবে না (এটি কেবল স্টপফ্রাউন্ডে কল করেই করা যেতে পারে);

উদাহরণ:

private static final int NOTIF_ID=1;

@Override
public void onCreate (){
    this.startForeground();
}

private void startForeground() {
    startForeground(NOTIF_ID, getMyActivityNotification(""));
}

private Notification getMyActivityNotification(String text){
    // The PendingIntent to launch our activity if the user selects
    // this notification
    CharSequence title = getText(R.string.title_activity);
    PendingIntent contentIntent = PendingIntent.getActivity(this,
            0, new Intent(this, MyActivity.class), 0);

    return new Notification.Builder(this)
            .setContentTitle(title)
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_launcher_b3)
            .setContentIntent(contentIntent).getNotification();     
}

/**
 * This is the method that can be called to update the Notification
 */
private void updateNotification() {
    String text = "Some text that will update the notification";

    Notification notification = getMyActivityNotification(text);

    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(NOTIF_ID, notification);
}

ডকুমেন্টেশন রাজ্যের

কোনও বিজ্ঞপ্তি সেট আপ করতে যাতে এটি আপডেট করা যায়, কল করে নোটিফিকেশন আইডি দিয়ে এটি জারি করুন NotificationManager.notify()। আপনি এটি জারি করার পরে এই বিজ্ঞপ্তিটি আপডেট করার জন্য, কোনও NotificationCompat.Builderবিষয় আপডেট করুন বা তৈরি করুন , Notificationএটি থেকে একটি বিষয় তৈরি করুন এবং Notificationআপনি আগে ব্যবহার করেছেন একই আইডি দিয়ে ইস্যু করুন । যদি পূর্বের বিজ্ঞপ্তিটি এখনও দৃশ্যমান হয় তবে সিস্টেমটি তাকে Notificationঅবজেক্টের সামগ্রী থেকে আপডেট করে । পূর্ববর্তী বিজ্ঞপ্তিটি যদি খারিজ করা হয় তবে পরিবর্তে একটি নতুন বিজ্ঞপ্তি তৈরি করা হবে।


35
এটা সঠিক উত্তর! উপরের উত্তরটি খুব ভুল এবং বিভ্রান্তিকর। আপনার নিখুঁত বিজ্ঞপ্তি আপডেট করার জন্য আপনাকে কেবল আপনার পরিষেবাটি পুনরায় চালু করার দরকার নেই।
রাদু

7
@ রাদু যদিও আমি সম্মত হই যে এটিই সর্বোত্তম উত্তর (এটি কমন্সওয়্যারের উত্তর নিয়ে নেওয়া কিছুটা দীর্ঘ কোড-পাথ এড়িয়ে চলে) আপনি ভুল করেছেন যে কমন্সওয়্যারের উত্তর কী করে - স্টার্ট / স্টপফোরগাউন্ড পরিষেবাটি শুরু করে / বন্ধ করে না, তারা কেবল তার অগ্রভাগকে প্রভাবিত করে ।
স্টিভি

@ স্টেভি ধন্যবাদ যে স্টিভির জন্য আপনি সম্ভবত সঠিক বলেছেন। তবুও আমি তা নিয়ে গণ্ডগোল করব না!
রাদু

কলিং notify()বা startForeground()উভয় নেতৃত্ব ডাকতে onStartCommand()
এম রেজা নাসিরলু

10
এর সাথে NotificationManagerপ্রদর্শিত একটি বিজ্ঞপ্তি আপডেট করতে ব্যবহার করার ক্ষেত্রে সমস্যাটি startForegroundহ'ল কলিংটি stopForegroundআর বিজ্ঞপ্তি সরিয়ে ফেলবে না। অন্য কল দিয়ে এটিকে আপডেট করা startForegroundসেই সমস্যাটি থেকে মুক্তি দেয়।
টাদ

21

অ্যান্ড্রয়েড 8.0+ এ লুকা মানজোর উত্তরটির উন্নতি করা বিজ্ঞপ্তিটি আপডেট করার সময় এটি শব্দ করবে এবং শিরোনাম হিসাবে প্রদর্শিত হবে।
আপনার যুক্ত করা প্রয়োজন যে রোধ করতেsetOnlyAlertOnce(true)

সুতরাং কোডটি হল:

private static final int NOTIF_ID=1;

@Override
public void onCreate(){
        this.startForeground();
}

private void startForeground(){
        startForeground(NOTIF_ID,getMyActivityNotification(""));
}

private Notification getMyActivityNotification(String text){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
        ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(
        NotificationChannel("timer_notification","Timer Notification",NotificationManager.IMPORTANCE_HIGH))
}

        // The PendingIntent to launch our activity if the user selects
        // this notification
        PendingIntent contentIntent=PendingIntent.getActivity(this,
        0,new Intent(this,MyActivity.class),0);

        return new NotificationCompat.Builder(this,"my_channel_01")
        .setContentTitle("some title")
        .setContentText(text)
        .setOnlyAlertOnce(true) // so when data is updated don't make sound and alert in android 8.0+
        .setOngoing(true)
        .setSmallIcon(R.drawable.ic_launcher_b3)
        .setContentIntent(contentIntent)
        .build();
}

/**
 * This is the method that can be called to update the Notification
 */
private void updateNotification(){
        String text="Some text that will update the notification";

        Notification notification=getMyActivityNotification(text);

        NotificationManager mNotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(NOTIF_ID,notification);
}

আপনি আমার দিন বাঁচিয়েছেন। আপনাকে ধন্যবাদ
রুবিন ভিগুয়েরা

1
অনুপস্থিত কীওয়ার্ডটি এখানে থাকতে হবেnew NotificationChannel
7hny

5

আপনার পরিষেবায় এটি করার কোড এখানে । একটি নতুন বিজ্ঞপ্তি তৈরি করুন, তবে সূচনাপৃষ্ঠে আপনি যে একই বিজ্ঞপ্তি আইডিটি ব্যবহার করেছেন সেটিকে বিজ্ঞপ্তি পরিচালককে অনুরোধ করুন।

Notification notify = createNotification();
final NotificationManager notificationManager = (NotificationManager) getApplicationContext()
    .getSystemService(getApplicationContext().NOTIFICATION_SERVICE);

notificationManager.notify(ONGOING_NOTIFICATION, notify);

সম্পূর্ণ নমুনা কোডগুলির জন্য, আপনি এখানে চেক করতে পারেন:

https://github.com/plateaukao/AutoScreenOnOff/blob/master/src/com/danielkao/autoscreenonoff/SensorMonitorService.java


আমি নিশ্চিত না যে এটি স্টার্ট সার্ভিসের অগ্রভাগের স্থিতি বজায় রাখবে।
মার্টিন মার্কনকিনি

@ ড্যানিয়েল কাও আপনার সমাধান কোনও অগ্রভাগ পরিষেবা শুরু করে না
ইগোরগানাপলস্কি

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

@ এটি কাজ করে না। প্রজ্ঞাপন স্থিতি পরিণত not foregroundজন্য foreground createdবার্তা।
ব্যায়চ্লাভ

1
এর ফলে একটি সদৃশ বিজ্ঞপ্তি হবে, কারণ স্টার্টফোরগ্রাউন্ড () ইতিমধ্যে ডাকা হয়েছিল।
ইগোরগানাপলস্কি

2

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

সঠিক কেসটি সনাক্ত করতে আপনি নিম্নলিখিত প্যাটার্নটি ব্যবহার করতে পারেন:

private void notify(@NonNull String action) {
    boolean isForegroundNotificationVisible = false;
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    StatusBarNotification[] notifications = notificationManager.getActiveNotifications();
    for (StatusBarNotification notification : notifications) {
        if (notification.getId() == FOREGROUND_NOTE_ID) {
            isForegroundNotificationVisible = true;
            break;
        }
    }
    Log.v(getClass().getSimpleName(), "Is foreground visible: " + isForegroundNotificationVisible);
    if (isForegroundNotificationVisible){
        notificationManager.notify(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
    } else {
        startForeground(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
    }
}

অতিরিক্ত হিসাবে আপনি অন্যান্য উত্তর হিসাবে বিজ্ঞপ্তি এবং চ্যানেল নির্মাণ প্রয়োজন:

private Notification buildForegroundNotification(@NonNull String action) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        createNotificationChannel();
    }
    //Do any customization you want here
    String title;
    if (ACTION_STOP.equals(action)) {
        title = getString(R.string.fg_notitifcation_title_stopping);
    } else {
        title = getString(R.string.fg_notitifcation_title_starting);
    }
    //then build the notification
    return new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setOngoing(true)
            .build();
}

@RequiresApi(Build.VERSION_CODES.O)
private void createNotificationChannel(){
    NotificationChannel chan = new NotificationChannel(CHANNEL_ID, getString(R.string.fg_notification_channel), NotificationManager.IMPORTANCE_DEFAULT);
    chan.setLightColor(Color.RED);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    assert manager != null;
    manager.createNotificationChannel(chan);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.