后台应用程序在接收推送通知时无法显示UI

时间:2012-07-31 06:23:16

标签: blackberry push-notification listener background-application

这是我的完整推送通知监听器。

public class MyApp extends UiApplication {
    public static void main(String[] args) {
        PushAgent pa = new PushAgent();
        pa.enterEventDispatcher();
    }
}

这个课程是否正确延长了?

public class PushAgent extends Application {
private static final String PUSH_PORT = "32023";
private static final String BPAS_URL = "http://pushapi.eval.blackberry.com";
private static final String APP_ID = "2727-c55087eR3001rr475448i013212a56shss2";
private static final String CONNECTION_SUFFIX = ";deviceside=false;ConnectionType=mds-public";

public static final long ID = 0x749cb23a75c60e2dL;

private MessageReadingThread messageReadingThread;

public PushAgent() {
    if (!CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) {
        return;
    }
    if (DeviceInfo.isSimulator()) {
        return;
    }
    messageReadingThread = new MessageReadingThread();
    messageReadingThread.start();
    registerBpas();
}

private static class MessageReadingThread extends Thread {

    private boolean running;
    private ServerSocketConnection socket;
    private HttpServerConnection conn;
    private InputStream inputStream;
    private PushInputStream pushInputStream;

    public MessageReadingThread() {
        this.running = true;
    }

    public void run() {
        String url = "http://:" + PUSH_PORT + CONNECTION_SUFFIX;

        try {
            socket = (ServerSocketConnection) Connector.open(url);
        } catch (IOException ex) {
        }

        while (running) {
            try {
                Object o = socket.acceptAndOpen();
                conn = (HttpServerConnection) o;
                inputStream = conn.openInputStream();
                pushInputStream = new MDSPushInputStream(conn, inputStream);
                PushMessageReader.process(pushInputStream, conn);
            } catch (Exception e) {
                if (running) {
                    running = false;
                }
            } finally {
                close(conn, pushInputStream, null);
            }
        }
    }
}

public static void close(Connection conn, InputStream is, OutputStream os) {
    if (os != null) {
        try {
            os.close();
        } catch (IOException e) {
        }
    }
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
        }
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (IOException e) {
        }
    }
}

private String formRegisterRequest(String bpasUrl, String appId,
        String token) {
    StringBuffer sb = new StringBuffer(bpasUrl);
    sb.append("/mss/PD_subReg?");
    sb.append("serviceid=").append(appId);
    sb.append("&osversion=").append(DeviceInfo.getSoftwareVersion());
    sb.append("&model=").append(DeviceInfo.getDeviceName());
    if (token != null && token.length() > 0) {
        sb.append("&").append(token);
    }
    return sb.toString();
}

private void registerBpas() {
    final String registerUrl = formRegisterRequest(BPAS_URL, APP_ID, null)
            + CONNECTION_SUFFIX;
    Object theSource = new Object() {
        public String toString() {
            return "Oriental Daily";
        }
    };

    NotificationsManager.registerSource(ID, theSource,
            NotificationsConstants.IMPORTANT);

    new Thread() {
        public void run() {
            try {
                HttpConnection httpConnection = (HttpConnection) Connector
                        .open(registerUrl);
                InputStream is = httpConnection.openInputStream();
                String response = new String(IOUtilities.streamToBytes(is));
                close(httpConnection, is, null);

                String nextUrl = formRegisterRequest(BPAS_URL, APP_ID,
                        response) + CONNECTION_SUFFIX;
                HttpConnection nextHttpConnection = (HttpConnection) Connector
                        .open(nextUrl);
                InputStream nextInputStream = nextHttpConnection
                        .openInputStream();
                response = new String(
                        IOUtilities.streamToBytes(nextInputStream));
                close(nextHttpConnection, is, null);
            } catch (IOException e) {
            }
        }
    }.start();
}
}
}

这是process;

