總網頁瀏覽量

關於我自己

我的相片
人生的必修課是接受無常,人生的選修課是放下執著。
顯示具有 PackageManager 標籤的文章。 顯示所有文章
顯示具有 PackageManager 標籤的文章。 顯示所有文章

2012年3月14日 星期三

查詢&開啟應用程式列表 - getInstalledApplications & getLaunchIntentForPackage (二)

在此範例加入AP icon的資訊, 會讓user更容易辨識要尋找的AP


新增
./res/layout/layout_gv_item.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" >

    <ImageView
        android:id="@+id/adapter_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
  
    <TextView
        android:id="@+id/adapter_tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>

因GridView中不只包含一個TextView資訊←可以用android.R.layout.simple_list_item_1
而是每個Item有TextView及ImageView←故建立一個類別extends BaseAdapter
./src/com.tsots.allap/GVAdapter.java
package com.tsots.allap;

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class GVAdapter extends BaseAdapter 
{
    LayoutInflater mInflater;
    ArrayList<String> adapter_apName;
    ArrayList<Bitmap> adapter_apIcon;

    public GVAdapter(Context context, ArrayList<String> list_apName, ArrayList<Bitmap> list_apIcon)
    {
        mInflater = LayoutInflater.from(context);
        adapter_apName = list_apName;
        adapter_apIcon = list_apIcon;
    }

    @Override
    public int getCount() {
        return adapter_apIcon.size();
    }

    @Override
    public Object getItem(int position) {
        return adapter_apIcon.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
       
        convertView = mInflater.inflate(R.layout.layout_gv_item,null);
        ImageView adapter_iv = (ImageView) convertView.findViewById (R.id.adapter_iv);
        TextView adapter_tv = (TextView) convertView.findViewById (R.id.adapter_tv);
        adapter_iv.setImageBitmap(adapter_apIcon.get(position));
        adapter_tv.setText(adapter_apName.get(position).toString());
        return convertView;
    }
}

主程式部份則多抓一個ApplicationInfo.loadIcon(packageManager)=AP icon的值
./src/com.tsots.allap/Activity_ALLAP.java
GVAdapter gvadapter;
gvadapter = new GVAdapter(context, list_apName, list_apIcon);
GridView gridView1;
gridView1 = (GridView) findViewById (R.id.gridView1);
PackageManager packageManager = context.getPackageManager();
//取得Device中包括系統預設與手動安裝的所有AP
List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
for(int i = 0 ; i <allappInfo.size() ; i ++)
{
            ApplicationInfo appAI = allappInfo.get(i);
            //取得Device中可以Launch的AP
            Intent intent = packageManager.getLaunchIntentForPackage(appAI.packageName);
            if (intent != null)
            {
                String finalAPName = appAI.loadLabel(packageManager).toString();
                Drawable drawableAPIcon = appAI.loadIcon(packageManager);   
                // ApplicationInfo取得的icon為Drawable, 需轉成Bitmap            
                Bitmap bitmapAPIcon = DrawableToBitmap(drawableAPIcon);
                // 調整icon為相同pixel
                Bitmap finalAPicon = fixSize(bitmapAPIcon);
                list_apName.add(finalAPName);
                list_apIcon.add(finalAPicon);
            }
}

gvadapter = new GVAdapter(context, list_apName, list_apIcon);
gridView1.setAdapter(gvadapter);

public Bitmap DrawableToBitmap(Drawable drawableAPIcon)
{
            BitmapDrawable  bd = (BitmapDrawable)drawableAPIcon;
            Bitmap bitmapAPIcon = bd.getBitmap();

        return bitmapAPIcon;
}

public Bitmap fixSize(Bitmap bitmapAPIcon)
{
        int iconWidth = 0;
        int iconHeight = 0;
        int newIconWidth = 100;
        int newIconHeight = 100;
        iconWidth = bitmapAPIcon.getWidth();
        iconHeight = bitmapAPIcon.getHeight();
        float scaleIconWidth = ((float) newIconWidth) / iconWidth;
        float scaleIconHeight = ((float) newIconHeight) / iconHeight;
        Matrix iconMatrix = new Matrix();
        iconMatrix.postScale(scaleIconWidth, scaleIconHeight);
        Bitmap finalAPicon = Bitmap.createBitmap(bitmapAPIcon, 0, 0,iconWidth, iconHeight, iconMatrix, true);
        return finalAPicon;
}

2012年3月3日 星期六

區分系統AP & 手動AP

