显示后台启动服务的通知

时间:2014-03-15 02:01:34

标签: android asmack

所以我正在使用asmack库来监听传入的xmpp数据包。我已经实现了服务。它启动,绑定,运行一个方法,然后它就是未绑定的。该服务创建一个PacketListener来获取传入的消息,并在新消息进入时显示通知。这一切都在应用程序是活动活动时有效,但在完全关闭时无效(在窗口列表中刷掉)并且它只是服务运行,PacketListener不会触发。它会在应用程序重新打开后立即触发,然后解除所有通知。我希望这些通知在他们进入时被触发,而不是暂停服务,如果你愿意的话。该服务的代码在这里:

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);
            }
        }

    }
}

以及启动/绑定服务的代码在这里:

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;
        }
    }

正如我所说,我想在前台活动关闭时从后台运行的服务接收通知。有没有办法做到这一点?也许在它自己的过程中有它?还有别的吗?

编辑:如果您想知道

,正在进行的通知会在点击时发挥作用

1 个答案:

答案 0 :(得分:0)

使用startforeground方法 http://developer.android.com/reference/android/app/Service.html#startForeground%28int,%20android.app.Notification%29

在onCreate of service

public void onCreate() {

 startForeground (int id, Notification notification)
}