diff options
6 files changed, 454 insertions, 0 deletions
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 6615d711b..1e3f66be5 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -29,6 +29,8 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.SET_WALLPAPER" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.SEND_SMS" /> + <uses-permission android:name="android.permission.RECEIVE_SMS" /> <!-- We will request access to the camera, saying we require a camera of some sort but not one with autofocus capability. --> @@ -651,6 +653,23 @@ </intent-filter> </activity> + <activity android:name=".os.SmsMessagingDemo" android:label="OS/SMS Messaging"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.SAMPLE_CODE" /> + </intent-filter> + </activity> + + <activity android:name=".os.SmsReceivedDialog" + android:theme="@android:style/Theme.Translucent.NoTitleBar" + android:launchMode="singleInstance" /> + + <receiver android:name=".os.SmsMessageReceiver" android:enabled="false"> + <intent-filter> + <action android:name="android.provider.Telephony.SMS_RECEIVED" /> + </intent-filter> + </receiver> + <!-- ************************************* --> <!-- ANIMATION PACKAGE SAMPLES --> <!-- ************************************* --> diff --git a/samples/ApiDemos/res/layout/sms_demo.xml b/samples/ApiDemos/res/layout/sms_demo.xml new file mode 100644 index 000000000..1074f52ca --- /dev/null +++ b/samples/ApiDemos/res/layout/sms_demo.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source 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. +--> + +<!-- Demonstrates sending and receiving SMS messages. + See corresponding Java code SmsMessagingDemo.java +--> + +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="6dip"> + <TextView + android:textColor="#ff0000" + android:textStyle="bold" + android:text="@string/sms_warning" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <CheckBox + android:id="@+id/sms_enable_receiver" + android:text="@string/sms_enable_receiver" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + <TableLayout + android:padding="6dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:stretchColumns="1"> + <TableRow android:layout_width="match_parent"> + <TextView android:text="@string/sms_recipient_label" /> + <EditText android:id="@+id/sms_recipient" /> + </TableRow> + <TableRow> + <TextView android:text="@string/sms_content_label" /> + <EditText android:id="@+id/sms_content" /> + </TableRow> + <TableRow> + <Button + android:id="@+id/sms_send_message" + android:text="@string/sms_send_message" + android:layout_column="1" /> + </TableRow> + <TableRow> + <TextView + android:id="@+id/sms_status" + android:layout_column="1" /> + </TableRow> + </TableLayout> + </LinearLayout> +</ScrollView> diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml index c7bb84e9c..799d67fa0 100644 --- a/samples/ApiDemos/res/values/strings.xml +++ b/samples/ApiDemos/res/values/strings.xml @@ -879,5 +879,21 @@ <string name="appwidget_configure_instructions">This text will be shown before the date in our example widget.</string> <string name="appwidget_prefix_default">Oh hai</string> <string name="appwidget_text_format"><xliff:g id="prefix">%1$s</xliff:g>: <xliff:g id="time">%2$s</xliff:g></string> + + <!-- ============================ --> + <!-- SMS Messaging examples strings --> + <!-- ============================ --> + + <string name="sms_warning"> + WARNING: this demo can send actual text messages (one at a time), so be sure to + test with the Android emulator or have a text messaging plan with your carrier. + </string> + <string name="sms_enable_receiver">Enable SMS broadcast receiver</string> + <string name="sms_recipient_label">Recipient #</string> + <string name="sms_content_label">Message Body</string> + <string name="sms_send_message">Send</string> + <string name="sms_speak_string_format">Message from "%1$s": %2$s</string> + <string name="reply">Reply</string> + <string name="dismiss">Dismiss</string> </resources> diff --git a/samples/ApiDemos/src/com/example/android/apis/os/SmsMessageReceiver.java b/samples/ApiDemos/src/com/example/android/apis/os/SmsMessageReceiver.java new file mode 100644 index 000000000..ec809557f --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/os/SmsMessageReceiver.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 The Android Open Source 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. + */ + +package com.example.android.apis.os; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.ContactsContract; +import android.telephony.SmsMessage; + +public class SmsMessageReceiver extends BroadcastReceiver { + /** Tag string for our debug logs */ + private static final String TAG = "SmsMessageReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + Bundle extras = intent.getExtras(); + if (extras == null) + return; + + Object[] pdus = (Object[]) extras.get("pdus"); + + for (int i = 0; i < pdus.length; i++) { + SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[i]); + String fromAddress = message.getOriginatingAddress(); + String fromDisplayName = fromAddress; + + Uri uri; + String[] projection; + + // If targeting Donut or below, use + // Contacts.Phones.CONTENT_FILTER_URL and + // Contacts.Phones.DISPLAY_NAME + uri = Uri.withAppendedPath( + ContactsContract.PhoneLookup.CONTENT_FILTER_URI, + Uri.encode(fromAddress)); + projection = new String[] { ContactsContract.PhoneLookup.DISPLAY_NAME }; + + // Query the filter URI + Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); + if (cursor != null) { + if (cursor.moveToFirst()) + fromDisplayName = cursor.getString(0); + + cursor.close(); + } + + // Trigger the main activity to fire up a dialog that shows/reads the received messages + Intent di = new Intent(); + di.setClass(context, SmsReceivedDialog.class); + di.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); + di.putExtra(SmsReceivedDialog.SMS_FROM_ADDRESS_EXTRA, fromAddress); + di.putExtra(SmsReceivedDialog.SMS_FROM_DISPLAY_NAME_EXTRA, fromDisplayName); + di.putExtra(SmsReceivedDialog.SMS_MESSAGE_EXTRA, message.getMessageBody().toString()); + context.startActivity(di); + + // For the purposes of this demo, we'll only handle the first received message. + break; + } + } +} diff --git a/samples/ApiDemos/src/com/example/android/apis/os/SmsMessagingDemo.java b/samples/ApiDemos/src/com/example/android/apis/os/SmsMessagingDemo.java new file mode 100644 index 000000000..94f4e5ac5 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/os/SmsMessagingDemo.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2010 The Android Open Source 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. + */ + +package com.example.android.apis.os; + +import java.util.List; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.os.Bundle; +import android.telephony.SmsManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.CompoundButton.OnCheckedChangeListener; + +import com.example.android.apis.R; + +public class SmsMessagingDemo extends Activity { + /** Tag string for our debug logs */ + private static final String TAG = "SmsMessagingDemo"; + + public static final String SMS_RECIPIENT_EXTRA = "com.example.android.apis.os.SMS_RECIPIENT"; + + public static final String ACTION_SMS_SENT = "com.example.android.apis.os.SMS_SENT_ACTION"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.sms_demo); + + if (getIntent().hasExtra(SMS_RECIPIENT_EXTRA)) { + ((TextView) findViewById(R.id.sms_recipient)).setText(getIntent().getExtras() + .getString(SMS_RECIPIENT_EXTRA)); + ((TextView) findViewById(R.id.sms_content)).requestFocus(); + } + + // Enable or disable the broadcast receiver depending on the checked + // state of the checkbox. + CheckBox enableCheckBox = (CheckBox) findViewById(R.id.sms_enable_receiver); + + final PackageManager pm = this.getPackageManager(); + final ComponentName componentName = new ComponentName("com.example.android.apis", + "com.example.android.apis.os.SmsMessageReceiver"); + + enableCheckBox.setChecked(pm.getComponentEnabledSetting(componentName) == + PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + + enableCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + Log.d(TAG, (isChecked ? "Enabling" : "Disabling") + " SMS receiver"); + + pm.setComponentEnabledSetting(componentName, + isChecked ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + }); + + final EditText recipientTextEdit = (EditText) SmsMessagingDemo.this + .findViewById(R.id.sms_recipient); + final EditText contentTextEdit = (EditText) SmsMessagingDemo.this + .findViewById(R.id.sms_content); + final TextView statusView = (TextView) SmsMessagingDemo.this.findViewById(R.id.sms_status); + + // Watch for send button clicks and send text messages. + Button sendButton = (Button) findViewById(R.id.sms_send_message); + sendButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + if (TextUtils.isEmpty(recipientTextEdit.getText())) { + Toast.makeText(SmsMessagingDemo.this, "Please enter a message recipient.", + Toast.LENGTH_SHORT).show(); + return; + } + + if (TextUtils.isEmpty(contentTextEdit.getText())) { + Toast.makeText(SmsMessagingDemo.this, "Please enter a message body.", + Toast.LENGTH_SHORT).show(); + return; + } + + recipientTextEdit.setEnabled(false); + contentTextEdit.setEnabled(false); + + SmsManager sms = SmsManager.getDefault(); + + List<String> messages = sms.divideMessage(contentTextEdit.getText().toString()); + + String recipient = recipientTextEdit.getText().toString(); + for (String message : messages) { + sms.sendTextMessage(recipient, null, message, PendingIntent.getBroadcast( + SmsMessagingDemo.this, 0, new Intent(ACTION_SMS_SENT), 0), null); + } + } + }); + + // Register broadcast receivers for SMS sent and delivered intents + registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String message = null; + boolean error = true; + switch (getResultCode()) { + case Activity.RESULT_OK: + message = "Message sent!"; + error = false; + break; + case SmsManager.RESULT_ERROR_GENERIC_FAILURE: + message = "Error."; + break; + case SmsManager.RESULT_ERROR_NO_SERVICE: + message = "Error: No service."; + break; + case SmsManager.RESULT_ERROR_NULL_PDU: + message = "Error: Null PDU."; + break; + case SmsManager.RESULT_ERROR_RADIO_OFF: + message = "Error: Radio off."; + break; + } + + recipientTextEdit.setEnabled(true); + contentTextEdit.setEnabled(true); + contentTextEdit.setText(""); + + statusView.setText(message); + statusView.setTextColor(error ? Color.RED : Color.GREEN); + } + }, new IntentFilter(ACTION_SMS_SENT)); + } +} diff --git a/samples/ApiDemos/src/com/example/android/apis/os/SmsReceivedDialog.java b/samples/ApiDemos/src/com/example/android/apis/os/SmsReceivedDialog.java new file mode 100644 index 000000000..0df93a782 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/os/SmsReceivedDialog.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2010 The Android Open Source 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. + */ + +package com.example.android.apis.os; + +import java.util.Locale; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.speech.tts.TextToSpeech; +import android.speech.tts.TextToSpeech.OnInitListener; +import android.util.Log; + +import com.example.android.apis.R; + +public class SmsReceivedDialog extends Activity implements OnInitListener { + private static final String TAG = "SmsReceivedDialog"; + + private static final int DIALOG_SHOW_MESSAGE = 1; + + public static final String SMS_FROM_ADDRESS_EXTRA = "com.example.android.apis.os.SMS_FROM_ADDRESS"; + public static final String SMS_FROM_DISPLAY_NAME_EXTRA = "com.example.android.apis.os.SMS_FROM_DISPLAY_NAME"; + public static final String SMS_MESSAGE_EXTRA = "com.example.android.apis.os.SMS_MESSAGE"; + + private TextToSpeech mTts; + + private String mFromDisplayName; + private String mFromAddress; + private String mMessage; + private String mFullBodyString; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mFromAddress = getIntent().getExtras().getString(SMS_FROM_ADDRESS_EXTRA); + mFromDisplayName = getIntent().getExtras().getString(SMS_FROM_DISPLAY_NAME_EXTRA); + mMessage = getIntent().getExtras().getString(SMS_MESSAGE_EXTRA); + + mFullBodyString = String.format( + getResources().getString(R.string.sms_speak_string_format), + mFromDisplayName, + mMessage); + + showDialog(DIALOG_SHOW_MESSAGE); + mTts = new TextToSpeech(this, this); + } + + public void onInit(int status) { + if (status == TextToSpeech.SUCCESS) { + int result = mTts.setLanguage(Locale.US); + if (result == TextToSpeech.LANG_MISSING_DATA + || result == TextToSpeech.LANG_NOT_SUPPORTED) { + Log.e(TAG, "TTS language is not available."); + } else { + mTts.speak(mFullBodyString, TextToSpeech.QUEUE_ADD, null); + } + } else { + // Initialization failed. + Log.e(TAG, "Could not initialize TTS."); + } + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case DIALOG_SHOW_MESSAGE: + return new AlertDialog.Builder(this) + .setIcon(android.R.drawable.ic_dialog_email) + .setTitle("Message Received") + .setMessage(mFullBodyString) + .setPositiveButton(R.string.reply, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + // Begin creating the reply with the SmsMessagingDemo activity + Intent i = new Intent(); + i.setClass(SmsReceivedDialog.this, SmsMessagingDemo.class); + i.putExtra(SmsMessagingDemo.SMS_RECIPIENT_EXTRA, mFromAddress); + startActivity(i); + + dialog.dismiss(); + finish(); + } + }) + .setNegativeButton(R.string.dismiss, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + dialog.dismiss(); + finish(); + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + public void onCancel(DialogInterface dialog) { + finish(); + } + }).create(); + } + return null; + } +} |