==========================第1層:抓出所有AP==========================
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);       
for(int i = 0 ; i <allappInfo.size() ; i ++)
{  
    //appPI取得如ApplicationInfo{2ad14680 com.android.launcher}的資訊              
    ApplicationInfo appPI = allappInfo.get(i); 
}

=======================第2層:可以被launch的AP=======================
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
for(int i = 0 ; i <allappInfo.size() ; i ++)
{
    ApplicationInfo appPI = allappPagInfo.get(i);
    Intent intent = packageManager.getLaunchIntentForPackage(appPI.packageName);
    //如果沒有android.intent.action.MAIN←launch進入點, 則intent=null
    if (intent != null)
    {
        //appPI2會抓到可以被launch的AP資訊
        ApplicationInfo appPI2 = allappPagInfo.get(i);
    }
}

========================第3層:只需要系統或手動AP========================
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
for(int i = 0 ; i <allappInfo.size() ; i ++)
{
    ApplicationInfo appAI = allappInfo.get(i);
    Intent intent = packageManager.getLaunchIntentForPackage(appAI.packageName);
    if (intent != null)
    {
        //位於/system/app/的AP → FLAG_SYSTEM>0
        if ((appAI.flags & appAI.FLAG_SYSTEM) > 0)
        {
            //appPI2只會抓到可以被launch的系統AP資訊
            ApplicationInfo appPI2 = allappInfo.get(i);
        }
        else
        {
            //appPI3只會抓到可以被launch的手動AP資訊
            ApplicationInfo appPI3 = allappInfo.get(i);
        }
    }
}

以(ApplicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)的值來判別,
該值大於0時,表示取得的AP為系統預設(整合在Image中, 放在system/app/),
該值小於等於0時, 表示取得的AP為之後安裝的(未整合在Image中, 放在data/app/)

2012年3月2日 星期五

過濾掉無法launch的AP & 按AP Name英文字母排序

+++++++++++++++++++++++++過濾掉無法launch的AP++++++++++++++++++++++++++++++++++++++

一個 Activity 基本上要在 AndroidManifest.xml 的<intent-filter>中註冊一個 action 和 category; 
        <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
action.MAIN指該 Activity 是個AP的進入點=開啟後的第一個畫面;
category.LAUNCHER指在應用程式選單上會出現該 Activity 的 icon,以方便執行。
當搜尋系統中的應用程式時,會去比對AP的 <intent-filter>,而搜尋條件是包裝在 Intent 物件中以找到符合某種條件程式。

<intent-filter>的內容就像是應用程式的索引,內容比對成功就會回傳相對應的 ResolveInfo
一個應用程式中,可以有多個 Activity 都註冊 CATEGORY_LAUNCHER,那在安裝完後就會有多個 icon 出現在程式選單上,分別能執行各個 Activity。如果 Activity 沒有註冊 CATEGORY_LAUNCHER,那至少要註冊 CATEGORY_DEFAULT,因為它是系統使用 Intent 搜尋的預設條件之一。註冊 CATEGORY_DEFAULT 後該 Activity 不會有 icon 在應用程式選單上出現


 
ArrayList<ApplicationInfo> appCanLaunch = new ArrayList<ApplicationInfo>();
for (ApplicationInfo apAICanLaunch : allappInfo)
{
    Intent intent = packageManager.getLaunchIntentForPackage(apAICanLaunch.packageName);
    //Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }
    //如果沒有android.intent.action.MAIN←launch進入點, 則intent=null
    if (intent != null)
    {
        appCanLaunch.add(apAICanLaunch);
    }
}

輸出結果:
Calculator
Dev Tools
Calendar
Browser
Email
Downloads
Clock

++++++++++++++++++++按AP英文字母排序後, 再過濾掉無法launch的AP+++++++++++++++++++++++++

PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
Collections.sort(allappInfo, new ApplicationInfo.DisplayNameComparator(packageManager));
ArrayList<ApplicationInfo> appCanLaunch = new ArrayList<ApplicationInfo>();
for (ApplicationInfo apAICanLaunch : allappInfo)
{
    Intent intent = packageManager.getLaunchIntentForPackage(apAICanLaunch.packageName);
    //Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }
    //如果沒有android.intent.action.MAIN←launch進入點, 則intent=null
    if (intent != null)
    {
        appCanLaunch.add(apAICanLaunch);
    }
}

輸出結果:
Browser
Calculator
Calendar
Clock
Dev Tools
Downloads
Email

