Revision: 855
http://swingme.svn.sourceforge.net/swingme/?rev=855&view=rev
Author: janeroski
Date: 2010-04-28 15:27:05 +0000 (Wed, 28 Apr 2010)
Log Message:
-----------
SMS: Add new implementation
Modified Paths:
--------------
AndroidME/AndroidManifest.xml
AndroidME/src_Android/net/yura/android/io/socket/SocketConnection.java
AndroidME/src_MIDP/javax/microedition/io/Connector.java
AndroidME/src_Test/net/yura/android/MainTest.java
Added Paths:
-----------
AndroidME/src_Android/net/yura/android/messaging/
AndroidME/src_Android/net/yura/android/messaging/BinaryMessageImpl.java
AndroidME/src_Android/net/yura/android/messaging/MessageConnectionImpl.java
AndroidME/src_Android/net/yura/android/messaging/MessageImpl.java
AndroidME/src_Android/net/yura/android/messaging/TextMessageImpl.java
Modified: AndroidME/AndroidManifest.xml
===================================================================
--- AndroidME/AndroidManifest.xml 2010-04-28 14:21:22 UTC (rev 854)
+++ AndroidME/AndroidManifest.xml 2010-04-28 15:27:05 UTC (rev 855)
@@ -26,5 +26,6 @@
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.SEND_SMS" />
</manifest>
\ No newline at end of file
Modified: AndroidME/src_Android/net/yura/android/io/socket/SocketConnection.java
===================================================================
--- AndroidME/src_Android/net/yura/android/io/socket/SocketConnection.java 2010-04-28 14:21:22 UTC (rev 854)
+++ AndroidME/src_Android/net/yura/android/io/socket/SocketConnection.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -31,8 +31,6 @@
import java.io.OutputStream;
import java.net.Socket;
-import javax.microedition.io.StreamConnection;
-
public class SocketConnection implements javax.microedition.io.SocketConnection {
protected Socket socket;
Added: AndroidME/src_Android/net/yura/android/messaging/BinaryMessageImpl.java
===================================================================
--- AndroidME/src_Android/net/yura/android/messaging/BinaryMessageImpl.java (rev 0)
+++ AndroidME/src_Android/net/yura/android/messaging/BinaryMessageImpl.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -0,0 +1,29 @@
+package net.yura.android.messaging;
+
+import java.util.Date;
+
+import javax.wireless.messaging.BinaryMessage;
+
+/**
+ * Provides BinaryMessage functionalities.
+ */
+public class BinaryMessageImpl extends MessageImpl implements BinaryMessage {
+
+ private byte[] payloadData;
+
+ public BinaryMessageImpl(String address) {
+ this(address, null);
+ }
+
+ public BinaryMessageImpl(String address, Date timestamp) {
+ super(address, timestamp);
+ }
+
+ public byte[] getPayloadData() {
+ return this.payloadData;
+ }
+
+ public void setPayloadData(byte[] payloadData) {
+ this.payloadData = payloadData;
+ }
+}
Added: AndroidME/src_Android/net/yura/android/messaging/MessageConnectionImpl.java
===================================================================
--- AndroidME/src_Android/net/yura/android/messaging/MessageConnectionImpl.java (rev 0)
+++ AndroidME/src_Android/net/yura/android/messaging/MessageConnectionImpl.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -0,0 +1,172 @@
+package net.yura.android.messaging;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.ArrayList;
+import java.util.Date;
+
+import javax.wireless.messaging.BinaryMessage;
+import javax.wireless.messaging.Message;
+import javax.wireless.messaging.MessageConnection;
+import javax.wireless.messaging.MessageListener;
+import javax.wireless.messaging.TextMessage;
+
+import net.yura.android.AndroidMeMIDlet;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+
+/**
+ * Provides MessageConnection functionalities. Note: <uses-permission
+ * id="android.permission.RECEIVE_SMS" /> is required for receiving SMS Note 2:
+ * when using the PushRegistry, we could register the service the Manifest.xml
+ * as well.
+ */
+public class MessageConnectionImpl extends BroadcastReceiver implements MessageConnection {
+ private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
+ private final String url;
+
+ private MessageListener messageListener;
+ private short port;
+ private final Object receiveLock;
+ private final ArrayList<Message> receivedMessages;
+ private boolean isListeningForMessages;
+
+ public MessageConnectionImpl(String url) {
+ url = url.substring("sms://".length());
+ this.url = url;
+
+ this.receiveLock = new Object();
+ this.receivedMessages = new ArrayList<Message>();
+ int colonIndex = url.indexOf(':');
+ if (colonIndex != -1 && colonIndex < url.length() - 1) {
+ String portStr = url.substring(colonIndex + 1);
+ for (int i = 0; i < portStr.length(); i++) {
+ if (!Character.isDigit(portStr.charAt(i))) {
+ portStr = portStr.substring(0, i);
+ break;
+ }
+ }
+ this.port = (short) Integer.parseInt(portStr);
+ }
+ }
+
+ public Message newMessage(String type) {
+ return newMessage(type, this.url);
+ }
+
+ public Message newMessage(String type, String address) {
+ if (MessageConnection.TEXT_MESSAGE.equals(type)) {
+ return new TextMessageImpl(address);
+ }
+
+ if (MessageConnection.BINARY_MESSAGE.equals(type)) {
+ return new BinaryMessageImpl(address);
+ }
+
+ throw new IllegalArgumentException();
+ }
+
+ public int numberOfSegments(Message msg) {
+ // maximum length is 140 byts or 160 characters (with 7bit characters):
+ if (msg instanceof TextMessage) {
+
+ String text = ((TextMessage) msg).getPayloadText();
+ ArrayList<String> segments = SmsManager.getDefault().divideMessage(text);
+ return segments.size();
+ }
+
+ if (msg instanceof BinaryMessage) {
+ byte[] data = ((BinaryMessage) msg).getPayloadData();
+ return (data == null) ? 1 : (data.length / 140) + 1;
+ }
+
+ return 0;
+ }
+
+ public Message receive() throws IOException, InterruptedIOException {
+ if (!this.isListeningForMessages) {
+ setupMessageReceiver();
+ }
+ synchronized (this.receiveLock) {
+ if (this.receivedMessages.size() > 0) {
+ Message msg = this.receivedMessages.remove(0);
+ return msg;
+ }
+ try {
+ this.receiveLock.wait();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ if (this.receivedMessages.size() > 0) {
+ Message msg = this.receivedMessages.remove(0);
+ return msg;
+ } else {
+ throw new InterruptedIOException();
+ }
+ }
+
+ private void setupMessageReceiver() {
+ this.isListeningForMessages = true;
+ IntentFilter filter = new IntentFilter(ACTION);
+ AndroidMeMIDlet.DEFAULT_ACTIVITY.registerReceiver(this, filter);
+ }
+
+ public void send(Message msg) throws IOException, InterruptedIOException {
+ String address = msg.getAddress();
+ if (msg instanceof TextMessage) {
+ // TODO when a port is specified use data message?
+ String text = ((TextMessage) msg).getPayloadText();
+ SmsManager.getDefault().sendTextMessage(address, null, text, null, null);
+ } else if (msg instanceof BinaryMessage) {
+ byte[] data = ((BinaryMessage) msg).getPayloadData();
+ SmsManager.getDefault().sendDataMessage(address, null, this.port, data, null, null);
+ } else {
+ throw new IOException("invalid type: " + msg);
+ }
+ }
+
+ public void setMessageListener(MessageListener l) throws IOException {
+ if (!this.isListeningForMessages) {
+ setupMessageReceiver();
+ }
+ this.messageListener = l;
+ }
+
+ public void close() throws IOException {
+ // TODO check if SmsManager needs to be released
+ synchronized (this.receiveLock) {
+ this.receiveLock.notify();
+ }
+ if (this.isListeningForMessages) {
+ AndroidMeMIDlet.DEFAULT_ACTIVITY.unregisterReceiver(this);
+ this.isListeningForMessages = false;
+ }
+ }
+
+ @Override
+ public void onReceive(Context ctx, Intent intent) {
+ // #debug
+ System.out.println("SMS:onReceive.");
+ Bundle bundle = intent.getExtras();
+ Object messages[] = (Object[]) bundle.get("pdus");
+ for (int n = 0; n < messages.length; n++) {
+ SmsMessage msg = SmsMessage.createFromPdu((byte[]) messages[n]);
+ // TODO: how to create binary messages?
+ TextMessage textMsg = new TextMessageImpl(msg.getOriginatingAddress(), new Date(msg.getTimestampMillis()));
+ this.receivedMessages.add(textMsg);
+ synchronized (this.receiveLock) {
+ this.receiveLock.notify();
+ }
+ if (this.messageListener != null) {
+ this.messageListener.notifyIncomingMessage(this);
+ }
+ }
+ }
+}
Added: AndroidME/src_Android/net/yura/android/messaging/MessageImpl.java
===================================================================
--- AndroidME/src_Android/net/yura/android/messaging/MessageImpl.java (rev 0)
+++ AndroidME/src_Android/net/yura/android/messaging/MessageImpl.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -0,0 +1,36 @@
+package net.yura.android.messaging;
+
+import java.util.Date;
+
+import javax.wireless.messaging.Message;
+
+/**
+ * Provides basic Message implementation.
+ */
+public class MessageImpl implements Message {
+
+ protected String address;
+ protected Date timestamp;
+
+ public MessageImpl(String address, Date timestamp) {
+ this.timestamp = timestamp;
+ if (address != null) {
+ setAddress(address);
+ }
+ }
+
+ public Date getTimestamp() {
+ return this.timestamp;
+ }
+
+ public String getAddress() {
+ return this.address;
+ }
+
+ public void setAddress(String addr) {
+ if (addr.startsWith("sms://")) {
+ addr = addr.substring(6);
+ }
+ this.address = addr;
+ }
+}
Added: AndroidME/src_Android/net/yura/android/messaging/TextMessageImpl.java
===================================================================
--- AndroidME/src_Android/net/yura/android/messaging/TextMessageImpl.java (rev 0)
+++ AndroidME/src_Android/net/yura/android/messaging/TextMessageImpl.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -0,0 +1,29 @@
+package net.yura.android.messaging;
+
+import java.util.Date;
+
+import javax.wireless.messaging.TextMessage;
+
+/**
+ * Provides TextMessage functionalities.
+ */
+public class TextMessageImpl extends MessageImpl implements TextMessage {
+
+ private String payloadText;
+
+ public TextMessageImpl(String address) {
+ this(address, null);
+ }
+
+ public TextMessageImpl(String address, Date timestamp) {
+ super(address, timestamp);
+ }
+
+ public String getPayloadText() {
+ return this.payloadText;
+ }
+
+ public void setPayloadText(String payloadText) {
+ this.payloadText = payloadText;
+ }
+}
Modified: AndroidME/src_MIDP/javax/microedition/io/Connector.java
===================================================================
--- AndroidME/src_MIDP/javax/microedition/io/Connector.java 2010-04-28 14:21:22 UTC (rev 854)
+++ AndroidME/src_MIDP/javax/microedition/io/Connector.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -11,66 +11,71 @@
import net.yura.android.io.file.AndroidFileConnection;
import net.yura.android.io.socket.ServerSocketConnection;
import net.yura.android.io.socket.SocketConnection;
+import net.yura.android.messaging.MessageConnectionImpl;
public class Connector {
- public static final int READ = 0x01;
- public static final int WRITE = 0x02;
- public static final int READ_WRITE = READ | WRITE;
+ public static final int READ = 0x01;
+ public static final int WRITE = 0x02;
+ public static final int READ_WRITE = READ | WRITE;
- private static final String PROTOCOL_FILE = "file:";
- private static final String PROTOCOL_SOCKET = "socket:";
- private static final String PROTOCOL_HTTP = "http:";
+ private static final String PROTOCOL_FILE = "file:";
+ private static final String PROTOCOL_SOCKET = "socket:";
+ private static final String PROTOCOL_HTTP = "http:";
+ private static final String PROTOCOL_SMS = "sms:";
- public static final Connection open(String name) throws IOException {
- return open(name, READ_WRITE);
- }
+ public static final Connection open(String name) throws IOException {
+ return open(name, READ_WRITE);
+ }
- public static final Connection open(String name, int mode)
- throws IOException {
- Connection connection;
- if (name.startsWith(PROTOCOL_FILE)) {
- connection = new AndroidFileConnection(name);
- // TODO : http should have a separate connection type
- } else if (name.startsWith(PROTOCOL_SOCKET)) {
- connection = getSocketConnection(name);
- } else {
- connection = new AndroidURLConnection(name);
- }
- return connection;
- }
+ public static final Connection open(String name, int mode)
+ throws IOException {
+ Connection connection;
+ if (name.startsWith(PROTOCOL_FILE)) {
+ connection = new AndroidFileConnection(name);
+ // TODO : http should have a separate connection type
+ } else if (name.startsWith(PROTOCOL_SOCKET)) {
+ connection = getSocketConnection(name);
+ }
+ else if (name.startsWith(PROTOCOL_SMS)) {
+ connection = new MessageConnectionImpl(name);
+ } else {
+ connection = new AndroidURLConnection(name);
+ }
+ return connection;
+ }
- public static final DataInputStream openDataInputStream(String name)
- throws IOException {
- return new DataInputStream(openInputStream(name));
- }
+ public static final DataInputStream openDataInputStream(String name)
+ throws IOException {
+ return new DataInputStream(openInputStream(name));
+ }
- public static final DataOutputStream openDataOutputStream(String name)
- throws IOException {
- return new DataOutputStream(openOutputStream(name));
- }
+ public static final DataOutputStream openDataOutputStream(String name)
+ throws IOException {
+ return new DataOutputStream(openOutputStream(name));
+ }
- public static final InputStream openInputStream(String name)
- throws IOException {
- Connection connection = open(name, READ);
- return ((InputConnection) connection).openInputStream();
- }
+ public static final InputStream openInputStream(String name)
+ throws IOException {
+ Connection connection = open(name, READ);
+ return ((InputConnection) connection).openInputStream();
+ }
- public static final OutputStream openOutputStream(String name)
- throws IOException {
- Connection connection = open(name, WRITE);
- return ((OutputConnection) connection).openOutputStream();
- }
+ public static final OutputStream openOutputStream(String name)
+ throws IOException {
+ Connection connection = open(name, WRITE);
+ return ((OutputConnection) connection).openOutputStream();
+ }
- private static Connection getSocketConnection(String name) throws IOException {
- int portSepIndex = name.lastIndexOf(':');
- int port = Integer.parseInt(name.substring(portSepIndex + 1));
- String host = name.substring("socket://".length(), portSepIndex);
+ private static Connection getSocketConnection(String name) throws IOException {
+ int portSepIndex = name.lastIndexOf(':');
+ int port = Integer.parseInt(name.substring(portSepIndex + 1));
+ String host = name.substring("socket://".length(), portSepIndex);
- if (host.length() > 0) {
- return new SocketConnection(host, port);
- } else {
- return new ServerSocketConnection(port);
- }
- }
+ if (host.length() > 0) {
+ return new SocketConnection(host, port);
+ } else {
+ return new ServerSocketConnection(port);
+ }
+ }
}
Modified: AndroidME/src_Test/net/yura/android/MainTest.java
===================================================================
--- AndroidME/src_Test/net/yura/android/MainTest.java 2010-04-28 14:21:22 UTC (rev 854)
+++ AndroidME/src_Test/net/yura/android/MainTest.java 2010-04-28 15:27:05 UTC (rev 855)
@@ -1,12 +1,29 @@
package net.yura.android;
+
+
+import javax.microedition.io.Connector;
+import javax.microedition.lcdui.Graphics;
+import javax.wireless.messaging.MessageConnection;
+import javax.wireless.messaging.TextMessage;
+
import net.yura.mobile.gui.Midlet;
+import net.yura.mobile.gui.components.Button;
import net.yura.mobile.gui.components.Label;
+import net.yura.mobile.gui.components.Panel;
+import net.yura.mobile.gui.components.TextField;
+import net.yura.mobile.logging.Logger;
+import net.yura.mobile.gui.layout.BorderLayout;
+import net.yura.mobile.gui.layout.BoxLayout;
+import net.yura.mobile.gui.layout.FlowLayout;
import net.yura.mobile.test.MainPane;
import net.yura.mobile.test.MainPane.Section;
public class MainTest extends Section {
+ private TextField smsTextField;
+ private TextField smsNumberField;
+
public MainTest(MainPane mainPane) {
super(mainPane);
}
@@ -17,6 +34,7 @@
addSection("PIM", new PimTest());
addSection("Multimedia", new MultimediaTest());
+ addTest("Send SMS", "sms");
}
// @Override
@@ -27,8 +45,54 @@
else if ("exit".equals(actionCommand)) {
Midlet.exit();
}
- else if ("pim".equals(actionCommand)) {
- //TODO:
+ else if ("sms".equals(actionCommand)) {
+
+
+ smsTextField = new TextField();
+ smsNumberField = new TextField(TextField.PHONENUMBER);
+
+ Button smsSendBtn = new Button("Send SMS");
+ smsSendBtn.setActionCommand("sendSms");
+ smsSendBtn.addActionListener(this);
+
+ Panel left = new Panel(new FlowLayout(Graphics.VCENTER, 0));
+ left.add(new Label("Text:"));
+ left.add(new Label("Phone:"));
+
+ Panel right = new Panel(new BoxLayout(Graphics.VCENTER));
+ right.add(smsTextField);
+ right.add(smsNumberField);
+
+ Panel smsPanel = new Panel(new BorderLayout());
+ smsPanel.add(left, Graphics.LEFT);
+ smsPanel.add(right);
+ smsPanel.add(smsSendBtn, Graphics.BOTTOM);
+
+ addToScrollPane(smsPanel, null);
}
}
+
+ public void actionPerformed(String actionCommand) {
+ if ("sendSms".equals(actionCommand)) {
+ System.out.println(">>>>> sendSms");
+
+ String phoneNumber = smsNumberField.getText();
+ String message = smsTextField.getText();
+
+ try {
+ MessageConnection conn = (MessageConnection) Connector.open("sms://" + phoneNumber);
+ TextMessage msg = (TextMessage) conn.newMessage(MessageConnection.TEXT_MESSAGE);
+ msg.setPayloadText(message);
+ //#debug
+ Logger.debug("Sending SMS message with body " + message + " to phone number " + phoneNumber);
+ conn.send(msg);
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ else {
+ super.actionPerformed(actionCommand);
+ }
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|