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 final ConnectorSpec specs
= new ConnectorSpec(intent
);
80 final ConnectorCommand command
= new ConnectorCommand(intent
);
85 WebSMS
.addConnector(specs
);
86 } catch (Exception e
) {
87 Log
.e(TAG
, "error while receiving broadcast", e
);
90 if (command
== null) {
93 if (command
.getType() == ConnectorCommand
.TYPE_SEND
) {
94 if (!specs
.hasStatus(ConnectorSpec
.STATUS_ERROR
)) {
95 this.saveMessage(context
, command
);
97 // Display notification if sending failed
98 final String
[] r
= command
.getRecipients();
99 final int l
= r
.length
;
100 StringBuilder buf
= new StringBuilder(r
[0]);
101 for (int i
= 1; i
< l
; i
++) {
105 final String to
= buf
.toString();
108 Notification n
= new Notification(
109 R
.drawable
.stat_notify_sms_failed
, context
110 .getString(R
.string
.notify_failed_
), System
111 .currentTimeMillis());
112 final Intent i
= new Intent(Intent
.ACTION_SENDTO
, Uri
113 .parse(INTENT_SCHEME_SMSTO
+ ":" + Uri
.encode(to
)),
114 context
, WebSMS
.class);
115 // add pending intent
116 i
.putExtra(Intent
.EXTRA_TEXT
, command
.getText());
117 i
.putExtra(WebSMS
.EXTRA_ERRORMESSAGE
, specs
119 i
.setFlags(i
.getFlags() | Intent
.FLAG_ACTIVITY_NEW_TASK
);
121 final PendingIntent cIntent
= PendingIntent
.getActivity(
123 n
.setLatestEventInfo(context
, context
124 .getString(R
.string
.notify_failed
)
125 + " " + specs
.getErrorMessage(), to
+ ": "
126 + command
.getText(), cIntent
);
127 n
.flags
|= Notification
.FLAG_AUTO_CANCEL
;
129 n
.flags
|= Notification
.FLAG_SHOW_LIGHTS
;
130 n
.ledARGB
= 0xffff0000;
134 final SharedPreferences p
= PreferenceManager
135 .getDefaultSharedPreferences(context
);
136 final boolean vibrateOnFail
= p
.getBoolean(
137 WebSMS
.PREFS_FAIL_VIBRATE
, false);
138 final String s
= p
.getString(WebSMS
.PREFS_FAIL_SOUND
, null);
140 if (s
== null || s
.length() <= 0) {
143 soundOnFail
= Uri
.parse(s
);
147 n
.flags
|= Notification
.DEFAULT_VIBRATE
;
149 n
.sound
= soundOnFail
;
151 NotificationManager mNotificationMgr
= // .
152 (NotificationManager
) context
153 .getSystemService(Context
.NOTIFICATION_SERVICE
);
154 mNotificationMgr
.notify(getNotificationID(), n
);
161 * Get a fresh and unique ID for a new notification.
163 * @return return the ID
165 private static synchronized int getNotificationID() {
166 ++nextNotificationID
;
167 return nextNotificationID
;
171 * Save Message to internal database.
176 * {@link ConnectorCommand}
178 private void saveMessage(final Context context
,
179 final ConnectorCommand command
) {
180 if (command
.getType() != ConnectorCommand
.TYPE_SEND
) {
183 final String
[] recipients
= command
.getRecipients();
184 for (int i
= 0; i
< recipients
.length
; i
++) {
185 if (recipients
[i
] == null || recipients
[i
].length() == 0) {
186 continue; // skip empty recipients
188 // save sms to content://sms/sent
189 ContentValues values
= new ContentValues();
190 values
.put(ADDRESS
, recipients
[i
]);
192 values
.put(TYPE
, MESSAGE_TYPE_SENT
);
193 values
.put(BODY
, command
.getText());
194 if (command
.getSendLater() > 0) {
195 values
.put(DATE
, command
.getSendLater());
197 context
.getContentResolver().insert(
198 Uri
.parse("content://sms/sent"), values
);