部份參考文獻:http://www.dotblogs.com.tw/neil/archive/2011/08/12/33058.aspx

2012年2月29日 星期三

偵測APK install / uninstall 所發出的Broadcast事件

當有AP被install / uninstall時,
系統會發出Broadcast :ACTION_PACKAGE_ADDED / ACTION_PACKAGE_REMOVED,
假設我們在APP List的畫面中,
希望能"即時"的在AP有新增/移除時變更於Activity,
就需要建立BroadcastReceiver

=======================方法一:不用新增class也不用在Manifest.xml中宣告=======================
@Override
protected void onResume()
{
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_PACKAGE_ADDED);     //只能接收用adb install的安裝事件
    filter.addAction(Intent.ACTION_PACKAGE_REMOVED);//只能接收用adb uninstall的反安裝事件
    filter.addDataScheme("package");
    mIntentReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {               
            final String action = intent.getAction();
            if (Intent.ACTION_PACKAGE_ADDED.equals(action))
            {               

                Uri data = intent.getData();
                String pkgName = data.getEncodedSchemeSpecificPart();
                //pkgName被安裝AP的package name, 在存入SQLite時必須要的資訊

                queryAPInfo();
                Toast.makeText(context, "ACTION_PACKAGE_ADDED", Toast.LENGTH_SHORT).show();
            }
            else if (Intent.ACTION_PACKAGE_REMOVED.equals(action))
           {
                queryAPInfo();
                Toast.makeText(context, "ACTION_PACKAGE_REMOVED", Toast.LENGTH_SHORT).show();
            }
        }
    };       
registerReceiver(mIntentReceiver, filter);

super.onResume();
}

@Override
protected void onPause()
{
    context.unregisterReceiver(mIntentReceiver);
    super.onPause();
}

//改一下queryAPInfo()
//此function所做的: 重新查一遍package的資料, 並setAdapter()更新畫面
public void ArrayList<String> queryAPInfo()
{
    for(int i = 0 ; i <allappPagInfo.size() ; i ++)
    {              
        list_apPag = new ArrayList<String>();
        list_apName = new ArrayList<String>(); 
        PackageInfo appPI = allappPagInfo.get(i); //PackageInfo{2ad3d2e0 com.android.launcher}
        String apPag = appPI.packageName;         //com.android.launcher
        list_apPag.add(apPag);
        String apName = appPI.applicationInfo.loadLabel(packageManager).toString(); //Launcher
        list_apName.add(apName);   
    }
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list_apName);
    GridView gridView1 = (GridView) findViewById (R.id.gridView1);
    gridView1.setAdapter(adapter);
}

 =======================方法二:新增class且要在Manifest.xml中宣告=======================
1. adb uninstall
2. User在Device上操作解除安裝
都可以偵測到 
./AndroidManifest.xml
<receiver android:name=".PackageReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_ADDED" />
        <action android:name="android.intent.action.PACKAGE_REMOVED" />
        <data android:scheme="package" />
     </intent-filter>
</receiver>

./src/com.tsots.AppManager/Activity.java
package com.tsots.AppManager;
public class Activity extends Activity
{
    protected void onCreate(Bundle icicle) 
    {
        .....
    }

    @Override
    protected void onResume()
    {
        PackageReceiver BRC = new PackageReceiver();
        IntentFilter mFilter1, mFilter2;
        //過濾PACKAGE_ADDED與PACKAGE_REMOVED事件
        mFilter1 = new IntentFilter(BRC.addpk_ACTION);
        mFilter2 = new IntentFilter(
BRC.removepk_ACTION);
        mFilter1.addDataScheme("package");
        mFilter2.addDataScheme("package");
        //註冊Receiver     
        registerReceiver(BRC, mFilter1);
        registerReceiver(BRC, mFilter2);

        super.onResume();
    }

    public class PackageReceiver extends BroadcastReceiver
    {
        private static final String addpk_ACTION = "android.intent.action.PACKAGE_ADDED";
        private static final String removepk_ACTION = "android.intent.action.PACKAGE_REMOVED";       
 
        @Override
        public void onReceive(Context context, Intent intent)
        {
            if (intent.getAction().equals(addpk_ACTION))
            {       
                Uri data = intent.getData();
                String pkgName = data.getEncodedSchemeSpecificPart();

                //pkgName為package名稱
                Intent iSend = new Intent(addpk_ACTION);

                //送出廣播 
                context.sendBroadcast(iSend);
            }         
            else if (intent.getAction().equals(removepk_ACTION))
            {               
                Uri data = intent.getData();
                String pkgName = data.getEncodedSchemeSpecificPart();

                //pkgName為package名稱 
                Intent iSend = new Intent(removepk_ACTION);

                //送出廣播
                context.sendBroadcast(iSend);
            }
        }
    }

}

