例のPackageManager - Package nameからApplication Icon、name取得と他Application起動
昨日のPostで宣言した通り例のごとくPackageManagerについてのPostになります。ActivityManagerと連携してRecentTaskのListに載っているTaskの起動をしてみたいと思います。下記のScreen shotのようにApplication iconやApplication nameを取得し表示、さらにはitemをclickしてそのApplicationを起動出来ます(Home button長押しで出てくるTask managerみたいな機能)
PackageManagerとは
DeviceにinstallされているApplicationの様々な情報を取得することができる(ここ参照)
実装の要点は下記です
- PackageManager objectを取得
- (ApplicationManagerを使い取得した)Package nameからApplicationInfo objectを取得
- ApplicationInfoからapplication iconを取得
- ApplicationInfoからapplication nameを取得
- PackageManagerを使いApplicationをlaunchする為のIntentを取得
んで実装です
AndroidManifest.xml(ActivityManagerの回と変わらず)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.practice" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ActivityManagerPractice" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <!-- Task情報取得のためにAndroidManifest.xmlにandroid.permission.GET_TASKSを記載 --> <uses-permission android:name="android.permission.GET_TASKS" /> </manifest>
Activity
package com.android.practice; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ListView; public class ActivityManagerPractice extends Activity implements View.OnClickListener{ private static final String TAG = "ActivityManagerPractice"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setOnClickListeners(); } private void setOnClickListeners(){ ((Button)findViewById(R.id.process_display_button)).setOnClickListener(this); ((Button)findViewById(R.id.recent_task_display_button)).setOnClickListener(this); ((Button)findViewById(R.id.running_task_display_button)).setOnClickListener(this); } @Override public void onClick(View v) { final ListView lv = new ListView(this); BaseAdapter adapter = null; String title = null; switch(v.getId()){ case R.id.process_display_button: adapter = new ProcessAdapter(this); title = "Process"; lv.setOnItemClickListener((ProcessAdapter)adapter); break; case R.id.recent_task_display_button: adapter = new RecentTaskAdapter(this); title = "Recent Task"; lv.setOnItemClickListener((RecentTaskAdapter)adapter); break; case R.id.running_task_display_button: adapter = new RunningTaskAdapter(this); title = "Running Task"; lv.setOnItemClickListener((RunningTaskAdapter)adapter); break; default: return; } showListDialog(this, lv, adapter, title); } private void showListDialog(Context context, ListView lv, BaseAdapter adapter, String title){ lv.setAdapter(adapter); final AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); dialog = null; } }); builder.setView(lv); builder.create().show(); } }
PackageManager、ActivityManger取得class(抽象なAdapter拡張class)
package com.android.practice; import java.util.List; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.content.Context; import android.content.pm.PackageManager; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; abstract public class AbsActivityManagerAdapter<T> extends BaseAdapter { final protected Context mContext; final protected ActivityManager mActivityMgr; final protected PackageManager mPackageMgr; protected List<T> mInfoList; public AbsActivityManagerAdapter(Context context){ mContext = context; //ActivityManager objectを取得 mActivityMgr = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); //PackageManager objectを取得 mPackageMgr = context.getPackageManager(); mInfoList = createList(); } @Override public int getCount() { if(mInfoList == null){ return 0; } return mInfoList.size(); } @Override public Object getItem(int position) { if(mInfoList == null || position < 0 || position >= mInfoList.size()){ return null; } return mInfoList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null){ view = getListItemLayout(); ViewHolder viewHolder = createViewHolder(view); view.setTag(viewHolder); } setContentsToViewHolder(view, position); return view; } abstract protected List<T> createList(); abstract protected View getListItemLayout(); abstract protected ViewHolder createViewHolder(View view); abstract protected void setContentsToViewHolder(View view, int position); public static interface ViewHolder{ } }
RunningAppProcessInfo取得class
package com.android.practice; import java.util.List; import android.app.ActivityManager.RunningAppProcessInfo; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class ProcessAdapter extends AbsActivityManagerAdapter<RunningAppProcessInfo> implements OnItemClickListener{ private static final String TAG = "ProcessAdapter"; public ProcessAdapter(Context context) { super(context); } @Override protected View getListItemLayout(){ LayoutInflater lInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return lInflater.inflate(R.layout.process, null); } @Override protected ViewHolder createViewHolder(View view){ ProcessListViewHolder viewHolder = new ProcessListViewHolder(); viewHolder.mImage = (ImageView)view.findViewById(R.id.icon); viewHolder.mApplicationText = (TextView)view.findViewById(R.id.application); viewHolder.mPackageText = (TextView)view.findViewById(R.id.pkg); viewHolder.mProcessText = (TextView)view.findViewById(R.id.process); viewHolder.mImportanceText = (TextView)view.findViewById(R.id.importance); viewHolder.mImportanceReasonText = (TextView)view.findViewById(R.id.importance_reason); return viewHolder; } @Override protected void setContentsToViewHolder(View view, int position){ ProcessListViewHolder viewHolder = (ProcessListViewHolder)view.getTag(); ApplicationInfo appInfo = null; String pkgName = mInfoList.get(position).pkgList[0]; try { if(pkgName != null){ //Package nameからApplicationInfo objectを取得 appInfo = mPackageMgr.getApplicationInfo(pkgName, 0); } } catch (NameNotFoundException e) { e.printStackTrace(); } if(appInfo != null){ //ApplicationInfoからapplication iconを取得 Drawable appIcon = appInfo.loadIcon(mPackageMgr); viewHolder.mImage.setImageDrawable(appIcon); //ApplicationInfoからapplication nameを取得 String appName = (String) appInfo.loadLabel(mPackageMgr); viewHolder.mApplicationText.setText("Application: " + appName); } viewHolder.mPackageText.setText("Package: " + pkgName); //Process nameの取得。基本はPackage nameと一緒 viewHolder.mProcessText.setText("Process: " + mInfoList.get(position).processName); viewHolder.mImportanceText.setText("Importance: " + mInfoList.get(position).importance); viewHolder.mImportanceReasonText.setText("ImportanceReason: " + + mInfoList.get(position).importanceReasonCode); } @Override protected List<RunningAppProcessInfo> createList() { //RunningAppProcessInfoのListを取得 return mActivityMgr.getRunningAppProcesses(); } public static class ProcessListViewHolder implements ViewHolder{ public ImageView mImage; public TextView mApplicationText; public TextView mPackageText; public TextView mProcessText; public TextView mImportanceText; public TextView mImportanceReasonText; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String pkgName = mInfoList.get(position).pkgList[0]; //PackageManagerを使いApplicationをlaunchする為のIntentを取得 Intent intent = mPackageMgr.getLaunchIntentForPackage(pkgName); if(intent == null){ Log.d(TAG, "intent null"); return; } mContext.startActivity(intent); } }
RecentTaskInfo取得class
package com.android.practice; import java.util.List; import com.android.practice.AbsActivityManagerAdapter.ViewHolder; import com.android.practice.ProcessAdapter.ProcessListViewHolder; import android.app.ActivityManager; import android.app.ActivityManager.RecentTaskInfo; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; import android.widget.TextView; public class RecentTaskAdapter extends AbsActivityManagerAdapter<RecentTaskInfo> implements OnItemClickListener{ private static final String TAG = "RecentTaskAdapter"; public RecentTaskAdapter(Context context) { super(context); } @Override protected List<RecentTaskInfo> createList() { //RecentTaskInfoのListを取得 return mActivityMgr.getRecentTasks(100, 0); } @Override protected View getListItemLayout() { LayoutInflater lInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return lInflater.inflate(R.layout.recent_task, null); } @Override protected ViewHolder createViewHolder(View view) { RecentTaskListViewHolder viewHolder = new RecentTaskListViewHolder(); viewHolder.mImage = (ImageView)view.findViewById(R.id.recent_task_app_icon); viewHolder.mApplicationText = (TextView)view.findViewById(R.id.recent_task_app_name); viewHolder.mPackageText = (TextView)view.findViewById(R.id.recent_task_pkg_name); return viewHolder; } @Override protected void setContentsToViewHolder(View view, int position) { RecentTaskListViewHolder viewHolder = (RecentTaskListViewHolder)view.getTag(); ApplicationInfo appInfo = null; //Taskを起動したIntentを取得 Intent intent = mInfoList.get(position).baseIntent; String pkgName = intent.getComponent().getPackageName(); try { if(pkgName != null){ //Package nameからApplicationInfo objectを取得 appInfo = mPackageMgr.getApplicationInfo(pkgName, 0); } } catch (NameNotFoundException e) { e.printStackTrace(); } if(appInfo != null){ //ApplicationInfoからapplication iconを取得 Drawable appIcon = appInfo.loadIcon(mPackageMgr); viewHolder.mImage.setImageDrawable(appIcon); //ApplicationInfoからapplication nameを取得 String appName = (String) appInfo.loadLabel(mPackageMgr); viewHolder.mApplicationText.setText("Application: " + appName); } //ComponentName objectからPackageNameを取得 viewHolder.mPackageText.setText("Package: " + pkgName); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = mInfoList.get(position).baseIntent; if(intent == null){ Log.d(TAG, "intent null"); return; } mContext.startActivity(intent); } public static class RecentTaskListViewHolder implements ViewHolder{ public ImageView mImage; public TextView mApplicationText; public TextView mPackageText; } }
RunningTaskInfo取得class
package com.android.practice; import java.util.List; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class RunningTaskAdapter extends AbsActivityManagerAdapter<RunningTaskInfo> implements OnItemClickListener{ private static final String TAG = "RunningTaskAdapter"; public RunningTaskAdapter(Context context) { super(context); } @Override protected List<RunningTaskInfo> createList() { //RunningTaskInfoのListを取得 return mActivityMgr.getRunningTasks(100); } @Override protected View getListItemLayout() { LayoutInflater lInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return lInflater.inflate(R.layout.running_task, null); } @Override protected ViewHolder createViewHolder(View view) { RunningTaskListViewHolder viewHolder = new RunningTaskListViewHolder(); viewHolder.mImage = (ImageView)view.findViewById(R.id.running_task_app_icon); viewHolder.mApplicationText = (TextView)view.findViewById(R.id.running_task_app_name); viewHolder.mPackageText = (TextView)view.findViewById(R.id.running_task_pkg_name); viewHolder.mClassText = (TextView)view.findViewById(R.id.running_task_cls_name); return viewHolder; } @Override protected void setContentsToViewHolder(View view, int position) { RunningTaskListViewHolder viewHolder = (RunningTaskListViewHolder)view.getTag(); ApplicationInfo appInfo = null; String pkgName = mInfoList.get(position).topActivity.getPackageName(); try { if(pkgName != null){ //Package nameからApplicationInfo objectを取得 appInfo = mPackageMgr.getApplicationInfo(pkgName, 0); } } catch (NameNotFoundException e) { e.printStackTrace(); } if(appInfo != null){ //ApplicationInfoからapplication iconを取得 Drawable appIcon = appInfo.loadIcon(mPackageMgr); viewHolder.mImage.setImageDrawable(appIcon); //ApplicationInfoからapplication nameを取得 String appName = (String) appInfo.loadLabel(mPackageMgr); viewHolder.mApplicationText.setText("Application: " + appName); } //ComponentName objectからPackage nameを取得 viewHolder.mPackageText.setText("Package: " + pkgName); //ComponentName objectからClass nameを取得 viewHolder.mClassText.setText("Class: " + mInfoList.get(position).topActivity.getClassName()); } public static class RunningTaskListViewHolder implements ViewHolder{ public ImageView mImage; public TextView mApplicationText; public TextView mPackageText; public TextView mClassText; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String pkgName = mInfoList.get(position).topActivity.getPackageName(); //PackageManagerを使いApplicationをlaunchする為のIntentを取得 Intent intent = mPackageMgr.getLaunchIntentForPackage(pkgName); if(intent == null){ Log.d(TAG, "intent null"); return; } mContext.startActivity(intent); } }
と、まあこんな感じです。他にもあるIntentに反応するpackageを取得したりとPackageManagerを使用すると色んなことが出来ます
HashTag #Java, #Android, #PackageManager, #ListView, #BaseAdapter, #RunningAppProcessInfo, #RecentTaskInfo, #RunningTaskInfo, #AdapterView.OnItemClickListener