First cut of two pane activity.

How to launch:
- Kick "Email 2 Pane" in the app drawer.

Major known issues:
- When you launches "Email 2 Pane", it starts directly; the logic in Welcom
  won't be executed.
- There's no UI to add accounts.  Use the old UI.
- There's no way to select non-default accounts.
- The on-screen buttons except for older/newer don't work.
- No contex menus work.

Change-Id: I38374acafafbae62e46f84294a7677e54686cfc2
This commit is contained in:
Makoto Onuki 2010-07-21 14:29:49 -07:00
parent bab0d45904
commit d6a2978857
10 changed files with 731 additions and 24 deletions

View File

@ -4,9 +4,9 @@
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.
@ -66,6 +66,20 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
We show this on the home for the development purpose.
STOPSHIP: Remove label, and MAIN/LAUNCHER intent filter.
-->
<activity
android:name=".activity.MessageListXL"
android:label="@string/activity_label_2pane"
android:theme="@android:style/Theme.WithActionBar"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.UpgradeAccounts"
android:label="@string/upgrade_accounts_title"
@ -146,8 +160,8 @@
android:launchMode="singleTop"
android:theme="@android:style/Theme.WithActionBar" >
</activity>
<activity
<activity
android:name=".activity.AccountShortcutPicker"
android:label="@string/app_name"
android:enabled="false"
@ -157,12 +171,12 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".activity.MailboxList"
android:theme="@android:style/Theme.WithActionBar" >
</activity>
<activity
android:name=".activity.MessageList"
android:theme="@style/ThemeNoTitleBar">
@ -188,7 +202,7 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:name=".activity.MessageView"
android:theme="@android:style/Theme.NoTitleBar" >
@ -261,12 +275,12 @@
android:enabled="false"
>
</service>
<!--EXCHANGE-REMOVE-SECTION-START-->
<!--Required stanza to register the ContactsSyncAdapterService with SyncManager -->
<service
android:name="com.android.exchange.ContactsSyncAdapterService"
android:exported="true">
<service
android:name="com.android.exchange.ContactsSyncAdapterService"
android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>

View File

@ -0,0 +1,118 @@
<?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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- We put MailboxListFragment here at runtime. -->
<FrameLayout
android:id="@+id/left_pane"
android:layout_width="360dip"
android:layout_height="match_parent"
/>
<!--
Right pane.
Because we need to show buttons for MessageView by ourselves, we need a linear layout here.
See also the comment below.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
>
<!-- We put MessageList/MessageViewFragment here at runtime. -->
<FrameLayout
android:id="@+id/right_pane"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<!--
Bottom buttons
These buttons can't be in MessageViewFragment, because the button
layout changes on the phone layout.
(We can (probably) create a separate layout for XL devices, but not sure if that'd be
a good idea, at this point.)
However, putting these buttons means we have to show/hide them
according to the screen state, which means we can't just use the
fragment transaction to replace fragments.
Maybe we should create another fragment, MessageViewWithCommandsFragment,
on top of MessageViewFragment.
-->
<LinearLayout
android:id="@+id/message_view_buttons"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:paddingBottom="1dip"
android:background="@android:drawable/bottom_bar"
android:visibility="gone"
>
<Button
android:id="@+id/delete"
android:text="@string/delete_action"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/unread"
android:text="@string/unread_action"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/reply"
android:text="@string/reply_action"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/reply_all"
android:text="@string/reply_all_action"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/forward"
android:text="@string/forward_action"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/moveToNewer"
android:text="@string/message_view_move_to_newer"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
<Button
android:id="@+id/moveToOlder"
android:text="@string/message_view_move_to_older"
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -23,7 +23,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
android:fadingEdge="none"
android:fillViewport="true"

View File

@ -737,4 +737,8 @@
always a larger value because it represents the limit of displayed results. -->
<string name="gal_completed_limited_fmt">First <xliff:g id="results" example="20">%1$d</xliff:g>
results from <xliff:g id="domain">%2$s</xliff:g></string>
<!-- Do Not Translate. STOPSHIP: Dev version only. Remove this. -->
<string name="activity_label_2pane">Email 2 Pane</string>
</resources>

View File