2012年2月25日 星期六

查詢&開啟應用程式列表 - getInstalledApplications & getLaunchIntentForPackage (一)

因為是教學範例, 所以用GridView抓個預設的android.R.layout.simple_list_item_1←欄位樣式來放我們所需的資料

./res/layout/allap.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" />

    <GridView
        android:id="@+id/gridView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="2" >
    </GridView>

</LinearLayout>


./src/com.tsots.allap/Activity_ALLAP.java
package com.tsots.allap;

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.Toast;

public class Activity_ALLAP extends Activity {
    Context context = Activity_ALLAP.this;
    GridView gridView1;
    PackageManager packageManager;
    List<ApplicationInfo> allappInfo;
    ArrayList<String> list_apPag = new ArrayList<String>();
    ArrayList<String> list_apName = new ArrayList<String>();
    ArrayAdapter<String> adapter;
    AdapterView.OnItemClickListener mClickListener;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_allap);
       
        gridView1 = (GridView) findViewById (R.id.gridView1);
        packageManager =context.getPackageManager();
        //取得Device中包括系統預設與手動安裝的所有AP
        allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
        queryAPInfo();            

        adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list_apName);
        gridView1.setAdapter(adapter);       
        clickAction();      
        gridView1.setOnItemClickListener(mClickListener);
    }
   
    public ArrayList<String> queryAPInfo()
    {
        for(int i = 0 ; i <allappInfo.size() ; i ++)
        {                
            ApplicationInfo appPI = allappInfo.get(i);//ApplicationInfo{2ad3d2e0 com.android.launcher}
            String apPag = appPI.packageName;         //com.android.launcher
            list_apPag.add(apPag);
            String apName = appPI.loadLabel(packageManager).toString();//Launcher
            list_apName.add(apName);    
        }
        return list_apName;
    }
   
    /*
     *  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     *  有此行程式可將不同的activity看成好像是同一個應用程式
     *  當你從主activity跳至另一個activity(此activity早己存在於系統之中)
     *  當你按下"back"後它會跳回主activity
     *  如果沒加入此程式當按下"back"後它則會離開主activity       
     */
    public void clickAction()
    {
        mClickListener = new AdapterView.OnItemClickListener ()
        {
            public void onItemClick(AdapterView parent, View v, int position, long id)
            {
                Intent intent = getPackageManager().getLaunchIntentForPackage(list_apPag.get(position));
                try
                {
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
                catch(NullPointerException e)
                {
                    Toast.makeText(context, "NO Activity can be launch", Toast.LENGTH_LONG).show();
                }
                catch(Exception e)
                {
                    String errorInfo = e.toString();
                    Toast.makeText(context, errorInfo, Toast.LENGTH_LONG).show();
                }
            }
        };
    }
}


%%%%%%%%%%%%%%%%%延伸學習%%%%%%%%%%%%%%%%%%%%%%%%%

package的ACTION_PACKAGE_ADDED / ACTION_PACKAGE_REMOVED事件
http://bedingfield-tsots.blogspot.com/2012/05/broadcastreceiver.html 

 

查詢&開啟應用程式列表 - getInstalledApplications & getLaunchIntentForPackage (二)
http://bedingfield-tsots.blogspot.com/2012/03/getinstalledapplications.html

 

2012年2月24日 星期五

PackageInfo / ApplicationInfo / ResolveInfo 的比較



=======================List<PackageInfo>=======================================
PackageManager packageManager = context.getPackageManager();
List<PackageInfo> allappPagInfo = packageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES);
System.out.println("100L pagInfo.size() : "+allappPagInfo.size());//48             
for(int i = 0 ; i <allappPagInfo.size() ; i ++)
{                 
    PackageInfo appPI = allappPagInfo.get(i);//PackageInfo{2ad3d2e0 com.android.launcher}
    String apPag = appPI.applicationInfo.packageName;//com.android.launcher
    String apName = appPI.applicationInfo.loadLabel(packageManager).toString();//Launcher
    Drawable apIcon = appPI.applicationInfo.loadIcon(packageManager);//android.graphics.drawable.BitmapDrawable@2ae37b08
    String dir = appPI.applicationInfo.publicSourceDir;
    long size = new File(dir).length();      //5015756
    ApplicationInfo allappInfo = appPI.applicationInfo;//ApplicationInfo{2ad14680 com.android.launcher}         
}


