diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c6143ecdf..67557a2df 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -53,6 +53,9 @@ + + diff --git a/src/com/android/email/activity/NfcHandler.java b/src/com/android/email/activity/NfcHandler.java new file mode 100644 index 000000000..ec62a51fb --- /dev/null +++ b/src/com/android/email/activity/NfcHandler.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2011 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.android.email.activity; + +import com.android.emailcommon.provider.Account; + +import android.app.Activity; +import android.content.Context; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.text.TextUtils; +import android.util.Log; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +/** + * This class implements sharing the e-mail address of the + * active account to another device using NFC. NFC sharing is only + * enabled when the activity is in the foreground and resumed. + * When an NFC link is established, {@link #createMessage} + * will be called to create the data to be sent over the link, + * which is a vCard in this case. + */ +public class NfcHandler implements NfcAdapter.NdefPushCallback { + private NfcAdapter mNfcAdapter; + private UIControllerBase mUiController; + private Activity mActivity; + private String mCurrentEmail; + private static final String TAG = "ContactsNfcHandler"; + + public NfcHandler(UIControllerBase controller, Activity + activity) { + mUiController = controller; + mActivity = activity; + mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity); + } + + public void onAccountChanged() { + if (mUiController.isActualAccountSelected()) { + final long accountId = mUiController.getActualAccountId(); + final Account account = Account.restoreAccountWithId( + mActivity, accountId); + mCurrentEmail = account.mEmailAddress; + } else { + mCurrentEmail = null; + } + + } + + public void onPause() { + if (mNfcAdapter != null) { + mNfcAdapter.disableForegroundNdefPush( + mActivity); + } + } + + public void onResume() { + if (mNfcAdapter != null) { + mNfcAdapter.enableForegroundNdefPush( + mActivity, this); + onAccountChanged(); // Fetch current account + } + } + + private static NdefMessage buildMailtoNdef(String address) { + if (TextUtils.isEmpty(address)) { + return null; + } + byte[] accountBytes; + try { + accountBytes = URLEncoder.encode(address, "UTF-8") + .getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + return null; + } + byte[] recordBytes = new byte[accountBytes.length + 1]; + recordBytes[0] = 0x06; // NDEF mailto: prefix + System.arraycopy(accountBytes, 0, recordBytes, 1, accountBytes.length); + NdefRecord mailto = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, + new byte[0], recordBytes); + return new NdefMessage(new NdefRecord[] { mailto }); + } + + @Override + public NdefMessage createMessage() { + if (mCurrentEmail != null) { + return buildMailtoNdef(mCurrentEmail); + } else { + return null; + } + } + + @Override + public void onMessagePushed() { + } +} diff --git a/src/com/android/email/activity/UIControllerBase.java b/src/com/android/email/activity/UIControllerBase.java index 0ec907c7f..000c97e19 100644 --- a/src/com/android/email/activity/UIControllerBase.java +++ b/src/com/android/email/activity/UIControllerBase.java @@ -93,6 +93,12 @@ abstract class UIControllerBase implements MailboxListFragment.Callback, */ private final List mRemovedFragments = new LinkedList(); + /** + * The NfcHandler implements Near Field Communication sharing features + * whenever the activity is in the foreground. + */ + private NfcHandler mNfcHandler; + /** * The active context for the current MessageList. * In some UI layouts such as the one-pane view, the message list may not be visible, but is @@ -143,6 +149,7 @@ abstract class UIControllerBase implements MailboxListFragment.Callback, if (DEBUG_FRAGMENTS) { FragmentManager.enableDebugLogging(true); } + mNfcHandler = new NfcHandler(this, activity); } /** @@ -196,6 +203,7 @@ abstract class UIControllerBase implements MailboxListFragment.Callback, Log.d(Logging.LOG_TAG, this + " onActivityResume"); } refreshActionBar(); + mNfcHandler.onResume(); } /** @@ -205,6 +213,7 @@ abstract class UIControllerBase implements MailboxListFragment.Callback, if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(Logging.LOG_TAG, this + " onActivityPause"); } + mNfcHandler.onPause(); } /** @@ -529,7 +538,6 @@ abstract class UIControllerBase implements MailboxListFragment.Callback, // Do nothing if the account is already selected. Not even going back to the inbox. return; } - if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) { openMailbox(accountId, Mailbox.QUERY_ALL_INBOXES); } else { @@ -541,11 +549,11 @@ abstract class UIControllerBase implements MailboxListFragment.Callback, + " to Welcome..."); Welcome.actionOpenAccountInbox(mActivity, accountId); mActivity.finish(); - return; } else { openMailbox(accountId, inboxId); } } + mNfcHandler.onAccountChanged(); } /**