@ -0,0 +1,54 @@
/*
* 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.android.email.activity;
import com.android.email.provider.EmailContent.Account;
import android.content.AsyncTaskLoader;
import android.content.Context;
/**
* A Loader to load the default account id asynchronously.
*
* TODO Test it.
*/
public class DefaultAccountLoader extends AsyncTaskLoader<Long> {
public DefaultAccountLoader(Context context) {
super(context);
}
@Override
public Long loadInBackground() {
return Account.getDefaultAccountId(getContext());
}
@Override
public void destroy() {
stopLoading();
}
@Override
public void startLoading() {
cancelLoad();
forceLoad();
}
@Override
public void stopLoading() {
cancelLoad();
}
}

View File

@ -53,7 +53,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
private static final String MESSAGE_MAILBOX_ID_SELECTION = MessageColumns.MAILBOX_KEY + "=?";
// Account & mailboxes access
private long mAccountId;
private long mAccountId = -1;
private LoadMailboxesTask mLoadMailboxesTask;
private MessageCountTask mMessageCountTask;
private long mDraftMailboxKey = -1;
@ -64,6 +64,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
private MailboxesAdapter mListAdapter;
private Callback mCallback;
private boolean mStarted;
/**
* Callback interface that owning activities must implement
*/
@ -86,12 +88,10 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
super.onActivityCreated(savedInstanceState);
mActivity = getActivity();
ListView listView = getListView();
listView.setOnItemClickListener(this);
listView.setItemsCanFocus(false);
registerForContextMenu(listView);
mListAdapter = new MailboxesAdapter(mActivity);
}
@ -103,6 +103,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
public void bindActivityInfo(long accountId, Callback callback) {
mAccountId = accountId;
mCallback = callback;
if (mStarted) {
startLoading();
}
}
/**
@ -111,8 +114,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
@Override
public void onStart() {
super.onStart();
mLoadMailboxesTask = new LoadMailboxesTask(mAccountId);
mLoadMailboxesTask.execute();
mStarted = true;
startLoading();
}
/**
@ -120,6 +123,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
*/
@Override
public void onResume() {
mStarted = false;
super.onResume();
updateMessageCount();
}
@ -139,12 +143,19 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
/**
* Called when the fragment is no longer in use.
*/
@Override
public void onDestroy() {
@Override
public void onDestroy() {
super.onDestroy();
mListAdapter.changeCursor(null);
}
}
private void startLoading() {
if (mAccountId != -1) {
mLoadMailboxesTask = new LoadMailboxesTask(mAccountId);
mLoadMailboxesTask.execute();
}
}
/**
* This is called via the activity

View File

@ -102,6 +102,8 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
private int mFirstSelectedItemHeight = -1;
private boolean mCanAutoRefresh;
private boolean mStarted;
/**
* Callback interface that owning activities must implement
*/
@ -166,6 +168,21 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
}
}
@Override
public void onStart() {
super.onStart();
mStarted = true;
if (mAccountId != -1) {
startLoading();
}
}
@Override
public void onStop() {
mStarted = false;
super.onStop();
}
@Override
public void onResume() {
super.onResume();
@ -234,8 +251,14 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
mAccountId = accountId;
mMailboxId = mailboxId;
if (mStarted) {
startLoading();
}
}
private void startLoading() {
Utility.cancelTaskInterrupt(mLoadMessagesTask);
mLoadMessagesTask = new LoadMessagesTask(mailboxId, accountId);
mLoadMessagesTask = new LoadMessagesTask(mMailboxId, mAccountId);
mLoadMessagesTask.execute();
}

View File