public class PushMessageReader {
private static final String MESSAGE_ID_HEADER = "Push-Message-ID";
private static final String MESSAGE_TYPE_TEXT = "text";
private static final String MESSAGE_TYPE_IMAGE = "image";

private static final int MESSAGE_ID_HISTORY_LENGTH = 10;
private static String[] messageIdHistory = new String[MESSAGE_ID_HISTORY_LENGTH];
private static byte historyIndex;

private static byte[] buffer = new byte[15 * 1024];
private static byte[] imageBuffer = new byte[10 * 1024];

public static final long ID = 0x749cb23a75c60e2dL;
public static Bitmap popup = Bitmap.getBitmapResource("icon_24.png");

private PushMessageReader() {
}

public static void process(PushInputStream pis, Connection conn) {
    try {
        HttpServerConnection httpConn;

        if (conn instanceof HttpServerConnection) {
            httpConn = (HttpServerConnection) conn;
        } else {
            throw new IllegalArgumentException(
                    "Can not process non-http pushes, expected HttpServerConnection but have "
                            + conn.getClass().getName());
        }

        String msgId = httpConn.getHeaderField(MESSAGE_ID_HEADER);
        String msgType = httpConn.getType();
        String encoding = httpConn.getEncoding();

        if (!alreadyReceived(msgId)) {
            byte[] binaryData;

            if (msgId == null) {
                msgId = String.valueOf(System.currentTimeMillis());
            }

            if (msgType.indexOf(MESSAGE_TYPE_TEXT) >= 0) {
                int size = pis.read(buffer);
                binaryData = new byte[size];
                System.arraycopy(buffer, 0, binaryData, 0, size);

                NotificationsManager.triggerImmediateEvent(ID, 0, null,
                        null);
                processTextMessage(buffer);
            } else if (msgType.indexOf(MESSAGE_TYPE_IMAGE) >= 0) {
                int size = pis.read(buffer);

                if (encoding != null && encoding.equalsIgnoreCase("base64")) {
                    Base64InputStream bis = new Base64InputStream(
                            new ByteArrayInputStream(buffer, 0, size));
                    size = bis.read(imageBuffer);
                }

                binaryData = new byte[size];
                System.arraycopy(buffer, 0, binaryData, 0, size);
            }
        }
        pis.accept();
    } catch (Exception e) {

    } finally {
        PushAgent.close(conn, pis, null);
    }
}

private static boolean alreadyReceived(String id) {
    if (id == null) {
        return false;
    }

    if (Arrays.contains(messageIdHistory, id)) {
        return true;
    }

    messageIdHistory[historyIndex++] = id;

    if (historyIndex >= MESSAGE_ID_HISTORY_LENGTH) {
        historyIndex = 0;
    }
    return false;
}

private static void processTextMessage(final byte[] data) {
    synchronized (Application.getEventLock()) {

        UiEngine ui = Ui.getUiEngine();

        GlobalDialog screen = new GlobalDialog("New Notification",
                "Article ID : " + new String(data), new String(data));

        ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE);
    }
}

static class GlobalDialog extends PopupScreen implements
        FieldChangeListener {
    ButtonField mOKButton = new ButtonField("OK", ButtonField.CONSUME_CLICK
            | FIELD_HCENTER);
    String data = "";

    public GlobalDialog(String title, String text, String data) {
        super(new VerticalFieldManager());
        this.data = data;

        add(new LabelField(title));
        add(new SeparatorField(SeparatorField.LINE_HORIZONTAL));
        add(new LabelField(text, DrawStyle.HCENTER));

        mOKButton.setChangeListener(this);
        add(mOKButton);
    }

    public void fieldChanged(Field field, int context) {
        if (mOKButton == field) {
            try {
                ApplicationManager.getApplicationManager().launch(
                        "OrientalDailyBB");
                ApplicationManager.getApplicationManager().postGlobalEvent(
                        ID, 0, 0, data, null);

                ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry
                        .getInstance();
                reg.unregister();

                close();
            } catch (ApplicationManagerException e) {
            }
        }
    }
}
}

在此项目中,我检查了启动时自动运行,以便此后台应用监听器将一直运行,并在BB App中将起始层设置为7描述。

但是,它无法显示弹出窗口Dialog,但我可以看到设备已收到推送通知。

弹出对话框后,用户点击确定将启动OrientalDailyBB项目并显示特定的MainScreen

FYI :侦听器优先级高于OrientalDailyBB项目,因为它是后台应用程序。因此,当我安装OrientalDailyBB时,它也将安装此侦听器。之所以发生这种情况,是因为此侦听器不在OrientalDailyBB项目文件夹中,而是在不同的文件夹中。我确实将它们分开以避免在用户退出OrientalDailyBB时终止后台应用程序。

1 个答案:

答案 0 :(得分:1)

我认为这是一个线程问题。 pushGlobalScreen是您可以尝试与invokeLater一起使用的消息。

UiApplication.getUiApplication().invokeLater(new Runnable() {
  public void run() {
    ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE);
  }
});

您也可以尝试将应用程序推向前台。