1. 程式人生 > >meta-data介紹

meta-data介紹

簡介-meta是什麼

meta-data是應用的清單檔案AndroidManifest.xmlapplication,activity,activity-alias,provider,receiver,service下的子標籤,比intent-filter多些父標籤.像友盟這些統計服務一般只需要一個AppID等,只需要定義在Application中,如果你想給某個元件新增meta-data,那麼meta-data必須定義在其元件申明內。

基礎使用

事實上,meta-data我們拿到的時候是一個Bundle,知道了這一點,我們就可以不畏懼它了,不信你看。

public Bundle metaData;

先看一下應用場景,在Application中定義APPID, 我們也可以直接給一個resource給meta-data

    <application
        ....
        <meta-data
            android:name="jerey"
            android:value="sdf123456">
        </meta-data>
    </application>

獲取Application中的meta-data方法:

    ApplicationInfo appInfo = null;
    appInfo = this.getPackageManager()
                  .getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
    Bundle bundle = appInfo.metaData;
    Log.i(TAG, "bundle.getString(jerey) : " + bundle.getString("jerey"));

可以看到列印為:

I/MainActivity: bundle.getString("jerey") : sdf123456

若我們像下面這種方式使用:

    <string-array name="test1">
        <item>test1_hello</item>
        <item>test1_hello2</item>
    </string-array>
    
    <meta-data
        android:name="test_array"
        android:resource="@array/test1">
    </meta-data>

在獲取時,獲取到的是id,R.id的id,我們還需要getResource.get...去獲取。我們測試一下:

    int id = bundle.getInt("test_array");
    String[] aString = getResources().getStringArray(id);
    for (int i = 0; i < aString.length; i++) {
        Log.i(TAG, "onCreate: " + aString[i]);
    }

logcat可以看到:

10-17 15:57:55.966 5247-5247/avatar.com.demos I/MainActivity: onCreate: test1_hello
10-17 15:57:55.966 5247-5247/avatar.com.demos I/MainActivity: onCreate: test1_hello2

既然知道了如何獲取Application中的引數,那麼其他的也如出一轍。

    //在Activity應用<meta-data>元素。
    ActivityInfo info = this.getPackageManager()
                            .getActivityInfo(getComponentName(),PackageManager.GET_META_DATA);  
    info.metaData.getString("meta_name"); 
    
    //在service應用<meta-data>元素。 
    ComponentName cn = new ComponentName(this, ×××Service.class);
    ServiceInfo info = this.getPackageManager().getServiceInfo(cn, PackageManager.GET_META_DATA); 
    info.metaData.getString("meta_name"); 
   
    //在receiver應用<meta-data>元素。
    ComponentName cn = new ComponentName(context, ×××Receiver.class); 
    ActivityInfo info = context.getPackageManager().getReceiverInfo(cn, PackageManager.GET_META_DATA); 
    info.metaData.getString("meta_name"); 

擴充套件應用-配合PackageManager

舉一個擴充套件應用場景,我們都知道,Android系統的多應用開啟功能,即比如你有三個瀏覽器,那麼我們傳送一個url的時候,如果沒有預設瀏覽器,會讓我們選擇一個瀏覽器。

    Intent intent = new Intent();        
    intent.setAction("android.intent.action.VIEW");   
    Uri content_url = Uri.parse("https://www.baidu.com");   
    intent.setData(content_url);  
    startActivity(intent);

現在我們喜歡,彈出的選擇介面多一點介紹,每個能夠接收這個Action的應用都能夠做一下自我介紹,在選擇的介面上下面顯示小字提示。

這個需求,我們肯定不是說提前記住每個應用的介紹,並且這種肯定是要控制反轉,即每個應用單獨提供自己的介紹的。這個時候meta-data就起到作用了,我們可以讓每個做公共跳轉的應用的Activity都新增一個叫titlemeta-data,那麼我們就能獲取到它,怎麼獲取呢,看下面操作,(我居然能突然奇想到這個例子,OMG)

操作1,利用PackageManager查詢Intent的功能,這個功能常用來判斷一個Intent是否有接收者的,比如從相簿選擇圖片,為了防止沒有相簿往往會做這樣的判斷。

Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES);

拿到List<ResolveInfo> activities,接下來幹什麼?

        for (ResolveInfo info : activities) {
            ActivityInfo mActivityInfo = info.activityInfo;
            mActivityInfo.packageName;
            mActivityInfo.name;
            Bundle data = info.activityInfo.metaData;
        }

我們拿到了應用的ActivityInfo,以及對應的meta-data,上述需求基本上算沒有難度了。

像上述拿其他應用的meta-data,看上去沒有什麼應用場景,但是有些時候可以幹很多出奇的事情的。