@ -0,0 +1,466 @@
/*
* 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.android.email.activity;
import com.android.email.Email;
import com.android.email.R;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
// TODO Where/when/how do we close loaders?? Do we have to? Getting this error:
// Finalizing a Cursor that has not been deactivated or closed.
// database = /data/data/com.google.android.email/databases/EmailProvider.db,
// table = Account, query = SELECT _id, displayName, emailAddress FROM Account
/**
* Two pane activity for XL screen devices.
*
* TOOD Test it!
*/
public class MessageListXL extends Activity implements View.OnClickListener {
private static final String BUNDLE_KEY_ACCOUNT_ID = "MessageListXl.account_id";
private static final String BUNDLE_KEY_MAILBOX_ID = "MessageListXl.mailbox_id";
private static final String BUNDLE_KEY_MESSAGE_ID = "MessageListXl.message_id";
private static final int LOADER_ID_DEFAULT_ACCOUNT = 0;
private Context mContext;
private long mAccountId = -1;
private long mMailboxId = -1;
private long mMessageId = -1;
private MailboxListFragment mMailboxListFragment;
private MessageListFragment mMessageListFragment;
private MessageViewFragment mMessageViewFragment;
private View mMessageViewButtons;
private View mMoveToNewer;
private View mMoveToOlder;
private boolean mActivityInitialized;
private final ArrayList<Fragment> mRestoredFragments = new ArrayList<Fragment>();
private MessageOrderManager mOrderManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.message_list_xl);
final boolean isRestoring = (savedInstanceState != null);
mContext = getApplicationContext();
mMessageViewButtons = findViewById(R.id.message_view_buttons);
mMoveToNewer = findViewById(R.id.moveToNewer);
mMoveToOlder = findViewById(R.id.moveToOlder);
mMoveToNewer.setOnClickListener(this);
mMoveToOlder.setOnClickListener(this);
if (isRestoring) {
restoreSavedState(savedInstanceState);
}
if (mAccountId == -1) {
loadDefaultAccount();
}
// TODO Initialize accounts dropdown.
mActivityInitialized = true;
if (isRestoring) {
initRestoredFragments();
}
}
private void restoreSavedState(Bundle savedInstanceState) {
mAccountId = savedInstanceState.getLong(BUNDLE_KEY_ACCOUNT_ID, -1);
mMailboxId = savedInstanceState.getLong(BUNDLE_KEY_MAILBOX_ID, -1);
mMessageId = savedInstanceState.getLong(BUNDLE_KEY_MESSAGE_ID, -1);
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "MessageListXl: Restoring "
+ mAccountId + "," + mMailboxId + "," + mMessageId);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(BUNDLE_KEY_ACCOUNT_ID, mAccountId);
outState.putLong(BUNDLE_KEY_MAILBOX_ID, mMailboxId);
outState.putLong(BUNDLE_KEY_MESSAGE_ID, mMessageId);
}
@Override
protected void onStart() {
super.onStart();
startMessageOrderManager();
}
@Override
protected void onResume() {
super.onResume();
// TODO Add stuff that's done in MessageList.onResume().
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
stopMessageOrderManager();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onAttachFragment(Fragment fragment) {
if (!mActivityInitialized) {
// Fragments are being restored in super.onCreate().
// We can't initialize fragments until the activity is initialized, so remember them for
// now, and initialize them later in initRestoredFragments().
mRestoredFragments.add(fragment);
return;
}
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "MessageListXl.onAttachFragment fragment=" + fragment.getClass());
}
super.onAttachFragment(fragment);
initFragment(fragment);
}
private void initFragment(Fragment fragment) {
if (fragment instanceof MailboxListFragment) {
initMailboxListFragment((MailboxListFragment) fragment);
} else if (fragment instanceof MessageListFragment) {
initMessageListFragment((MessageListFragment) fragment);
} else if (fragment instanceof MessageViewFragment) {
initMessageViewFragment((MessageViewFragment) fragment);
}
}
/**
* Called from {@link #onCreate}.
* Initializes the fragmetns that are restored in super.onCreate().
*/
private void initRestoredFragments() {
for (Fragment f : mRestoredFragments) {
initFragment(f);
}
mRestoredFragments.clear();
}
private void startMessageOrderManager() {
if (mMailboxId == -1) {
return;
}
if (mOrderManager != null && mOrderManager.getMailboxId() == mMailboxId) {
return;
}
stopMessageOrderManager();
mOrderManager = new MessageOrderManager(this, mMailboxId,
new MessageOrderManager.Callback() {
@Override
public void onMessagesChanged() {
updateNavigationArrows();
}
@Override
public void onMessageNotFound() {
// Current message removed.
selectMailbox(mMailboxId);
}
});
}
private void stopMessageOrderManager() {
if (mOrderManager != null) {
mOrderManager.close();
mOrderManager = null;
}
}
private void loadDefaultAccount() {
getLoaderManager().initLoader(LOADER_ID_DEFAULT_ACCOUNT, null, new LoaderCallbacks<Long>() {
@Override
public Loader<Long> onCreateLoader(int id, Bundle args) {
return new DefaultAccountLoader(mContext);
}
@Override
public void onLoadFinished(Loader<Long> loader, Long accountId) {
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "Default account=" + accountId);
}
if (accountId == null || accountId == -1) {
onNoAccountFound();
} else {
selectAccount(accountId);
}
}
});
}
private void onNoAccountFound() {
// Open Welcome, which in turn shows the adding a new account screen.
Welcome.actionStart(this);
finish();
return;
}
// NOTE These selectXxx are *not* only methods where mXxxId's are changed.
// When the activity is re-created (e.g. for orientation change), the following things happen.
// - mXxxId's are restored from Bundle
// - Fragments are restored by the framework (in super.onCreate())
// - mXxxId's are set to fragments in initXxxFragment()
//
// So, if you want to do something when, for example, the current account changes,
// selectAccount() is probably not a good place to do it, because it'll be skipped when
// the activity is re-created.
// Instead, do that in initXxxFragment(). Alternatively, adding the same procedure to
// initRestoredFragments() too will probably work.
private void selectAccount(long accountId) {
// TODO Handle "combined mailboxes". Who should take care of it? This activity?
// MailboxListFragment??
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "selectAccount mAccountId=" + mAccountId);
}
if (accountId == -1) {
throw new RuntimeException();
}
if (mAccountId == accountId) {
return;
}
mAccountId = accountId;
mMailboxId = -1;
mMessageId = -1;
// TODO We don't have to replace the fragment, Just update it.
// That will be in accordance with our back model.
final MailboxListFragment fragment = new MailboxListFragment();
final FragmentTransaction ft = openFragmentTransaction();
ft.replace(R.id.left_pane, fragment);
if (mMessageListFragment != null) {
ft.remove(mMessageListFragment);
}
if (mMessageViewFragment != null) {
ft.remove(mMessageListFragment);
}
ft.commit();
// TODO Open inbox for the selected account.
}
private void selectMailbox(long mailboxId) {
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "selectMailbox mMailboxId=" + mMailboxId);
}
if (mMailboxId == mailboxId) {
return;
}
// TODO We don't have to replace the fragment, if it's already the message list. Just
// update it.
// That will be in accordance with our back model.
mMailboxId = mailboxId;
mMessageId = -1;
MessageListFragment fragment = new MessageListFragment();
openFragmentTransaction().replace(R.id.right_pane, fragment).commit();
}
private void selectMessage(long messageId) {
// TODO: Deal with draft messages. (open MessageCompose instead)
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "selectMessage messageId=" + mMessageId);
}
if (mMessageId == messageId) {
return;
}
mMessageId = messageId;
MessageViewFragment fragment = new MessageViewFragment();
openFragmentTransaction().replace(R.id.right_pane, fragment).commit();
}
private void initMailboxListFragment(MailboxListFragment fragment) {
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "initMailboxListFragment mAccountId=" + mAccountId);
}
if (mAccountId == -1) {
throw new RuntimeException();
}
mMessageListFragment = null;
mMessageViewFragment = null;
mMailboxListFragment = fragment;
fragment.bindActivityInfo(mAccountId, new MailboxListFragment.Callback() {
@Override
public void onRefresh(long accountId, long mailboxId) {
// Will be removed.
}
// TODO Rename to onSelectMailbox
@Override
public void onOpen(long accountId, long mailboxId) {
selectMailbox(mailboxId);
}
});
}
private void initMessageListFragment(MessageListFragment fragment) {
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "initMessageListFragment mMailboxId=" + mMailboxId);
}
if (mAccountId == -1 || mMailboxId == -1) {
throw new RuntimeException();
}
mMessageListFragment = fragment;
mMessageViewFragment = null;
mMessageViewButtons.setVisibility(View.GONE);
fragment.setCallback(new MessageListFragment.Callback() {
@Override
public void onSelectionChanged() {
// TODO Context mode
}
@Override
// TODO Rename to onSelectMessage
public void onMessageOpen(long messageId, long mailboxId) { // RENAME: OpenMessage ?
selectMessage(messageId);
}
@Override
public void onMailboxNotFound() { // RENAME: NotExists? (see MessageViewFragment)
// TODO: What to do??
}
});
fragment.openMailbox(mAccountId, mMailboxId);
}
private void initMessageViewFragment(MessageViewFragment fragment) {
if (Email.DEBUG) {
Log.d(Email.LOG_TAG, "initMessageViewFragment messageId=" + mMessageId);
}
if (mMessageId == -1) {
throw new RuntimeException();
}
mMessageViewFragment = fragment;
mMessageListFragment = null;
mMessageViewButtons.setVisibility(View.VISIBLE);
fragment.setCallback(new MessageViewFragment.Callback() {
@Override
public boolean onUrlInMessageClicked(String url) {
return false;
}
@Override
public void onRespondedToInvite(int response) {
}
@Override
public void onMessageSetUnread() {
}
@Override
public void onMessageNotExists() {
}
@Override
public void onLoadMessageStarted() {
}
@Override
public void onLoadMessageFinished() {
}
@Override
public void onLoadMessageError() {
}
@Override
public void onFetchAttachmentStarted(String attachmentName) {
}
@Override
public void onFetchAttachmentFinished() {
}
@Override
public void onFetchAttachmentError() {
}
@Override
public void onCalendarLinkClicked(long epochEventStartTime) {
}
});
fragment.openMessage(mMessageId);
startMessageOrderManager();
mOrderManager.moveTo(mMessageId);
updateNavigationArrows();
}
private void updateNavigationArrows() {
mMoveToNewer.setEnabled((mOrderManager != null) && mOrderManager.canMoveToNewer());
mMoveToOlder.setEnabled((mOrderManager != null) && mOrderManager.canMoveToOlder());
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.moveToOlder:
moveToOlder();
break;
case R.id.moveToNewer:
moveToNewer();
break;
}
}
private boolean moveToOlder() {
if (mOrderManager != null && mOrderManager.moveToOlder()) {
mMessageId = mOrderManager.getCurrentMessageId();
mMessageViewFragment.openMessage(mMessageId);
return true;
}
return false;
}
private boolean moveToNewer() {
if (mOrderManager != null && mOrderManager.moveToNewer()) {
mMessageId = mOrderManager.getCurrentMessageId();
mMessageViewFragment.openMessage(mMessageId);
return true;
}
return false;
}
}

