ついでにActivityManager - 実行中のProcessやTask、最近起動したTask情報取得
はい、連日のpostになります。Managerしばりということで今回はActivityManagerです。下のScreen shotはRecentTask情報になります(Home button長押しすると出てくる奴と同じ情報)
ActivityManagerとは
Systemで動作しているProcessやTaskの情報を取得することが出来ます。BackgroundにあるProcessを殺したり、Foregroundに持ってきたりする事も出来ます
実装の要点は下記です(特にそんなにないけど)
気付いた点をまとめます
- ActivityManager#killBackgroundProcesses()を実行してもRunningTaskInfoからは消えない。SystemによりProcessは殺されているが、Userが戻ってくる時の為に最終的な状態を保持しているということがあるそうで、その際はRunningTaskInfoとして保持されるようです。(良くわかりませんが詳しくはRunningTaskInfoの説明を読んで下さい)
- Process nameとPackage nameは基本一緒
んで実装です
AndroidManifest.xml
<?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) { BaseAdapter adapter = null; String title = null; switch(v.getId()){ case R.id.process_display_button: adapter = new ProcessAdapter(this); title = "Process"; break; case R.id.recent_task_display_button: adapter = new RecentTaskAdapter(this); title = "Recent Task"; break; case R.id.running_task_display_button: adapter = new RunningTaskAdapter(this); title = "Running Task"; break; default: return; } showListDialog(this, adapter, title); } private void showListDialog(Context context, BaseAdapter adapter, String title){ final ListView lv = new ListView(context); 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(); } }
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.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; protected List<T> mInfoList; public AbsActivityManagerAdapter(Context context){ mContext = context; //ActivityManager objectを取得 mActivityMgr = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); 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.view.LayoutInflater; import android.view.View; import android.widget.TextView; public class ProcessAdapter extends AbsActivityManagerAdapter<RunningAppProcessInfo> { 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.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(); //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 TextView mProcessText; public TextView mImportanceText; public TextView mImportanceReasonText; } }
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.view.LayoutInflater; import android.view.View; import android.widget.TextView; public class RecentTaskAdapter extends AbsActivityManagerAdapter<RecentTaskInfo>{ 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.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(); //Taskを起動したIntentを取得 Intent intent = mInfoList.get(position).baseIntent; //ComponentName objectからPackageNameを取得 viewHolder.mPackageText.setText("Package: " + intent.getComponent().getPackageName()); } public static class RecentTaskListViewHolder implements ViewHolder{ public TextView mPackageText; } }
RunningTaskInfo取得class
package com.android.practice; import java.util.List; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; public class RunningTaskAdapter extends AbsActivityManagerAdapter<RunningTaskInfo>{ 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.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(); //ComponentName objectからPackage nameを取得 viewHolder.mPackageText.setText("Package: " + mInfoList.get(position).topActivity.getPackageName()); //ComponentName objectからClass nameを取得 viewHolder.mClassText.setText("Class: " + mInfoList.get(position).topActivity.getClassName()); } public static class RunningTaskListViewHolder implements ViewHolder{ public TextView mPackageText; public TextView mClassText; } }
こんな感じです。今回は情報を取得してDialogのListViewで表示しているだけですが、次回はPostの際にはPackageManagerを扱いとそれと連携させてAppの起動等が出来れば良いかなと思います
HashTag #Java, #Android, #ActivityManager, #RunningAppProcessInfo, #RecentTaskInfo, #RunningTaskInfo, #Dialog, #BaseAdaper, #ListView, #ViewHolder