/*******************************************************************************
* Code contributed to the webinos project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2011 Telecom Italia SpA
*
******************************************************************************/
package org.webinos.android.impl;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ContentValues;
import android.content.BroadcastReceiver;
import android.os.Bundle;
import android.database.Cursor;
import android.net.Uri;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.List;
import org.meshpoint.anode.AndroidContext;
import org.meshpoint.anode.bridge.Env;
import org.meshpoint.anode.module.IModule;
import org.meshpoint.anode.module.IModuleContext;
import org.w3c.dom.ObjectArray;
import org.webinos.api.DeviceAPIError;
import org.webinos.api.ErrorCallback;
import org.webinos.api.PendingOperation;
import org.webinos.api.messaging.FindMessagesSuccessCallback;
import org.webinos.api.messaging.Message;
import org.webinos.api.messaging.MessageFilter;
import org.webinos.api.messaging.MessageSendCallback;
import org.webinos.api.messaging.MessagingManager;
import org.webinos.api.messaging.OnIncomingMessage;
import android.content.Context;
public class MessagingImpl extends MessagingManager implements IModule {
private Context androidContext;
private SmsManager smsManager;
private Map<Integer, SmsReceiver> smsReceiverList;
private int counter;
private static final String LABEL = "org.webinos.android.impl.MessagingImpl";
/*****************************
* MessagingManager methods
*****************************/
@Override
public Message createMessage(Integer type) throws DeviceAPIError {
Log.v(LABEL, "createMessage");
if (type == null) {
throw new DeviceAPIError(DeviceAPIError.TYPE_MISMATCH_ERR);
}
if (type == TYPE_SMS) {
MessageImpl msg = new MessageImpl();
msg.setContext(androidContext);
msg.type = type;
msg.folder = FOLDER_DRAFTS;
return msg;
}
else if (type==TYPE_MMS || type==TYPE_EMAIL || type==TYPE_IM) {
//TODO Add support for mms, email and im
return null;
}
else {
throw new DeviceAPIError(DeviceAPIError.INVALID_VALUES_ERR);
}
}
@Override
public PendingOperation sendMessage(MessageSendCallback successCallback,
ErrorCallback errorCallback, Message message) throws DeviceAPIError {
Log.v(LABEL, "sendMessage");
if(successCallback == null || message == null) {
Log.v(LABEL, "sendMessage error (successCallback or message null)");
if(errorCallback!=null) {
errorCallback.onerror(new DeviceAPIError(DeviceAPIError.INVALID_VALUES_ERR));
}
return null;
}
Log.v(LABEL, "sendMessage - 02 ("+message.to.getLength()+")");
if(message.type == TYPE_SMS) {
if(message.to.getLength()>0){
MessagingRunnable smsSender = new SmsSender(successCallback, errorCallback, message);
Thread t = new Thread(smsSender);
t.start();
Log.v(LABEL, "sendMessage - thread started with id "+(int)t.getId());
//MessagingPendingOperation pOp = new MessagingPendingOperation(t, smsSender);
//pOp.setData(t, smsSender);
//return pOp;
return new MessagingPendingOperation(t, smsSender);
}
else {
//TODO what if the message has 0 recipients?
Log.v(LABEL, "sendMessage - message has 0 recipients");
}
}
else {
Log.v(LABEL, "sendMessage - 08");
//TODO Add support for mms, email and im
throw new DeviceAPIError(DeviceAPIError.NOT_SUPPORTED_ERR);
}
//TODO The method should always return a PendingOperation?
return null;
}
@Override
public PendingOperation findMessages(
FindMessagesSuccessCallback successCallback,
ErrorCallback errorCallback, MessageFilter filter)
throws DeviceAPIError {
Log.v(LABEL, "findMessages");
MessagingRunnable smsFinder = new SmsFinder(successCallback, errorCallback, filter);
Thread t = new Thread(smsFinder);
t.start();
//MessagingPendingOperation pOp = new MessagingPendingOperation(t, smsFinder);
//pOp.setData(t, smsFinder);
//return pOp;
return new MessagingPendingOperation(t, smsFinder);
}
@Override
public int onSMS(OnIncomingMessage messageHandler) throws DeviceAPIError {
counter++;
Log.v(LABEL, "onSMS - "+counter);
SmsReceiver smsReceiver = new SmsReceiver(messageHandler);
androidContext.registerReceiver(smsReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
smsReceiverList.put(counter, smsReceiver);
return counter;
}
@Override
public int onMMS(OnIncomingMessage messageHandler) throws DeviceAPIError {
// TODO Auto-generated method stub
return 0;
}
@Override
public int onEmail(OnIncomingMessage messageHandler) throws DeviceAPIError {
// TODO Auto-generated method stub
return 0;
}
@Override
public int onIM(OnIncomingMessage messageHandler) throws DeviceAPIError {
// TODO Auto-generated method stub
return 0;
}
@Override
public void unsubscribe(int subscriptionHandler) throws DeviceAPIError {
Log.v(LABEL, "unsubscribe - "+subscriptionHandler);
SmsReceiver smsReceiver = smsReceiverList.get(subscriptionHandler);
if(smsReceiver != null) {
androidContext.unregisterReceiver(smsReceiver);
smsReceiverList.remove(subscriptionHandler);
}
}
/*****************************
* IModule methods
*****************************/
@Override
public Object startModule(IModuleContext ctx) {
Log.v(LABEL, "startModule");
androidContext = ((AndroidContext)ctx).getAndroidContext();
smsManager = SmsManager.getDefault();
smsReceiverList = new HashMap<Integer, SmsReceiver>();
counter = 0;
return this;
}
@Override
public void stopModule() {
//TODO stop all findMessages and sendMessages
Log.v(LABEL, "stopModule");
if(!smsReceiverList.isEmpty()) {
Set<Integer> listenersId = smsReceiverList.keySet();
for(Integer i: listenersId) {
androidContext.unregisterReceiver(smsReceiverList.get(i));
}
}
}
class SmsSender implements MessagingRunnable {
private MessageSendCallback successCallback;
private ErrorCallback errorCallback;
private Message message;
private int smsCounter;
private SmsResponseReceiver smsResponseReceiver;
private String SMS_SENT;
private ArrayList<String> bodyParts;
private boolean stopped;
private SmsSender(MessageSendCallback succCallback, ErrorCallback errCallback, Message msg) {
successCallback = succCallback;
errorCallback = errCallback;
message = msg;
smsCounter = 0;
stopped = false;
smsResponseReceiver = new SmsResponseReceiver(successCallback, errorCallback, message.to.getLength(), this);
Log.v(LABEL, "SmsSender constructed");
}
public synchronized boolean isStopped() {
return stopped;
}
public synchronized void stop() {
stopped = true;
}
public void run() {
SMS_SENT = "org.webinos.messaging.SMS_SENT_"+(int)Thread.currentThread().getId();
androidContext.registerReceiver(smsResponseReceiver, new IntentFilter(SMS_SENT));
bodyParts = smsManager.divideMessage(message.body);
Log.v(LABEL, "SmsSender run - number of parts is "+bodyParts.size()+" - SMS_SENT is "+SMS_SENT);
sendNextMessage();
/*
ArrayList<String> bodyParts = smsManager.divideMessage(message.body);
Log.v(LABEL, "SmsSender run - number of parts is "+bodyParts.size());
for(int i=0; i<message.to.getLength(); i++) {
Log.v(LABEL, "SmsSender run - 04 ("+i+")");
try {
Intent intent=new Intent(SMS_SENT);
intent.putExtra("rec", message.to.getElement(i));
PendingIntent pnd = PendingIntent.getBroadcast(androidContext, 0, intent, 0);
if(bodyParts.size() == 1) {
smsManager.sendTextMessage(message.to.getElement(i), null, message.body, pnd, null);
}
else {
ArrayList<PendingIntent> pndList = new ArrayList<PendingIntent>();
for(int j=0;j<bodyParts.size()-1;j++){
pndList.add(null);
}
pndList.add(pnd);
smsManager.sendMultipartTextMessage(message.to.getElement(i), null, bodyParts, pndList, null);
}
}
// catch(IllegalArgumentException e) {
catch(Exception e) {
Log.v(LABEL, "SmsSender run - error "+e);
smsResponseReceiver.errorCaught(message.to.getElement(i));
}
}
*/
}
public void sendFinished() {
Log.v(LABEL, "SmsSender - sendFinished");
androidContext.unregisterReceiver(smsResponseReceiver);
}
public void sendNextMessage() {
Log.v(LABEL, "SmsSender - sendNextMessage");
if(isStopped()) {
Log.v(LABEL, "SmsSender - sendNextMessage - stopped");
sendFinished();
return;
}
if(smsCounter<message.to.getLength()) {
try {
//TODO Investigate why in case of multiple recipients the Extra of the intent is not correct...
Intent intent=new Intent(SMS_SENT);
intent.putExtra("rec", message.to.getElement(smsCounter));
intent.putExtra("body", message.body);
Log.v(LABEL, "intent created with rec = "+intent.getExtras().getString("rec"));
PendingIntent pnd = PendingIntent.getBroadcast(androidContext, 0, intent, 0);
if(bodyParts.size() == 1) {
smsManager.sendTextMessage(message.to.getElement(smsCounter), null, message.body, pnd, null);
}
else {
ArrayList<PendingIntent> pndList = new ArrayList<PendingIntent>();
for(int j=0;j<bodyParts.size()-1;j++){
pndList.add(null);
}
pndList.add(pnd);
smsManager.sendMultipartTextMessage(message.to.getElement(smsCounter), null, bodyParts, pndList, null);
}
}
// catch(IllegalArgumentException e) {
catch(Exception e) {
Log.v(LABEL, "SmsSender run - error "+e);
smsResponseReceiver.errorCaught(message.to.getElement(smsCounter));
}
smsCounter++;
}
}
}
//SMS Response receiver
class SmsResponseReceiver extends BroadcastReceiver {
private MessageSendCallback successCallback;
private ErrorCallback errorCallback;
private int smsNumber;
private int smsCounter;
private int errorCounter;
private SmsSender smsSender;
@Override
public void onReceive(Context ctx, Intent intent) {
if(smsSender.isStopped()) {
Log.v(LABEL, "SmsResponseReceiver onReceive - stopped");
smsSender.sendNextMessage();
return;
}
try {
String rec=null;
String body=null;
Bundle extras = intent.getExtras();
if(extras!=null){
rec=extras.getString("rec");
body=extras.getString("body");
}
switch(getResultCode()) {
case Activity.RESULT_OK:
Log.v(LABEL, "SmsResponseReceiver - Received intent OK ("+getResultCode()+") for rec "+rec);
//Insert the message in the db
ContentValues msgData = new ContentValues();
msgData.put("address", rec);
msgData.put("body", body);
msgData.put("read", 1);
Log.v(LABEL, "SmsResponseReceiver - 05");
androidContext.getContentResolver().insert(Uri.parse("content://sms/sent"), msgData);
Log.v(LABEL, "SmsResponseReceiver - 06");
sendFinished(0, rec);
break;
default:
Log.v(LABEL, "SmsResponseReceiver - Received intent error ("+getResultCode()+") for rec "+rec);
sendFinished(1, rec);
break;
}
}
catch(Exception e){
Log.v(LABEL, "SmsResponseReceiver - onReceive exception "+e.getMessage());
}
}
private SmsResponseReceiver(MessageSendCallback successCbk, ErrorCallback errorCbk, int smsNum, SmsSender sender) {
Log.v(LABEL, "SmsResponseReceiver constructor - succCbk: "+successCbk+" - errCbk: "+errorCbk+" - thread: "+(int)Thread.currentThread().getId());
successCallback = successCbk;
errorCallback = errorCbk;
smsNumber = smsNum;
smsCounter = 0;
errorCounter = 0;
smsSender = sender;
}
public void errorCaught(String recipient) {
sendFinished(1, recipient);
}
private void sendFinished(int res, String recipient) {
smsCounter++;
errorCounter+=res;
//TODO save the message in sent folder
Log.v(LABEL, "SmsResponseReceiver sendFinished - sms n "+smsCounter+" - err n "+errorCounter);
if(smsCounter == smsNumber) {
smsSender.sendFinished();
if(errorCounter==0) {
Log.v(LABEL, "SmsResponseReceiver sendFinished - successCallback");
successCallback.onsuccess();
}
else {
Log.v(LABEL, "SmsResponseReceiver sendFinished - errorCallback");
errorCallback.onerror(new DeviceAPIError(DeviceAPIError.UNKNOWN_ERR));
}
}
else {
if(res==0) {
Log.v(LABEL, "SmsResponseReceiver sendFinished - msgSendSuccess");
successCallback.onmessagesendsuccess(recipient);
}
else {
Log.v(LABEL, "SmsResponseReceiver sendFinished - msgSendError");
successCallback.onmessagesenderror(new DeviceAPIError(DeviceAPIError.UNKNOWN_ERR), recipient);
}
smsSender.sendNextMessage();
}
}
}
class SmsFinder implements MessagingRunnable {
private Env env = Env.getCurrent();
private FindMessagesSuccessCallback successCallback;
private ErrorCallback errorCallback;
private MessageFilter filter;
private boolean stopped;
private SmsFinder(FindMessagesSuccessCallback successCallback, ErrorCallback errorCallback, MessageFilter filter) {
this.successCallback = successCallback;
this.errorCallback = errorCallback;
this.filter = filter;
}
public synchronized boolean isStopped() {
return stopped;
}
public synchronized void stop() {
stopped = true;
}
private boolean searchSms() {
Log.v(LABEL, "searchSms - 01");
try {
if(filter==null) {
return true;
}
else if(filter.type==null) {
Log.v(LABEL, "searchSms - 02");
return true;
}
else for(int i=0; i<filter.type.length; i++) {
Log.v(LABEL, "searchSms - 03");
if(filter.type[i]==TYPE_SMS)
return true;
}
}
catch(Exception e) {
Log.v(LABEL, "searchSms exception: "+e.getMessage());
}
Log.v(LABEL, "searchSms - 09");
return false;
}
private boolean searchMms() {
Log.v(LABEL, "searchMms - 01");
try {
if(filter==null) {
return true;
}
else if(filter.type==null) {
Log.v(LABEL, "searchMms - 02");
return true;
}
else for(int i=0; i<filter.type.length; i++) {
Log.v(LABEL, "searchMms - 03");
if(filter.type[i]==TYPE_MMS)
return true;
}
}
catch(Exception e) {
Log.v(LABEL, "searchMms exception: "+e.getMessage());
}
Log.v(LABEL, "searchMms - 09");
return false;
}
private boolean searchDir(int dir) {
if(filter==null)
return true;
else if(filter.folder==null)
return true;
else for(int i=0; i<filter.folder.length; i++) {
if(filter.folder[i]==dir)
return true;
}
return false;
}
private String getFilterString(int folder) {
Log.v(LABEL, "getFilterString");
if(filter==null)
return null;
String res=new String();
boolean initialized=false;
if(filter.id!=null){
Log.v(LABEL, "getFilterString - id");
if(initialized)
res+=" AND ";
res+="_id="+filter.id;
initialized=true;
}
if(filter.from!=null){
Log.v(LABEL, "getFilterString - from");
if(initialized)
res+=" AND ";
if(folder==FOLDER_INBOX) {
res+="address=\'"+filter.from+"\'";
}
else {
res+="address=\'00000000\'";
}
initialized=true;
}
if(filter.to!=null) {
Log.v(LABEL, "getFilterString - to");
if(initialized)
res+=" AND ";
if(folder==FOLDER_INBOX) {
Log.v(LABEL, "getFilterString - to - inbox");
res+="address=\'00000000\'";
}
else {
if(filter.to.length == 1) {
Log.v(LABEL, "getFilterString - to - 1");
res+="address=\'"+filter.to[0]+"\'";
}
else {
Log.v(LABEL, "getFilterString - to - >1");
res+="(address=\'"+filter.to[0]+"\'";
for(int i=1;i<filter.to.length;i++) {
res+=" OR address=\'"+filter.to[i]+"\'";
}
res+=")";
}
}
initialized=true;
}
if(filter.body!=null){
Log.v(LABEL, "getFilterString - body");
if(initialized)
res+=" AND ";
res+="body=\'"+filter.body+"\'";
initialized=true;
}
if(filter.isRead!=null){
Log.v(LABEL, "getFilterString - isRead");
if(initialized)
res+=" AND ";
res+="read=";
if(filter.isRead){
res+="1";
}
else {
res+="0";
}
initialized=true;
}
if(initialized)
return res;
else
return null;
}
private Uri getUri(int type, int folder) {
Uri res=null;
if (type==TYPE_SMS) {
switch(folder) {
case FOLDER_INBOX:
res=Uri.parse("content://sms/inbox");
break;
case FOLDER_OUTBOX:
res=Uri.parse("content://sms/outbox");
break;
case FOLDER_SENTBOX:
res=Uri.parse("content://sms/sent");
break;
case FOLDER_DRAFTS:
res=Uri.parse("content://sms/draft");
break;
}
}
else if(type==TYPE_MMS) {
res=Uri.parse("content://mms/part");
}
return res;
}
private boolean checkTimestamp(Date timestamp) {
if(filter==null)
return true;
Log.v(LABEL, "checkTimestamp - timestamp is "+timestamp+", start is "+filter.startTimestamp+", end is "+filter.endTimestamp);
if(filter.startTimestamp!=null) {
if(timestamp.before(filter.startTimestamp))
return false;
}
if(filter.endTimestamp!=null) {
if(timestamp.after(filter.endTimestamp))
return false;
}
return true;
}
private List<Message> getSms(List<Message> list, int folder) {
String filterString=getFilterString(folder);
Log.v(LABEL, "smsFinder getSms - filter string is "+filterString);
// Uri searchUri=getUri(TYPE_SMS, folder);
Cursor cursor = androidContext.getContentResolver().query(getUri(TYPE_SMS, folder), new String[] { "_id", "thread_id", "address", "date", "read", "status", "type", "body" }, filterString, null,null);
MessageImpl msg;
Log.v(LABEL, "smsFinder getSms - 03 - messages found "+cursor.getCount());
cursor.moveToFirst();
for(int i=0; i<cursor.getCount(); i++) {
Log.v(LABEL, "smsFinder getSms - iteration n "+i);
msg = new MessageImpl();
msg.setContext(androidContext);
msg.timestamp = new Date(cursor.getLong(cursor.getColumnIndex("date")));
if(checkTimestamp(msg.timestamp)) {
msg.type = TYPE_SMS;
msg.id = cursor.getString(cursor.getColumnIndex("_id"));
msg.body = cursor.getString(cursor.getColumnIndex("body"));
msg.isRead = (cursor.getInt(cursor.getColumnIndex("read"))==0) ? false : true;
ObjectArray<String> toTmp;
Log.v(LABEL, "smsFinder getSms - 04");
switch(cursor.getInt(cursor.getColumnIndex("type"))) {
case 1:
Log.v(LABEL, "smsFinder getSms - 041");
msg.folder = FOLDER_INBOX;
msg.from = cursor.getString(cursor.getColumnIndex("address"));
toTmp = new org.meshpoint.anode.java.ObjectArray<String>(new String[]{"me"});
msg.to = toTmp;
list.add(msg);
break;
case 2:
Log.v(LABEL, "smsFinder getSms - 042");
msg.folder = FOLDER_SENTBOX;
msg.from = "me";
toTmp = new org.meshpoint.anode.java.ObjectArray<String>(new String[]{cursor.getString(cursor.getColumnIndex("address"))});
msg.to = toTmp;
list.add(msg);
break;
case 3:
Log.v(LABEL, "smsFinder getSms - 043");
msg.folder = FOLDER_DRAFTS;
msg.from = "me";
toTmp = new org.meshpoint.anode.java.ObjectArray<String>(new String[]{cursor.getString(cursor.getColumnIndex("address"))});
msg.to = toTmp;
list.add(msg);
break;
case 4:
//TODO verify if outbox is type 4...
Log.v(LABEL, "smsFinder getSms - 044");
msg.folder = FOLDER_OUTBOX;
msg.from = "me";
toTmp = new org.meshpoint.anode.java.ObjectArray<String>(new String[]{cursor.getString(cursor.getColumnIndex("address"))});
msg.to = toTmp;
list.add(msg);
break;
default:
//unknown type: skip the message
Log.v(LABEL, "smsFinder getSms - error - unexpected type of dir "+cursor.getInt(cursor.getColumnIndex("type")));
break;
}
}
cursor.moveToNext();
}
Log.v(LABEL, "smsFinder getSms - 05");
return list;
}
private List<Message> getMms(List<Message> list, int folder) {
Cursor cursor = androidContext.getContentResolver().query(Uri.parse("content://mms"), null, null, null,null);
Log.v(LABEL, "smsFinder getMms - 03 - messages found "+cursor.getCount());
cursor.moveToFirst();
for(int i=0; i<cursor.getCount(); i++) {
String id = cursor.getString(cursor.getColumnIndex("_id"));
Log.v(LABEL, "Messaggio "+i);
Log.v(LABEL, "id: "+id);
Log.v(LABEL, "date: "+cursor.getString(cursor.getColumnIndex("date")));
Log.v(LABEL, "read: "+cursor.getString(cursor.getColumnIndex("read")));
Log.v(LABEL, "seen: "+cursor.getString(cursor.getColumnIndex("seen")));
Cursor cursor2 = androidContext.getContentResolver().query(Uri.parse("content://mms/"+id+"/addr"), null, null, null,null);
Log.v(LABEL, "campi addr; righe "+cursor2.getCount()+" - colonne "+cursor2.getColumnCount());
cursor2.moveToFirst();
for (int k=0; k<cursor2.getCount(); k++) {
for(int j=0; j<cursor2.getColumnCount(); j++) {
Log.v(LABEL, cursor2.getColumnName(j)+": "+cursor2.getString(j));
}
cursor2.moveToNext();
}
cursor.moveToNext();
}
return list;
}
public void run() {
Log.v(LABEL, "smsFinder run");
Env.setEnv(env);
try {
Log.v(LABEL, "smsFinder run - 01");
List<Message> res = new ArrayList<Message>();
if(searchSms()) {
Log.v(LABEL, "smsFinder run - 02");
if(searchDir(FOLDER_INBOX)) {
Log.v(LABEL, "smsFinder run - search inbox");
res = getSms(res, FOLDER_INBOX);
}
if(searchDir(FOLDER_SENTBOX)) {
Log.v(LABEL, "smsFinder run - search sentbox");
res = getSms(res, FOLDER_SENTBOX);
}
if(searchDir(FOLDER_OUTBOX)) {
Log.v(LABEL, "smsFinder run - search outbox");
res = getSms(res, FOLDER_OUTBOX);
}
if(searchDir(FOLDER_DRAFTS)) {
Log.v(LABEL, "smsFinder run - search drafts");
res = getSms(res, FOLDER_DRAFTS);
}
}
if(searchMms()) {
Log.v(LABEL, "smsFinder run - 03");
//Uri uriSMSURI;
//uriSMSURI = Uri.parse("content://mms");
res = getMms(res, FOLDER_INBOX);
}
//TODO what if no results found? Return a null?
Log.v(LABEL, "smsFinder run - sending callback");
successCallback.onSuccess(res.toArray(new MessageImpl[res.size()]));
Log.v(LABEL, "smsFinder run - callback sent");
}
catch(Exception e) {
Log.v(LABEL, "smsFinder run, error: "+e);
errorCallback.onerror(new DeviceAPIError(DeviceAPIError.UNKNOWN_ERR));
}
Log.v(LABEL, "smsFinder run - END");
}
}
public class SmsReceiver extends BroadcastReceiver {
private OnIncomingMessage messageHandler;
private SmsReceiver(OnIncomingMessage messageHandler) {
this.messageHandler = messageHandler;
}
@Override
public void onReceive(Context context, Intent intent) {
Log.v(LABEL, "SMSReceiver - onreceive");
Env.setEnv(env);
Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
for (int i = 0; i < messages.length; i++) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) messages[i]);
MessageImpl msg = new MessageImpl();
msg.setContext(androidContext);
msg.type = TYPE_SMS;
// msg.id = ;
msg.body = smsMessage.getMessageBody();
msg.isRead = false;
msg.timestamp = new Date(smsMessage.getTimestampMillis());
ObjectArray<String> toTmp;
msg.folder = FOLDER_INBOX;
msg.from = smsMessage.getOriginatingAddress();
toTmp = new org.meshpoint.anode.java.ObjectArray<String>(new String[]{"me"});
msg.to = toTmp;
messageHandler.onEvent(msg);
}
}
}
}
abstract interface MessagingRunnable extends Runnable {
public abstract void stop();
public abstract boolean isStopped();
}
class MessagingPendingOperation extends PendingOperation {
private Thread t=null;
private MessagingRunnable r=null;
public MessagingPendingOperation(Thread t, MessagingRunnable r) {
this.t = t;
this.r = r;
}
// public void setData(Thread t, MessagingRunnable r) {
// this.t = t;
// this.r = r;
// }
public void cancel() {
// Log.v(LABEL, "MessagingPendingOperation cancel");
if(t!=null) {
// Log.v(LABEL, "MessagingPendingOperation cancel - send interrupt...");
//TODO is this interrupt needed???
t.interrupt();
if(r!=null)
r.stop();
}
}
}