个人感觉活动文件夹没有什么作用,跟主屏幕部件差不了多少,而且在avd (target:Android4.0.3)中没有找到活动文件夹,我在此avd的主页空白处进行长单击,看到的不是上下文菜单,而是选择桌面墙纸。今天发现在它妈的avd(target:Android2.1)还是存在可以找到活动文件夹的。这里就简单总结一下活动文件夹,以备忘吧。
Android中的活动文件夹对Content Provider的作用就相当于RSS阅读器对发布网站的作用。
项目结构:
项目源码:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wl" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".SimpleActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
<!-- LIVE FOLDERS--> <activity android:name=".AllContactsLiveFolderCreatorActivity" android:label="New live folder" android:icon="@drawable/ic_launcher"> <intent-filter> <action android:name="android.intent.action.CREATE_LIVE_FOLDER"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> <provider android:authorities="com.ai.livefolder.contacts" android:multiprocess="true" android:name=".MyContactsProvider"></provider> </application> </manifest>
AllContactsLiveFolderCreatorActivity.java:担当活动文件夹的生成程序或创造程序。
package com.wl; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.LiveFolders; public class AllContactsLiveFolderCreatorActivity extends Activity{ protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); final Intent intent = getIntent(); final String action = intent.getAction(); if(LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)){ setResult(RESULT_OK, createLiveFolder(MyContactsProvider.CONTACT_URI, "Contact LF", R.drawable.ic_launcher)); }else{ setResult(RESULT_CANCELED); } finish(); } private Intent createLiveFolder(Uri uri, String name, int icon){ final Intent intent = new Intent(); intent.setData(uri); intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, name); intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON, Intent.ShortcutIconResource.fromContext(this, icon)); intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST); return intent; } }
MyContactsProvider.java:一个Content Provider
package com.wl; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.MatrixCursor; import android.net.Uri; import android.provider.BaseColumns; import android.provider.ContactsContract; import android.provider.LiveFolders; import android.util.Log; public class MyContactsProvider extends ContentProvider{ public static final String AUTHORITY = "com.ai.livefolder.contacts"; public static final Uri CONTACT_URI = Uri.parse("content://" + AUTHORITY + "/contacts"); private static final int TYPE_MY_URI = 0; private static final UriMatcher URI_MATCHER; static{ URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); URI_MATCHER.addURI(AUTHORITY, "contacts", TYPE_MY_URI); } @Override public int bulkInsert(Uri arg0, ContentValues[] values){ return 0; } private static final String[] CURSOR_COLUMNS = new String[]{ BaseColumns._ID, LiveFolders.NAME, LiveFolders.DESCRIPTION, LiveFolders.INTENT, LiveFolders.ICON_PACKAGE, LiveFolders.ICON_RESOURCE }; private static final String[] CURSOR_ERROR_COLUMNS = new String[]{ BaseColumns._ID, LiveFolders.NAME, LiveFolders.DESCRIPTION }; private static final Object[] ERROR_MESSAGE_ROW = new Object[]{ -1, "No contacts found", "Check your contacts database" }; private static MatrixCursor sErrorCursor = new MatrixCursor(CURSOR_ERROR_COLUMNS); static{ sErrorCursor.addRow(ERROR_MESSAGE_ROW); } private static final String[] CONTACTS_COLUMN_NAMES = new String[]{ ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.TIMES_CONTACTED, ContactsContract.Contacts.STARRED }; public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){ int type = URI_MATCHER.match(uri); if(type == UriMatcher.NO_MATCH){ return sErrorCursor; } Log.i("ss", "query called"); try{ MatrixCursor mc = loadNewData(this); mc.setNotificationUri(getContext().getContentResolver(), Uri.parse("content://contacts/people/")); MyCursor wmc = new MyCursor(mc, this); return wmc; } catch(Throwable e){ return sErrorCursor; } } public static MatrixCursor loadNewData(ContentProvider cp){ MatrixCursor mc = new MatrixCursor(CURSOR_COLUMNS); Cursor allContacts = null; try{ allContacts = cp.getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_COLUMN_NAMES, null, null, ContactsContract.Contacts.DISPLAY_NAME); while(allContacts.moveToNext()){ String timesContacted = "Times contacted: " + allContacts.getInt(2); Object[] rowObject = new Object[]{ allContacts.getLong(0), allContacts.getString(1), timesContacted, Uri.parse("content://contacts/people/" + allContacts.getLong(0)), cp.getContext().getPackageName(), R.drawable.ic_launcher }; mc.addRow(rowObject); } return mc; } finally{ allContacts.close(); } } @Override public int delete(Uri arg0, String arg1, String[] arg2) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri arg0) { // TODO Auto-generated method stub return ContactsContract.Contacts.CONTENT_TYPE; } @Override public Uri insert(Uri arg0, ContentValues arg1) { // TODO Auto-generated method stub return null; } @Override public boolean onCreate() { // TODO Auto-generated method stub return true; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { // TODO Auto-generated method stub return 0; } }
MyCursor.java:对MatrixCursor的包装
package com.wl; import android.content.ContentProvider; import android.database.MatrixCursor; public class MyCursor extends BetterCursorWrapper{ private ContentProvider mcp = null; public MyCursor(MatrixCursor mc, ContentProvider inCp){ super(mc); mcp = inCp; } public boolean requery(){ MatrixCursor mc = MyContactsProvider.loadNewData(mcp); this.setInternalCursor(mc); return super.requery(); } }
BetterCursorWrapper.java
package com.wl; import android.content.ContentResolver; import android.database.CharArrayBuffer; import android.database.ContentObserver; import android.database.CrossProcessCursor; import android.database.CursorWindow; import android.database.DataSetObserver; import android.net.Uri; import android.os.Bundle; public class BetterCursorWrapper implements CrossProcessCursor{ protected CrossProcessCursor internalCursor; public BetterCursorWrapper(CrossProcessCursor inCursor){ this.setInternalCursor(inCursor); } public void setInternalCursor(CrossProcessCursor inCursor){ this.internalCursor = inCursor; } public void fillWindow(int arg0, CursorWindow arg1){ internalCursor.fillWindow(arg0, arg1); } public void close() { internalCursor.close(); } public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { internalCursor.copyStringToBuffer(columnIndex, buffer); } public void deactivate() { internalCursor.deactivate(); } public byte[] getBlob(int columnIndex) { return internalCursor.getBlob(columnIndex); } public int getColumnCount() { return internalCursor.getColumnCount(); } public int getColumnIndex(String columnName) { return internalCursor.getColumnIndex(columnName); } public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException { return internalCursor.getColumnIndexOrThrow(columnName); } public String getColumnName(int columnIndex) { return internalCursor.getColumnName(columnIndex); } public String[] getColumnNames() { return internalCursor.getColumnNames(); } public int getCount() { return internalCursor.getCount(); } public double getDouble(int columnIndex) { return internalCursor.getDouble(columnIndex); } public Bundle getExtras() { return internalCursor.getExtras(); } public float getFloat(int columnIndex) { return internalCursor.getFloat(columnIndex); } public int getInt(int columnIndex) { return internalCursor.getInt(columnIndex); } public long getLong(int columnIndex) { return internalCursor.getLong(columnIndex); } public int getPosition() { return internalCursor.getPosition(); } public short getShort(int columnIndex) { return internalCursor.getShort(columnIndex); } public String getString(int columnIndex) { return internalCursor.getString(columnIndex); } public boolean getWantsAllOnMoveCalls() { return internalCursor.getWantsAllOnMoveCalls(); } public CursorWindow getWindow() { return internalCursor.getWindow(); } public boolean isAfterLast() { return internalCursor.isAfterLast(); } public boolean isBeforeFirst() { return internalCursor.isBeforeFirst(); } public boolean isClosed() { return internalCursor.isClosed(); } public boolean isFirst() { return internalCursor.isFirst(); } public boolean isLast() { return internalCursor.isLast(); } public boolean isNull(int columnIndex) { return internalCursor.isNull(columnIndex); } public boolean move(int offset) { return internalCursor.move(offset); } public boolean moveToFirst() { return internalCursor.moveToFirst(); } public boolean moveToLast() { return internalCursor.moveToLast(); } public boolean moveToNext() { return internalCursor.moveToNext(); } public boolean moveToPosition(int position) { return internalCursor.moveToPosition(position); } public boolean moveToPrevious() { return internalCursor.moveToPrevious(); } public boolean onMove(int oldPosition, int newPosition) { return internalCursor.onMove(oldPosition, newPosition); } public void registerContentObserver(ContentObserver observer) { internalCursor.registerContentObserver(observer); } public void registerDataSetObserver(DataSetObserver observer) { internalCursor.registerDataSetObserver(observer); } public boolean requery() { return internalCursor.requery(); } public Bundle respond(Bundle extras) { return internalCursor.respond(extras); } public void setNotificationUri(ContentResolver cr, Uri uri) { internalCursor.setNotificationUri(cr, uri); } public void unregisterContentObserver(ContentObserver observer) { internalCursor.unregisterContentObserver(observer); } public void unregisterDataSetObserver(DataSetObserver observer) { internalCursor.unregisterDataSetObserver(observer); } }
SimpleActivity.java:
package com.wl; import android.app.Activity; import android.os.Bundle; public class SimpleActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>