原生黑莓 API 是否允许修改任何消息传递接口?
例如,我希望能够构建一个应用程序,在收到的消息底部添加一个按钮,上面写着“翻译这个”。我听说这种事情可以使用 J2ME 和本机 BlackBerry API。是否可以对所有类型的消息进行此操作,例如 SMS、电子邮件和 BB 消息?
翻译方面无关紧要,它只是为我所追求的那种功能提供了上下文。
原生黑莓 API 是否允许修改任何消息传递接口?
例如,我希望能够构建一个应用程序,在收到的消息底部添加一个按钮,上面写着“翻译这个”。我听说这种事情可以使用 J2ME 和本机 BlackBerry API。是否可以对所有类型的消息进行此操作,例如 SMS、电子邮件和 BB 消息?
翻译方面无关紧要,它只是为我所追求的那种功能提供了上下文。
试试Google Translation API,通过 http 请求管理正确的翻译应该没问题:
对于 Flash 开发人员以及需要从其他非 JavaScript 环境访问 AJAX 语言 API 的开发人员,API 公开了一个简单的 RESTful 接口。在所有情况下,支持的方法都是 GET,响应格式是带有嵌入状态代码的JSON编码结果。对于
google.language.translate
,可以使用 POST 方法。使用此接口的应用程序必须遵守所有现有的使用条款。一个需要特别注意的领域涉及在您的请求中正确识别自己。应用程序必须始终包含有效且准确的http referer 标头在他们的要求中。此外,我们要求但不要求每个请求都包含一个有效的 API 密钥。通过提供密钥,您的应用程序为我们提供了辅助识别机制,如果我们需要联系您以纠正任何问题,该机制很有用。
谈到这种服务的集成,我看到了两种选择:
更新
我终于设法把我的手放在这个好主意上:)
这是交易:将有两个应用程序:主应用程序和服务。主应用程序可以独立启动并用于翻译。服务将负责处理消息并触发主应用程序进行翻译。
主要应用代码:
public class TranslatorApp extends UiApplication {
public TranslatorApp(String text) {
pushScreen(new TranslationScreen(text));
}
public TranslatorApp() {
pushScreen(new TranslationScreen());
}
public static void main(String[] args) {
TranslatorApp app = null;
if (null == args || args.length == 0) {
app = new TranslatorApp();
} else {
app = new TranslatorApp(args[0]);
}
app.enterEventDispatcher();
}
}
class TranslationScreen extends MainScreen implements TranslateCallback {
final static int TMODE_MANUAL = 0;
final static int TMODE_INTEGRATED = 1;
Translator mTranslator = null;
BasicEditField mOriginalTextEdit = new BasicEditField("", "");
LabelField mOriginalTextLabel = new LabelField("");
LabelField mTranslatedTextLabel = new LabelField("");
String mOriginalText = "";
int mTranslationMode = TMODE_MANUAL;
public TranslationScreen() {
mTranslationMode = TMODE_MANUAL;
add(mOriginalTextEdit);
add(mTranslatedTextLabel);
mTranslator = new Translator(this);
}
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
if (mTranslationMode == TMODE_MANUAL) {
menu.add(new MenuItem("translate", 0, 0) {
public void run() {
mOriginalText = mOriginalTextEdit.getText();
translate();
}
});
}
}
public TranslationScreen(String text) {
mTranslationMode = TMODE_INTEGRATED;
mOriginalText = text;
mOriginalTextLabel.setText(mOriginalText);
add(mOriginalTextLabel);
add(mTranslatedTextLabel);
mTranslator = new Translator(this);
translate();
}
public void translationComplete(final String translatedText) {
UiApplication.getUiApplication().invokeLater(
new Runnable(){
public void run() {
mTranslatedTextLabel.setText(translatedText);
}});
}
public void exception(Exception ex) {
Dialog.alert(ex.getMessage());
}
private void translate() {
if (null != mOriginalText
&& 0 != mOriginalText.trim().length()) {
mTranslator.translate(mOriginalText);
} else {
Dialog.alert("text is empty");
}
}
}
interface ExceptionHandler {
public void exception(Exception ex);
}
interface TranslateCallback extends ExceptionHandler {
public void translationComplete(String translatedText);
}
class Translator {
TranslateCallback mCallback;
static final String url = "http://ajax.googleapis.com/ajax/"+
"services/language/translate?";
//remember to change referrer :)
static final String referrerUrl = "http://stackoverflow.com";
public Translator(TranslateCallback callback) {
mCallback = callback;
}
public void translate(final String text) {
Runnable translation = new Runnable() {
public void run() {
String result = "";
StringBuffer sb = new StringBuffer();
sb.append(url);
sb.append("v=1.0&");
sb.append("q=");
sb.append(URLencode(text));
sb.append("&");
sb.append("langpair=en|uk");
String requestUrl = sb.toString();
try {
HttpConnection connection = (HttpConnection) Connector
.open(requestUrl);
connection.setRequestMethod("POST");
connection.setRequestProperty("Referer", referrerUrl);
result = new String(IOUtilities.streamToBytes(connection
.openInputStream()), "UTF-8");
} catch (IOException e) {
mCallback.exception(e);
}
translationEnd(result);
}
};
Thread t = new Thread(translation);
t.start();
}
public static String URLencode(String s)
{
if (s!=null) {
StringBuffer tmp = new StringBuffer();
int i=0;
try {
while (true) {
int b = (int)s.charAt(i++);
if ((b>=0x30 && b<=0x39) || (b>=0x41 && b<=0x5A)
|| (b>=0x61 && b<=0x7A)) {
tmp.append((char)b);
}
else {
tmp.append("%");
if (b <= 0xf) tmp.append("0");
tmp.append(Integer.toHexString(b));
}
}
}
catch (Exception e) {}
return tmp.toString();
}
return null;
}
private void translationEnd(String result) {
String key = "translatedText";
int index = result.indexOf(key)+key.length()+"\"".length();
int beginIndex = result.indexOf("\"", index + 1)+1;
int endIndex = result.indexOf("\"", beginIndex);
String traslatedText = result.substring(beginIndex, endIndex);
mCallback.translationComplete(traslatedText);
}
}
这里是服务代码:
public class TranslatorSrvc extends Application implements MessageProcessor {
SMSListener mSMSListener = null;
EmailListener mEmailListener = null;
PIMListener mPIMListener = null;
public TranslatorSrvc() {
// SMS
mSMSListener = new SMSListener(this);
// Email
mEmailListener = new EmailListener(this);
//PIM
mPIMListener = new PIMListener(this);
}
public static void main(String[] args) {
TranslatorSrvc app = new TranslatorSrvc();
app.enterEventDispatcher();
}
private void showMessage(String message) {
synchronized (Application.getEventLock()) {
Dialog dlg = new Dialog(Dialog.D_OK, message, Dialog.OK, null,
Manager.FIELD_HCENTER);
Ui.getUiEngine().pushGlobalScreen(dlg, 1, UiEngine.GLOBAL_QUEUE);
}
}
public void processMessage(String text) {
try {
ApplicationManager.getApplicationManager().launch(
"SOTranslatorApp?" + text);
} catch (ApplicationManagerException e) {
exception(e);
}
}
public void exception(Exception ex) {
showMessage(ex.getMessage());
}
}
interface ExceptionHandler {
public void exception(Exception ex);
}
interface MessageProcessor extends ExceptionHandler {
public void processMessage(String text);
}
abstract class AMessageListener {
MessageProcessor mProcessor;
public AMessageListener(MessageProcessor processor) {
mProcessor = processor;
}
}
短信监听代码:
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.wireless.messaging.Message;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.MessageListener;
import javax.wireless.messaging.TextMessage;
public class SMSListener extends AMessageListener implements MessageListener {
MessageConnection mSMSConnection = null;
boolean mSMSReceiveDone = false;
Reader mSMSReader = null;
public SMSListener(MessageProcessor processor) {
super(processor);
try {
mSMSConnection = (MessageConnection) Connector.open("sms://:0");
mSMSConnection.setMessageListener(this);
mSMSReader = new Reader();
new Thread(mSMSReader).start();
} catch (IOException e) {
mProcessor.exception(e);
}
}
public void notifyIncomingMessage(MessageConnection conn) {
if (mSMSConnection == conn) {
mSMSReader.handleMessage();
}
}
// Isolate blocking I/O on a separate thread, so callback
// can return immediately.
class Reader implements Runnable {
private int pendingMessages = 0;
// The run method performs the actual message reading.
public void run() {
while (!mSMSReceiveDone) {
synchronized (this) {
if (pendingMessages == 0) {
try {
wait();
} catch (Exception e) {
mProcessor.exception(e);
}
}
pendingMessages--;
}
try {
Message mess = mSMSConnection.receive();
processSMSMessage(mess);
} catch (IOException ioe) {
mProcessor.exception(ioe);
}
}
}
public synchronized void handleMessage() {
pendingMessages++;
notify();
}
}
public void processSMSMessage(Message mess) {
if (mess instanceof TextMessage) {
TextMessage txtMessage = (TextMessage) mess;
String messageText = txtMessage.getPayloadText();
mProcessor.processMessage(messageText);
}
}
}
电子邮件侦听器代码:
import net.rim.blackberry.api.mail.Session;
import net.rim.blackberry.api.mail.event.FolderEvent;
import net.rim.blackberry.api.mail.event.FolderListener;
public class EmailListener extends AMessageListener implements FolderListener {
public EmailListener(MessageProcessor processor) {
super(processor);
Session.getDefaultInstance().getStore().addFolderListener(this);
}
public void messagesAdded(FolderEvent e) {
String text = e.getMessage().getBodyText();
mProcessor.processMessage(text);
}
public void messagesRemoved(FolderEvent e) {
}
}
PIM 侦听器代码(不幸的是,没有经过测试,非常感谢您的反馈!):
import java.io.UnsupportedEncodingException;
import net.rim.blackberry.api.blackberrymessenger.BlackBerryMessenger;
import net.rim.blackberry.api.blackberrymessenger.Message;
import net.rim.blackberry.api.blackberrymessenger.Session;
import net.rim.blackberry.api.blackberrymessenger.SessionListener;
import net.rim.blackberry.api.blackberrymessenger.SessionRequestListener;
import net.rim.device.api.system.ApplicationDescriptor;
public class PIMListener extends AMessageListener implements
SessionRequestListener, SessionListener {
ApplicationDescriptor mAppDescr = ApplicationDescriptor
.currentApplicationDescriptor();
public PIMListener(MessageProcessor processor) {
super(processor);
BlackBerryMessenger msgr = BlackBerryMessenger.getInstance();
msgr.addSessionRequestListener(this, mAppDescr);
}
public void sessionRequestAccepted(Session session) {
session.addListener(this, mAppDescr);
}
public void messageReceived(Session session, Message message) {
try {
mProcessor.processMessage(new String(message.getData(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
mProcessor.exception(e);
}
}
public void messageSent(Session session, Message message) {
}
public void sessionClosed(Session session) {
}
public void messageDelivered(Session session, Message message) {
}
public void messageQueuedForSend(Session session, Message message) {
}
}