View File

@ -90,6 +90,10 @@ public class MessageOrderManager {
startTask();
}
public long getMailboxId() {
return mMailboxId;
}
/**
* @return a {@link Handler} for {@link ContentObserver}.
*

View File

@ -151,6 +151,8 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
// contains the HTML content as set in WebView.
private String mHtmlTextWebView;
private boolean mStarted;
/**
* Encapsulates known information about a single attachment.
*/
@ -332,6 +334,10 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
@Override
public void onStart() {
super.onStart();
mStarted = true;
if (mMessageId != -1 || mFileEmailUri != null) {
openMessageInternal();
}
}
@Override
@ -346,6 +352,7 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
@Override
public void onStop() {
mStarted = false;
super.onStop();
}
@ -378,7 +385,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
mLoadBodyTask = null;
Utility.cancelTaskInterrupt(mLoadAttachmentsTask);
mLoadAttachmentsTask = null;
mPresenceUpdater.cancelAll();
if (mPresenceUpdater != null) {
mPresenceUpdater.cancelAll();
}
}
/**
@ -401,7 +410,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
mFileEmailUri = null;
mMessageId = messageId;
mAccountId = -1;
openMessageInternal();
if (mStarted) {
openMessageInternal();
}
}
/** Called by activities to a URI to an EML file to open. */
@ -409,7 +420,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
mFileEmailUri = fileEmailUri;
mMessageId = -1;
mAccountId = -1;
openMessageInternal();
if (mStarted) {
openMessageInternal();
}
}
private void openMessageInternal() {