2 * Copyright (C) 2010 Felix Bechstein
4 * This file is part of WebSMS.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free Software
8 * Foundation; either version 3 of the License, or (at your option) any later
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public License along with
17 * this program; If not, see <http://www.gnu.org/licenses/>.
19 package de
.ub0r
.android
.andGMXsms
;
21 import android
.app
.Notification
;
22 import android
.app
.NotificationManager
;
23 import android
.app
.PendingIntent
;
24 import android
.content
.BroadcastReceiver
;
25 import android
.content
.ContentValues
;
26 import android
.content
.Context
;
27 import android
.content
.Intent
;
28 import android
.content
.SharedPreferences
;
29 import android
.net
.Uri
;
30 import android
.preference
.PreferenceManager
;
31 import android
.util
.Log
;
32 import de
.ub0r
.android
.websms
.connector
.common
.CommandReceiver
;
33 import de
.ub0r
.android
.websms
.connector
.common
.ConnectorCommand
;
34 import de
.ub0r
.android
.websms
.connector
.common
.ConnectorSpec
;
37 * Fetch all incomming Broadcasts and forward them to WebSMS.
41 public final class WebSMSReceiver
extends BroadcastReceiver
{
42 /** Tag for debug output. */
43 private static final String TAG
= "WebSMS.bcr";
45 /** Intent's scheme to send sms. */
46 private static final String INTENT_SCHEME_SMSTO
= "smsto";
48 /** SMS DB: address. */
49 static final String ADDRESS
= "address";
50 /** SMS DB: person. */
51 // private static final String PERSON = "person";
53 private static final String DATE
= "date";
55 static final String READ
= "read";
56 /** SMS DB: status. */
57 // private static final String STATUS = "status";
59 static final String TYPE
= "type";
61 static final String BODY
= "body";
62 /** SMS DB: type - sent. */
63 static final int MESSAGE_TYPE_SENT
= 2;
65 /** Next notification ID. */
66 private static int nextNotificationID
= 1;
72 public void onReceive(final Context context
, final Intent intent
) {
73 final String action
= intent
.getAction();
74 Log
.d(TAG
, "action: " + action
);
78 if (CommandReceiver
.ACTION_INFO
.equals(action
)) {
79 this.handleInfoAction(context
, intent
);
84 * Fetch INFO broadcast.
91 private void handleInfoAction(final Context context
, final Intent intent
) {
92 final ConnectorSpec specs
= new ConnectorSpec(intent
);
93 final ConnectorCommand command
= new ConnectorCommand(intent
);
96 // security check. some other apps may send faulty broadcasts
101 WebSMS
.addConnector(specs
);
102 } catch (Exception e
) {
103 Log
.e(TAG
, "error while receiving broadcast", e
);
105 // save send messages
106 if (command
!= null && // .
107 command
.getType() == ConnectorCommand
.TYPE_SEND
) {
108 this.handleSendCommand(specs
, context
, intent
, command
);
113 * Save sent message or display error notification if failed sending.
116 * {@link ConnectorSpec}
122 * {@link ConnectorCommand}
124 private void handleSendCommand(final ConnectorSpec specs
,
125 final Context context
, final Intent intent
,
126 final ConnectorCommand command
) {
128 if (!specs
.hasStatus(ConnectorSpec
.STATUS_ERROR
)) {
129 this.saveMessage(context
, command
);
132 // Display notification if sending failed
133 final String
[] r
= command
.getRecipients();
134 final int l
= r
.length
;
135 StringBuilder buf
= new StringBuilder(r
[0]);
136 for (int i
= 1; i
< l
; i
++) {
140 final String to
= buf
.toString();
143 Notification n
= new Notification(R
.drawable
.stat_notify_sms_failed
,
144 context
.getString(R
.string
.notify_failed_
), System
145 .currentTimeMillis());
146 final Intent i
= new Intent(Intent
.ACTION_SENDTO
, Uri
147 .parse(INTENT_SCHEME_SMSTO
+ ":" + Uri
.encode(to
)), context
,
149 // add pending intent
150 i
.putExtra(Intent
.EXTRA_TEXT
, command
.getText());
151 i
.putExtra(WebSMS
.EXTRA_ERRORMESSAGE
, specs
.getErrorMessage());
152 i
.setFlags(i
.getFlags() | Intent
.FLAG_ACTIVITY_NEW_TASK
);
154 final PendingIntent cIntent
= PendingIntent
.getActivity(context
, 0, i
,
156 n
.setLatestEventInfo(context
, context
.getString(R
.string
.notify_failed
)
157 + " " + specs
.getErrorMessage(), to
+ ": " + command
.getText(),
159 n
.flags
|= Notification
.FLAG_AUTO_CANCEL
;
161 n
.flags
|= Notification
.FLAG_SHOW_LIGHTS
;
162 n
.ledARGB
= 0xffff0000;
166 final SharedPreferences p
= PreferenceManager
167 .getDefaultSharedPreferences(context
);
168 final boolean vibrateOnFail
= p
.getBoolean(WebSMS
.PREFS_FAIL_VIBRATE
,
170 final String s
= p
.getString(WebSMS
.PREFS_FAIL_SOUND
, null);
172 if (s
== null || s
.length() <= 0) {
175 soundOnFail
= Uri
.parse(s
);
179 n
.flags
|= Notification
.DEFAULT_VIBRATE
;
181 n
.sound
= soundOnFail
;
183 NotificationManager mNotificationMgr
= // .
184 (NotificationManager
) context
185 .getSystemService(Context
.NOTIFICATION_SERVICE
);
186 mNotificationMgr
.notify(getNotificationID(), n
);
190 * Get a fresh and unique ID for a new notification.
192 * @return return the ID
194 private static synchronized int getNotificationID() {
195 ++nextNotificationID
;
196 return nextNotificationID
;
200 * Save Message to internal database.
205 * {@link ConnectorCommand}
207 private void saveMessage(final Context context
,
208 final ConnectorCommand command
) {
209 if (command
.getType() != ConnectorCommand
.TYPE_SEND
) {
212 final String
[] recipients
= command
.getRecipients();
213 for (int i
= 0; i
< recipients
.length
; i
++) {
214 if (recipients
[i
] == null || recipients
[i
].length() == 0) {
215 continue; // skip empty recipients
217 // save sms to content://sms/sent
218 ContentValues values
= new ContentValues();
219 values
.put(ADDRESS
, recipients
[i
]);
221 values
.put(TYPE
, MESSAGE_TYPE_SENT
);
222 values
.put(BODY
, command
.getText());
223 if (command
.getSendLater() > 0) {
224 values
.put(DATE
, command
.getSendLater());
226 context
.getContentResolver().insert(
227 Uri
.parse("content://sms/sent"), values
);