技术开发 频道

实战:Android活动目录LiveFolder开发

  LiveFolder的实现

  本节中的LiveFolder Sample程序实现了一个活动目录,增加后将在桌面出现一个图标。点击这个活动目录在桌面的图标,将在LiveFolder的列表框中显示一些内容。LiveFolder Sample的执行效果如图8-5所示。

  图8-5中右图的列表项对话框共有8个项目,进一步点击每一个项目,还将出现浏览器显示空(blank)的网页。

  LiveFolder Sample实现的AndroidMenifest.xml中定义的一个用于创建LiveFolder 的Activity和一个显示内容的ContentProvider,如下所示:

<activity android:name="LiveFolderSample"  
    android:icon
="@drawable/app_icon" android:label="LiveFolder Sample">
    
<intent-filter>    
        
<action android:name="android.intent.action.CREATE_LIVE_FOLDER" />
        
<category android:name="android.intent.category.DEFAULT" />
    
</intent-filter>
</activity>
<provider android:name="LiveFolderSampleProvider"
            android:authorities
="livefoldersample"/>

 


▲图8-5 LiveFolder Sample(左:增加界面;中:LiveFolder的桌面图标;右:启动对话框)

  这里声明的Activity支持“android.intent.action.CREATE_LIVE_FOLDER”动作,表示可以用它来创建活动目录,也就是可能在活动目录的增加列表中出现它这个项目。

public class LiveFolderSample extends Activity {
    
private static final String URI  =   // ContentProvider的URI
              
"content://" + "livefoldersample" + "/live_folders/virtual";
    
private static final Uri CONTENT_URI = Uri.parse(URI);
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final Intent intent
= getIntent();        // 获得其中的Intent
        final
String action = intent.getAction();
        
if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
            final Intent liveFolderIntent
= new Intent();   // 返回结果中的Intent
            final Intent urlIntent  
=
                      
new Intent(Intent.ACTION_VIEW,Uri.parse("about://blank"));
            returnIntent.setData(CONTENT_URI);  
// Intent中的URI  
            returnIntent.putExtra(                
// LiveFolder对话框的名称
                    LiveFolders.EXTRA_LIVE_FOLDER_NAME,
"LiveFolderSample");
            returnIntent.putExtra(              
// LiveFolder的图标
                 LiveFolders.EXTRA_LIVE_FOLDER_ICON,Intent.ShortcutIconResource.
                                  fromContext(this,R.drawable.app_icon));
            returnIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
                    LiveFolders.DISPLAY_MODE_LIST);
            returnIntent.putExtra(              
// LiveFolder中的每个内容Intent
                        LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT,urlIntent);
            setResult(RESULT_OK, returnIntent);
// 设置返回结果
        }
else { setResult(RESULT_CANCELED);  }
        finish();
    }
}

 

  在创建LiveFolder的过程中,涉及两个Intent。returnIntent是Activity返回的效果,在其中通过额外参数指定图标和活动目录的名称,其中主要的内容是指向ContentProvider的URI,并定义了其中的图标和名称。

  返回内容returnIntent的一个特殊的域为urlIntent,也是一个Intent,它表示每一个项目被点击之后启动Activity的Intent。在这里将它定义为Intent.ACTION_VIEW 动作和以“about://blank”表示的Intent。当点击LiveFolder中的每一个项目的时候,将调用相应的程序(实际上是浏览器),对应的URI为“about://blank”再附加上每个内容的id。

  这里的ContentProvider的实现内容如下所示:

public class LiveFolderSampleProvider extends ContentProvider {
    
private static final int VIRTUAL = 1;        // 各个项目的id
    
private static final int VIRTUAL_ID = 2;
    
private static final int LIVE_FOLDER_SAMPLE = 3;
    
public static final String AUTHORITY = "livefoldersample";    // URI
    
private static final UriMatcher sUriMatcher;
    static {
        sUriMatcher
= new UriMatcher(UriMatcher.NO_MATCH);         // 建立匹配器
        sUriMatcher.addURI(AUTHORITY,
"virtual/", VIRTUAL);
        sUriMatcher.addURI(AUTHORITY,
"virtual/#", VIRTUAL_ID);
        sUriMatcher.addURI(AUTHORITY,
"live_folders/virtual", LIVE_FOLDER_SAMPLE);
    }
// ...... 省略部分内容:query()方法的实现
    @Override
public String getType(Uri uri) {  // 获取类型的实现
        switch (sUriMatcher.match(uri)) {
            
case VIRTUAL:
            
case VIRTUAL_ID:
                return
"";
            
case LIVE_FOLDER_SAMPLE:
                return
"";            
            default:
                throw
new IllegalArgumentException("Unknown URI " + uri);
        }
    }
    @Override
public boolean onCreate() { return true; }
    @Override
public Uri insert(Uri uri, ContentValues initialValues) {
        return
null;      // LiveFolder不要求实现insert()
    }
    @Override
public int delete(Uri uri, String where, String[] whereArgs) {
        return
0;          // LiveFolder不要求实现delete()
    }
    @Override  
public int update(Uri uri, ContentValues values,
                                      
String where, String[] whereClause) {
        return
0;          // LiveFolder不要求实现update()
    }
}

 

  对于为LiveFolder使用的ContentProvider,需要实现getType()方法,而其他方法不是必需的,如果要实现,可以在其他的地方对ContentProvider进行操作。

  query()方法的实现是主要的内容,如下所示:

   @Override public Cursor query(Uri uri, String[] projection, String selection,
                                        
String[] selectionArgs,String sortOrder) {
        switch (sUriMatcher.match(uri)) {  
// 查询操作的匹配
            
case VIRTUAL:                       // 不返回实际内容
            
case VIRTUAL_ID:
                return
null;
            
case LIVE_FOLDER_SAMPLE:
                return getLivefolder();  
// 调用返回内容
            default:
                throw
new IllegalArgumentException("Unknown URI " + uri);
        }
    }
    
private Cursor getLivefolder() {   // 返回具体的内容
        
int i = 0;
        
String[] columnNames = {LiveFolders._ID,LiveFolders.NAME};     // 2个必要的列
        
String[] temp = {"",""};
        MatrixCursor c
= new MatrixCursor(columnNames);
        
for(i = 0 ;i < 8;i++){          // 循环返回8个项目
            temp[
0] = String.valueOf(i);                                     // _ID的内容
            temp[
1] = LiveFolders.NAME + " = " + String.valueOf(i);    // NAME的内容
            c.addRow(temp);
        }
        return c;  
    }

 

  在查询返回的时候,实际上只有一个项有效,联系ContentProvider和LiveFolder创建者的是名称为“content://livefoldersample/live_folders/virtual”的URI。

  查询返回具有两列的内容,其中第一列为_ID,第二列为NAME。前者表示每列的id,这是必须具有的,后者也就是反映在LiveFolder对话框中的每个项目显示的内容。

  由于在这里没有为每个项目设置Intent域(LiveFolders.INTENT),因此每个项目在被选择之后将根据LiveFolder的创建者中设置的Intent附加上每个项目的id,作为启动的内容。例如,点击第2个项目将打开名称为“about://blank/1”的地址的空网页。

0
相关文章