通知显示,从后台启动服务 [英] Show notification from background started service

查看:249
本文介绍了通知显示,从后台启动服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我使用asmack库侦听传入XMPP包。我有实现的服务。它的开始,束缚,运行一个方法,然后它的绑定。该服务创建一个PacketListener获得传入的消息,当一个新的消息来。这所有的作品而应用程序是活跃的活动显示通知,但是当它完全关闭不起作用(滑开的窗口列表)和它只是服务运行后,PacketListener不火。它一旦应用程序被重新打开,虽然激发,发射关闭所有通知。我希望得到解雇这些通知,因为他们进来,而不是服务被暂停,如果你愿意。在code的服务是在这里:

So i'm using asmack library to listen for incoming xmpp packets. I've got the service implemented. It's started, bound, a method is run and then it's unbound. The service creates a PacketListener to get incoming messages, and displays a notification when a new message comes in. This all works while the app is the active activity, but doesn't work when it's fully closed (swiped away in the window list) and it's just the service running, the PacketListener doesn't fire. It fires as soon as the app is reopened though, firing off all notifications. I'm looking to get those notifications fired as they come in, instead of the service being suspended, if you will. The code for the service is here:

package com.jayseeofficial.xmpp.service;

import java.io.File;
import java.util.ArrayList;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;
import android.widget.Toast;

import com.jayseeofficial.xmpp.MainActivity;
import com.jayseeofficial.xmpp.Program;
import com.jayseeofficial.xmpp.R;
import com.jayseeofficial.xmpp.objects.Contact;
import com.jayseeofficial.xmpp.preferences.Preferences;

public class XMPPService extends Service {

    private Connection conn = null;
    private boolean loggedIn = false;

    private final XMPPBinder binder = new XMPPBinder();

    private Handler handler;

    @Override
    public IBinder onBind(Intent arg0) {
        handler = new Handler(getMainLooper());
        return binder;
    }

    public class XMPPBinder extends Binder {
        public XMPPService getService() {
            return XMPPService.this;
        }
    }

    public void logIn() {
        new LogInTask().execute();
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }

    private ConnectionConfiguration getConnectionConfiguration() {
        ConnectionConfiguration config = new ConnectionConfiguration(
                Preferences.Account.getServer(), Preferences.Account.getServerPort());
        config.setSASLAuthenticationEnabled(true);
        config.setCompressionEnabled(true);
        config.setSecurityMode(SecurityMode.enabled);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            config.setTruststoreType("AndroidCAStore");
            config.setKeystoreType("AndroidCAStore");
            config.setTruststorePassword(null);
            config.setTruststorePath(null);
        } else {
            config.setTruststoreType("BKS");
            String path = System.getProperty("javax.net.ssl.trustStore");
            if (path == null) {
                path = System.getProperty("java.home") + File.separator + "etc" + File.separator
                        + "security" + File.separator + "cacerts.bks";
            }
            config.setTruststorePath(path);
        }
        return config;
    }

    private void showNotification() {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("XMPP+").setContentText("running")
                .setSmallIcon(R.drawable.speech_bubble);

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

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(i);

        // Assign the intent
        mBuilder.setContentIntent(stackBuilder.getPendingIntent(9127,
                PendingIntent.FLAG_UPDATE_CURRENT));

        NotificationManager mgr = (NotificationManager) this
                .getSystemService(Context.NOTIFICATION_SERVICE);

        Notification n = mBuilder.build();

        n.flags |= Notification.FLAG_ONGOING_EVENT;

        mgr.notify(1,n);
    }

    private void hideNotification() {
        // TODO Implement hideNotification in XMPPService
    }

    private class LogInTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            try {

                showNotification();

                // Set up and log in
                conn = new XMPPConnection(getConnectionConfiguration());
                conn.connect();
                conn.login(Preferences.Account.getUsername(), Preferences.Account.getPassword());

                // Set up to receive messages
                PacketFilter filter = new PacketTypeFilter(Message.class);
                conn.addPacketListener(new XMPPMessagePacketListener(), filter);
                conn.sendPacket(new Presence(Type.available));

                final ArrayList<Contact> allContacts = new ArrayList<Contact>();

                // Populate contact list
                for (RosterEntry re : conn.getRoster().getEntries()) {
                    Log.d("Roster entry: ", re.getUser() + ": " + re.getName());
                    Contact c = new Contact();
                    if (re.getName() == null) {
                        c.setName(re.getUser());
                    } else {
                        c.setName(re.getName());
                    }
                    c.setAddress(re.getUser());

                    allContacts.add(c);
                }

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Program.contacts.addAll(allContacts);
                    }
                });

                loggedIn = true;
            } catch (XMPPException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void ignored) {
            if (loggedIn) {
                Toast.makeText(XMPPService.this, "Logged in successfully", Toast.LENGTH_LONG)
                        .show();
            } else {
                Toast.makeText(XMPPService.this, "Failed to log in", Toast.LENGTH_LONG).show();
            }
        }
    }

    private class XMPPMessagePacketListener implements PacketListener {
        @Override
        public void processPacket(Packet packet) {
            Message m = (Message) packet;
            if (m.getBody() != null) {
                com.jayseeofficial.xmpp.objects.Message message = new com.jayseeofficial.xmpp.objects.Message();
                message.setRecipient(Preferences.Account.getUsername() + "@"
                        + Preferences.Account.getServer());
                String fullSender = m.getFrom();
                String address = fullSender.substring(0, fullSender.indexOf('/'));
                message.setSender(address);
                message.setContents(m.getBody());
                Program.showMessageNotification(message, 9127);
            }
        }

    }
}

和code为起点/绑定服务是在这里:

and the code for the starting/binding the service is here:

public static void init() {
        if (!initialized) {
            // Call other portions of init code first
            SmackAndroid.init(context);
            Preferences.init();

            // Set up our variables
            contacts = GlazedLists.threadSafeList(new BasicEventList<Contact>());

            // Start up the xmpp connection
            Intent ixmpp = new Intent(context, XMPPService.class);
            context.startService(ixmpp);
            context.bindService(ixmpp, xmppConnection, Context.BIND_AUTO_CREATE);

            initialized = true;
        }
    }

因此​​,正如我说的,我希望在前台活动被关闭,从在后台运行的服务接收通知。是否有这样做的方法吗?也许有它在它自己的过程?别的东西吗?

So as I said, i want to receive notifications from the service running in the background when the foreground activity is closed. Is there any way of doing this? Maybe have it in it's own process? Something else?

编辑:正在进行的通知各地坚持和你想知道点击后工作,以防

the ongoing notification sticks around and works when clicked, in case you're wondering

推荐答案

使用startforeground方法
<一href=\"http://developer.android.com/reference/android/app/Service.html#startForeground%28int,%20android.app.Notification%29\" rel=\"nofollow\">http://developer.android.com/reference/android/app/Service.html#startForeground%28int,%20android.app.Notification%29

use startforeground method http://developer.android.com/reference/android/app/Service.html#startForeground%28int,%20android.app.Notification%29

在服务的onCreate

in onCreate of service

public void onCreate() {

 startForeground (int id, Notification notification)
}

这篇关于通知显示,从后台启动服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