========================List<ApplicationInfo>==================================
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);
System.out.println("100L allappInfo.size() : "+allappInfo.size());//48
for(int i = 0 ; i <allappInfo.size() ; i ++)
{
    ApplicationInfo appAI = allappInfo.get(i);
    String apPag = appAI.packageName;//com.android.launcher
    String apName = appAI.loadLabel(packageManager).toString();//Launcher
    Drawable apIcon = appAI.loadIcon(packageManager);        //android.graphics.drawable.BitmapDrawable@2ae99f60
    String dir = appAI.publicSourceDir;
    long size = new File(dir).length();      //5015756
    ApplicationInfo apInfo = appAI;        //ApplicationInfo{2ad52d98 com.android.launcher}
}

========================List<ResolveInfo>==================================
PackageManager packageManager = context.getPackageManager();
Intent intent=new Intent(Intent.ACTION_SEND,null);
intent.addCategory(Intent.CATEGORY_DEFAULT); 
intent.setType("text/plain"); 
List<ResolveInfo> allappInfo = packageManager.queryIntentActivities(intent, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);

for(int i = 0 ; i <allappInfo.size() ; i ++)
{
    ResolveInfo appRI = allappInfo.get(i);
    String apPag = appRI.activityInfo.packageName;
    String apName = appRI.loadLabel(packageManager).toString();
    Drawable apIcon = appRI.loadIcon(packageManager);
}

    -----------------------------------------以ArrayList<自訂類別>儲存搜尋結果    -----------------------------------------
    //先建立class
    public class AppInfo
    {
        public String apPag="";
        public String apName="";
        public Drawable apIcon=null;
    }  

        PackageManager packageManager = context.getPackageManager();
        List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);

        ArrayList<AppInfo> appInfo = new ArrayList<AppInfo>(); //用來存儲獲取的應用資訊資料
        for(int i=0;i<allappInfo.size();i++)
        {
            ApplicationInfo appAI = allappInfo.get(i);
            AppInfo tmpInfo = new AppInfo();
            tmpInfo.apPag = appAI.packageName;
            tmpInfo.apName = appAI.loadLabel(getPackageManager()).toString();
            tmpInfo.apIcon = appAI.loadIcon(getPackageManager());
            appInfo.add(tmpInfo);            
        }

    -----------------------------------------以ArrayList<String>儲存搜尋結果    -----------------------------------------
        PackageManager packageManager = context.getPackageManager();
        List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);

        ArrayList<ApplicationInfo> list_allappInfo = new ArrayList<ApplicationInfo>();
        ArrayList<String> list_apPag = new ArrayList<String>();
        ArrayList<String> list_apName = new ArrayList<String>();
        ArrayList<Drawable> list_apIcon = new ArrayList<Drawable>();            
        for(int i = 0 ; i <allappInfo.size() ; i ++)
        {
            ApplicationInfo appAI = allappInfo.get(i);
            list_allappInfo.add(appAI);
            String apPag = appAI.packageName;
            list_apPag.add(apPag);
            String apName = appAI.loadLabel(packageManager).toString();
            list_apName.add(apName);
            Drawable apIcon = appAI.loadIcon(packageManager);
            list_apIcon.add(apIcon);
        }

    -----------------------------------------以List<Map<String,Object>>儲存搜尋結果    -----------------------------------------
PackageManager packageManager = context.getPackageManager();
        List<ApplicationInfo> allappInfo = packageManager.getInstalledApplications(PackageManager.GET_ACTIVITIES);                
        ArrayList<Map<String,Object>> arrayMap = new ArrayList<Map<String,Object>>(allappInfo.size());
        for(int i = 0 ; i < allappInfo.size() ; i ++)
        {
            ApplicationInfo appAI = allappInfo.get(i);
            Map<String,Object> map=new HashMap<String,Object>();
            String apPag = appAI.packageName;     
            String apName = appAI.loadLabel(packageManager).toString();
            Drawable apIcon = appAI.loadIcon(packageManager);                    
            map.put("package", apPag);
            map.put("name", apName);
            map.put("icon",apIcon);
            //map : {icon=android.graphics.drawable.BitmapDrawable@2afbf9f0, name=VPN Services, package=com.android.server.vpn}
            arrayMap.add(map);
            //arrayMap : [{map}, {map}, {map}, ...]
        }