mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-27 19:52:17 -05:00
Update issue 1623
Removed dependency from K9 to MessageProvider (and added ability for components to register themselve for being notified when K9 instance is ready) Moved Intent broadcast code from MessageProvider to K9 Made query() easily extensible using strategy pattern, the discriminant still being the Uri path
This commit is contained in:
parent
46ba547d94
commit
71dbdf3417
@ -1,6 +1,11 @@
|
|||||||
|
|
||||||
package com.fsck.k9;
|
package com.fsck.k9;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -20,19 +25,42 @@ import com.fsck.k9.mail.Address;
|
|||||||
import com.fsck.k9.mail.Message;
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||||
import com.fsck.k9.provider.MessageProvider;
|
|
||||||
import com.fsck.k9.service.BootReceiver;
|
import com.fsck.k9.service.BootReceiver;
|
||||||
import com.fsck.k9.service.MailService;
|
import com.fsck.k9.service.MailService;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class K9 extends Application
|
public class K9 extends Application
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Components that are interested in knowing when the K9 instance is
|
||||||
|
* available and ready (Android invokes Application.onCreate() after other
|
||||||
|
* components') should implement this interface and register using
|
||||||
|
* {@link K9#registerApplicationAware(ApplicationAware)}.
|
||||||
|
*/
|
||||||
|
public static interface ApplicationAware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Called when the Application instance is available and ready.
|
||||||
|
*
|
||||||
|
* @param application
|
||||||
|
* The application instance. Never <code>null</code>.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
void initializeComponent(K9 application) throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
public static Application app = null;
|
public static Application app = null;
|
||||||
public static File tempDirectory;
|
public static File tempDirectory;
|
||||||
public static final String LOG_TAG = "k9";
|
public static final String LOG_TAG = "k9";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components that are interested in knowing when the K9 instance is
|
||||||
|
* available and ready.
|
||||||
|
*
|
||||||
|
* @see ApplicationAware
|
||||||
|
*/
|
||||||
|
private static List<ApplicationAware> observers = new ArrayList<ApplicationAware>();
|
||||||
|
|
||||||
|
|
||||||
public enum BACKGROUND_OPS
|
public enum BACKGROUND_OPS
|
||||||
{
|
{
|
||||||
WHEN_CHECKED, ALWAYS, NEVER, WHEN_CHECKED_AUTO_SYNC
|
WHEN_CHECKED, ALWAYS, NEVER, WHEN_CHECKED_AUTO_SYNC
|
||||||
@ -418,8 +446,6 @@ public class K9 extends Application
|
|||||||
K9.setK9Language(sprefs.getString("language", ""));
|
K9.setK9Language(sprefs.getString("language", ""));
|
||||||
K9.setK9Theme(sprefs.getInt("theme", android.R.style.Theme_Light));
|
K9.setK9Theme(sprefs.getInt("theme", android.R.style.Theme_Light));
|
||||||
MessagingController.getInstance(this).resetVisibleLimits(prefs.getAccounts());
|
MessagingController.getInstance(this).resetVisibleLimits(prefs.getAccounts());
|
||||||
MessageProvider mp = new MessageProvider();
|
|
||||||
mp.setApplication(this);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to give MimeMessage a temp directory because File.createTempFile(String, String)
|
* We have to give MimeMessage a temp directory because File.createTempFile(String, String)
|
||||||
@ -487,9 +513,50 @@ public class K9 extends Application
|
|||||||
broadcastIntent(K9.Intents.EmailReceived.ACTION_EMAIL_RECEIVED, account, folder, message);
|
broadcastIntent(K9.Intents.EmailReceived.ACTION_EMAIL_RECEIVED, account, folder, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void searchStats(final AccountStats stats)
|
||||||
|
{
|
||||||
|
// let observers know a fetch occured
|
||||||
|
K9.this.sendBroadcast(new Intent(K9.Intents.EmailReceived.ACTION_REFRESH_OBSERVER, null));
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* since Android invokes Application.onCreate() only after invoking all
|
||||||
|
* other components' onCreate(), here is a way to notify interested
|
||||||
|
* component that the application is available and ready
|
||||||
|
*/
|
||||||
|
protected void notifyObservers()
|
||||||
|
{
|
||||||
|
for (final ApplicationAware aware : observers)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
aware.initializeComponent(this);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.w(K9.LOG_TAG, "Failure when notifying " + aware, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a component to be notified when the {@link K9} instance is ready.
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* Never <code>null</code>.
|
||||||
|
*/
|
||||||
|
public static void registerApplicationAware(final ApplicationAware component)
|
||||||
|
{
|
||||||
|
if (!observers.contains(component))
|
||||||
|
{
|
||||||
|
observers.add(component);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getK9Language()
|
public static String getK9Language()
|
||||||
|
@ -6,11 +6,8 @@ import java.util.List;
|
|||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.UriMatcher;
|
import android.content.UriMatcher;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.MatrixCursor;
|
import android.database.MatrixCursor;
|
||||||
@ -34,13 +31,212 @@ import com.fsck.k9.mail.store.LocalStore;
|
|||||||
public class MessageProvider extends ContentProvider
|
public class MessageProvider extends ContentProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected interface QueryHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The path this instance is able to respond to.
|
||||||
|
*
|
||||||
|
* @return Never <code>null</code>.
|
||||||
|
*/
|
||||||
|
String getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uri
|
||||||
|
* @param projection
|
||||||
|
* @param selection
|
||||||
|
* @param selectionArgs
|
||||||
|
* @param sortOrder
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
* @see {@link ContentProvider#query(Uri, String[], String, String[], String)}
|
||||||
|
*/
|
||||||
|
Cursor query(Uri uri, String[] projection,
|
||||||
|
String selection, String[] selectionArgs, String sortOrder) throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve messages from the integrated inbox.
|
||||||
|
*/
|
||||||
|
protected class MessagesQueryHandler implements QueryHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return "inbox_messages/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(final Uri uri, final String[] projection, final String selection,
|
||||||
|
final String[] selectionArgs, final String sortOrder) throws Exception
|
||||||
|
{
|
||||||
|
return getMessages(projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param projection
|
||||||
|
* Projection to use. If <code>null</code>, use the default
|
||||||
|
* projection.
|
||||||
|
* @return Never <code>null</code>.
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
protected MatrixCursor getMessages(final String[] projection) throws InterruptedException
|
||||||
|
{
|
||||||
|
// TODO use the given projection if prevent
|
||||||
|
final MatrixCursor cursor = new MatrixCursor(DEFAULT_MESSAGE_PROJECTION);
|
||||||
|
final BlockingQueue<List<MessageInfoHolder>> queue = new SynchronousQueue<List<MessageInfoHolder>>();
|
||||||
|
|
||||||
|
// new code for integrated inbox, only execute this once as it will be processed afterwards via the listener
|
||||||
|
final SearchAccount integratedInboxAccount = new SearchAccount(getContext(), true, null, null);
|
||||||
|
final MessagingController msgController = MessagingController.getInstance(K9.app);
|
||||||
|
|
||||||
|
msgController.searchLocalMessages(integratedInboxAccount, null,
|
||||||
|
new MesssageInfoHolderRetrieverListener(queue));
|
||||||
|
|
||||||
|
final List<MessageInfoHolder> holders = queue.take();
|
||||||
|
|
||||||
|
// TODO add sort order parameter
|
||||||
|
Collections.sort(holders, new MessageList.ReverseComparator<MessageInfoHolder>(
|
||||||
|
new MessageList.DateComparator()));
|
||||||
|
|
||||||
|
int id = -1;
|
||||||
|
for (final MessageInfoHolder holder : holders)
|
||||||
|
{
|
||||||
|
final Message message = holder.message;
|
||||||
|
id++;
|
||||||
|
|
||||||
|
cursor.addRow(new Object[]
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
holder.fullDate,
|
||||||
|
holder.sender,
|
||||||
|
holder.subject,
|
||||||
|
holder.preview,
|
||||||
|
holder.account,
|
||||||
|
holder.uri,
|
||||||
|
CONTENT_URI + "/delete_message/"
|
||||||
|
+ message.getFolder().getAccount().getAccountNumber() + "/"
|
||||||
|
+ message.getFolder().getName() + "/" + message.getUid() });
|
||||||
|
}
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the account list.
|
||||||
|
*/
|
||||||
|
protected class AccountsQueryHandler implements QueryHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return "accounts";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(final Uri uri, String[] projection, String selection,
|
||||||
|
String[] selectionArgs, String sortOrder) throws Exception
|
||||||
|
{
|
||||||
|
return getAllAccounts();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cursor getAllAccounts()
|
||||||
|
{
|
||||||
|
String[] projection = new String[] { "accountNumber", "accountName" };
|
||||||
|
|
||||||
|
MatrixCursor ret = new MatrixCursor(projection);
|
||||||
|
|
||||||
|
for (Account account : Preferences.getPreferences(getContext()).getAccounts())
|
||||||
|
{
|
||||||
|
Object[] values = new Object[2];
|
||||||
|
values[0] = account.getAccountNumber();
|
||||||
|
values[1] = account.getDescription();
|
||||||
|
ret.addRow(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the unread message count for a given account specified by its
|
||||||
|
* {@link Account#getAccountNumber() number}.
|
||||||
|
*/
|
||||||
|
protected class UnreadQueryHandler implements QueryHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return "account_unread/#";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(final Uri uri, String[] projection, String selection,
|
||||||
|
String[] selectionArgs, String sortOrder) throws Exception
|
||||||
|
{
|
||||||
|
List<String> segments = null;
|
||||||
|
int accountId = -1;
|
||||||
|
segments = uri.getPathSegments();
|
||||||
|
accountId = Integer.parseInt(segments.get(1));
|
||||||
|
return getAccountUnread(accountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cursor getAccountUnread(int accountNumber)
|
||||||
|
{
|
||||||
|
String[] projection = new String[] { "accountName", "unread" };
|
||||||
|
|
||||||
|
MatrixCursor ret = new MatrixCursor(projection);
|
||||||
|
|
||||||
|
Account myAccount;
|
||||||
|
AccountStats myAccountStats = null;
|
||||||
|
|
||||||
|
Object[] values = new Object[2];
|
||||||
|
|
||||||
|
for (Account account : Preferences.getPreferences(getContext()).getAccounts())
|
||||||
|
{
|
||||||
|
if (account.getAccountNumber()==accountNumber)
|
||||||
|
{
|
||||||
|
myAccount = account;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
myAccountStats = account.getStats(getContext());
|
||||||
|
values[0] = myAccount.getDescription();
|
||||||
|
values[1] = myAccountStats.unreadMessageCount;
|
||||||
|
ret.addRow(values);
|
||||||
|
}
|
||||||
|
catch (MessagingException e)
|
||||||
|
{
|
||||||
|
Log.e(K9.LOG_TAG, e.getMessage());
|
||||||
|
values[0] = "Unknown";
|
||||||
|
values[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronized listener used to retrieve {@link MessageInfoHolder}s using a
|
||||||
|
* given {@link BlockingQueue}.
|
||||||
|
*/
|
||||||
protected class MesssageInfoHolderRetrieverListener extends MessagingListener
|
protected class MesssageInfoHolderRetrieverListener extends MessagingListener
|
||||||
{
|
{
|
||||||
private final BlockingQueue<List<MessageInfoHolder>> queue;
|
private final BlockingQueue<List<MessageInfoHolder>> queue;
|
||||||
|
|
||||||
private List<MessageInfoHolder> holders = new ArrayList<MessageInfoHolder>();
|
private List<MessageInfoHolder> holders = new ArrayList<MessageInfoHolder>();
|
||||||
|
|
||||||
private MesssageInfoHolderRetrieverListener(BlockingQueue<List<MessageInfoHolder>> queue)
|
/**
|
||||||
|
* @param queue
|
||||||
|
* Never <code>null</code>. The synchronized channel to use
|
||||||
|
* to retrieve {@link MessageInfoHolder}s.
|
||||||
|
*/
|
||||||
|
public MesssageInfoHolderRetrieverListener(BlockingQueue<List<MessageInfoHolder>> queue)
|
||||||
{
|
{
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
}
|
}
|
||||||
@ -51,7 +247,7 @@ public class MessageProvider extends ContentProvider
|
|||||||
{
|
{
|
||||||
for (final Message message : messages)
|
for (final Message message : messages)
|
||||||
{
|
{
|
||||||
holders.add(new MessageInfoHolder(context, message));
|
holders.add(new MessageInfoHolder(getContext(), message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,27 +269,7 @@ public class MessageProvider extends ContentProvider
|
|||||||
|
|
||||||
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
|
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
|
||||||
|
|
||||||
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
|
private static final String[] DEFAULT_MESSAGE_PROJECTION = new String[]
|
||||||
|
|
||||||
private static final int URI_INBOX_MESSAGES = 0;
|
|
||||||
private static final int URI_DELETE_MESSAGE = 1;
|
|
||||||
private static final int URI_ACCOUNTS = 2;
|
|
||||||
private static final int URI_ACCOUNT_UNREAD = 3;
|
|
||||||
|
|
||||||
private static Context context = null;
|
|
||||||
private static boolean mIsListenerRegister = false;
|
|
||||||
|
|
||||||
private static Application mApp;
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
URI_MATCHER.addURI(AUTHORITY, "inbox_messages/", URI_INBOX_MESSAGES);
|
|
||||||
URI_MATCHER.addURI(AUTHORITY, "delete_message/", URI_DELETE_MESSAGE);
|
|
||||||
URI_MATCHER.addURI(AUTHORITY, "accounts", URI_ACCOUNTS);
|
|
||||||
URI_MATCHER.addURI(AUTHORITY, "account_unread/#", URI_ACCOUNT_UNREAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String[] messages_projection = new String[]
|
|
||||||
{
|
{
|
||||||
"id",
|
"id",
|
||||||
"date",
|
"date",
|
||||||
@ -104,115 +280,35 @@ public class MessageProvider extends ContentProvider
|
|||||||
"uri",
|
"uri",
|
||||||
"delUri"
|
"delUri"
|
||||||
};
|
};
|
||||||
MessagingListener mListener = new MessagingListener()
|
|
||||||
{
|
|
||||||
|
|
||||||
public void searchStats(AccountStats stats)
|
/**
|
||||||
{
|
* URI matcher used for
|
||||||
notifyDatabaseModification();
|
* {@link #query(Uri, String[], String, String[], String)}
|
||||||
}
|
*/
|
||||||
};
|
private UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||||
|
|
||||||
public Cursor getAllAccounts()
|
/**
|
||||||
{
|
* Handlers registered to respond to
|
||||||
String[] projection = new String[] { "accountNumber", "accountName" };
|
* {@link #query(Uri, String[], String, String[], String)}
|
||||||
|
*/
|
||||||
MatrixCursor ret = new MatrixCursor(projection);
|
private List<QueryHandler> mQueryHandlers = new ArrayList<QueryHandler>();
|
||||||
|
|
||||||
for (Account account : Preferences.getPreferences(getContext()).getAccounts())
|
|
||||||
{
|
|
||||||
Object[] values = new Object[2];
|
|
||||||
values[0] = account.getAccountNumber();
|
|
||||||
values[1] = account.getDescription();
|
|
||||||
ret.addRow(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cursor getAccountUnread(int accountNumber)
|
|
||||||
{
|
|
||||||
String[] projection = new String[] { "accountName", "unread" };
|
|
||||||
|
|
||||||
MatrixCursor ret = new MatrixCursor(projection);
|
|
||||||
|
|
||||||
Account myAccount;
|
|
||||||
AccountStats myAccountStats = null;
|
|
||||||
|
|
||||||
Object[] values = new Object[2];
|
|
||||||
|
|
||||||
for (Account account : Preferences.getPreferences(getContext()).getAccounts())
|
|
||||||
{
|
|
||||||
if (account.getAccountNumber()==accountNumber)
|
|
||||||
{
|
|
||||||
myAccount = account;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
myAccountStats = account.getStats(getContext());
|
|
||||||
values[0] = myAccount.getDescription();
|
|
||||||
values[1] = myAccountStats.unreadMessageCount;
|
|
||||||
ret.addRow(values);
|
|
||||||
}
|
|
||||||
catch (MessagingException e)
|
|
||||||
{
|
|
||||||
Log.e(K9.LOG_TAG, e.getMessage());
|
|
||||||
values[0] = "Unknown";
|
|
||||||
values[1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplication(Application app)
|
|
||||||
{
|
|
||||||
if (context == null)
|
|
||||||
{
|
|
||||||
context = app.getApplicationContext();
|
|
||||||
}
|
|
||||||
if (app != null)
|
|
||||||
{
|
|
||||||
mApp = app;
|
|
||||||
MessagingController msgController = MessagingController.getInstance(mApp);
|
|
||||||
if ((msgController != null) && (!mIsListenerRegister))
|
|
||||||
{
|
|
||||||
msgController.addListener(mListener);
|
|
||||||
mIsListenerRegister = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreate()
|
public boolean onCreate()
|
||||||
{
|
{
|
||||||
context = getContext();
|
registerQueryHandler(new AccountsQueryHandler());
|
||||||
|
registerQueryHandler(new MessagesQueryHandler());
|
||||||
|
registerQueryHandler(new UnreadQueryHandler());
|
||||||
|
|
||||||
if (mApp != null)
|
return true;
|
||||||
{
|
|
||||||
MessagingController msgController = MessagingController.getInstance(mApp);
|
|
||||||
if ((msgController != null) && (!mIsListenerRegister))
|
|
||||||
{
|
|
||||||
msgController.addListener(mListener);
|
|
||||||
mIsListenerRegister = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int delete(Uri uri, String selection, String[] selectionArgs)
|
public int delete(Uri uri, String selection, String[] selectionArgs)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "delete");
|
|
||||||
|
|
||||||
if (mApp == null)
|
|
||||||
{
|
{
|
||||||
Log.d(K9.LOG_TAG, "K9 not ready");
|
Log.v(K9.LOG_TAG, "delete");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nota : can only delete a message
|
// Nota : can only delete a message
|
||||||
@ -241,21 +337,23 @@ public class MessageProvider extends ContentProvider
|
|||||||
Message msg = null;
|
Message msg = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Folder lf = LocalStore.getLocalInstance(myAccount, mApp).getFolder(folderName);
|
Folder lf = LocalStore.getLocalInstance(myAccount, K9.app).getFolder(folderName);
|
||||||
int msgCount = lf.getMessageCount();
|
int msgCount = lf.getMessageCount();
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
|
{
|
||||||
Log.d(K9.LOG_TAG, "folder msg count = " + msgCount);
|
Log.d(K9.LOG_TAG, "folder msg count = " + msgCount);
|
||||||
|
}
|
||||||
msg = lf.getMessage(msgUid);
|
msg = lf.getMessage(msgUid);
|
||||||
}
|
}
|
||||||
catch (MessagingException e)
|
catch (MessagingException e)
|
||||||
{
|
{
|
||||||
Log.e(K9.LOG_TAG, e.getMessage());
|
Log.e(K9.LOG_TAG, "Unable to retrieve message", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// launch command to delete the message
|
// launch command to delete the message
|
||||||
if ((myAccount != null) && (msg != null))
|
if ((myAccount != null) && (msg != null))
|
||||||
{
|
{
|
||||||
MessagingController.getInstance(mApp).deleteMessages(new Message[] { msg }, mListener);
|
MessagingController.getInstance(K9.app).deleteMessages(new Message[] { msg }, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -274,86 +372,29 @@ public class MessageProvider extends ContentProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
|
public Cursor query(final Uri uri, final String[] projection, final String selection,
|
||||||
|
final String[] selectionArgs, final String sortOrder)
|
||||||
{
|
{
|
||||||
|
final Cursor cursor;
|
||||||
|
|
||||||
if (K9.DEBUG)
|
final int code = mUriMatcher.match(uri);
|
||||||
Log.d(K9.LOG_TAG, "query");
|
|
||||||
|
|
||||||
if (mApp == null)
|
if (code == -1)
|
||||||
{
|
{
|
||||||
Log.d(K9.LOG_TAG, "K9 not ready");
|
throw new IllegalStateException("Unrecognized URI: " + uri);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cursor cursor;
|
try
|
||||||
switch (URI_MATCHER.match(uri))
|
|
||||||
{
|
{
|
||||||
case URI_INBOX_MESSAGES:
|
// since we used the list index as the UriMatcher code, using it
|
||||||
{
|
// back to retrieve the handler from the list
|
||||||
final MatrixCursor mCursor = new MatrixCursor(messages_projection);
|
final QueryHandler handler = mQueryHandlers.get(code);
|
||||||
final BlockingQueue<List<MessageInfoHolder>> queue = new SynchronousQueue<List<MessageInfoHolder>>();
|
cursor = handler.query(uri, projection, selection, selectionArgs, sortOrder);
|
||||||
|
}
|
||||||
// new code for integrated inbox, only execute this once as it will be processed afterwards via the listener
|
catch (Exception e)
|
||||||
SearchAccount integratedInboxAccount = new SearchAccount(getContext(), true, null, null);
|
{
|
||||||
MessagingController msgController = MessagingController.getInstance(mApp);
|
Log.e(K9.LOG_TAG, "Unable to execute query for URI: " + uri, e);
|
||||||
|
return null;
|
||||||
msgController.searchLocalMessages(integratedInboxAccount, null,
|
|
||||||
new MesssageInfoHolderRetrieverListener(queue));
|
|
||||||
|
|
||||||
List<MessageInfoHolder> holders;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
holders = queue.take();
|
|
||||||
}
|
|
||||||
catch (InterruptedException e)
|
|
||||||
{
|
|
||||||
Log.e(K9.LOG_TAG, "Unable to retrieve message list", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(holders, new MessageList.ReverseComparator<MessageInfoHolder>(new MessageList.DateComparator()));
|
|
||||||
|
|
||||||
int id = -1;
|
|
||||||
for (final MessageInfoHolder holder : holders)
|
|
||||||
{
|
|
||||||
final Message message = holder.message;
|
|
||||||
id++;
|
|
||||||
|
|
||||||
mCursor.addRow(new Object[]
|
|
||||||
{
|
|
||||||
id,
|
|
||||||
holder.fullDate,
|
|
||||||
holder.sender,
|
|
||||||
holder.subject,
|
|
||||||
holder.preview,
|
|
||||||
holder.account,
|
|
||||||
holder.uri,
|
|
||||||
CONTENT_URI + "/delete_message/"
|
|
||||||
+ message.getFolder().getAccount().getAccountNumber() + "/"
|
|
||||||
+ message.getFolder().getName() + "/" + message.getUid() });
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor = mCursor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case URI_ACCOUNTS:
|
|
||||||
cursor = getAllAccounts();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case URI_ACCOUNT_UNREAD:
|
|
||||||
|
|
||||||
List<String> segments = null;
|
|
||||||
int accountId = -1;
|
|
||||||
segments = uri.getPathSegments();
|
|
||||||
accountId = Integer.parseInt(segments.get(1));
|
|
||||||
cursor = getAccountUnread(accountId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unrecognized URI:" + uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
@ -364,24 +405,33 @@ public class MessageProvider extends ContentProvider
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "update");
|
{
|
||||||
|
Log.v(K9.LOG_TAG, "update");
|
||||||
|
}
|
||||||
|
|
||||||
//TBD
|
//TBD
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void notifyDatabaseModification()
|
/**
|
||||||
|
* Register a {@link QueryHandler} to handle a certain {@link Uri} for
|
||||||
|
* {@link #query(Uri, String[], String, String[], String)}
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* Never <code>null</code>.
|
||||||
|
*/
|
||||||
|
protected void registerQueryHandler(final QueryHandler handler)
|
||||||
{
|
{
|
||||||
|
if (mQueryHandlers.contains(handler))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mQueryHandlers.add(handler);
|
||||||
|
|
||||||
if (K9.DEBUG)
|
// use the index inside the list as the UriMatcher code for that handler
|
||||||
Log.d(K9.LOG_TAG, "notifyDatabaseModification -> UPDATE");
|
final int code = mQueryHandlers.indexOf(handler);
|
||||||
|
mUriMatcher.addURI(AUTHORITY, handler.getPath(), code);
|
||||||
Intent intent = new Intent(K9.Intents.EmailReceived.ACTION_REFRESH_OBSERVER, null);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
|
|
||||||
context.getContentResolver().notifyChange(CONTENT_URI, null);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user