スマートフォンのメモリ容量に限りがあるため、複数のアプリケーションを一度にアンインストールする必要が生じることがあります。そのような場合、Androidアプリケーションの一括削除機能を実装したアプリケーションが必要になります。
まずはレイアウトファイルから説明します:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="5" >
<TextView
android:id="@+id/textView1"
style="@style/my_style"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="4" />
<TextView
android:id="@+id/textView2"
style="@style/my_style"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="1"
android:gravity="center_vertical|center_horizontal"
android:text="アプリ名" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="4"
android:gravity="center_vertical|center_horizontal"
android:text="システムアプリ" />
</LinearLayout>
<ListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
</ListView>
<Button
android:id="@+id/btn_uninstall"
style="@style/my_style"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="5"
android:text="アンインストール" />
</LinearLayout>
レイアウトファイルは比較的シンプルで、最も重要なのはリスト部分です。
次に、Javaクラスファイルの実装を説明します:
package com.example.batchuninstaller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class AppUninstallerActivity extends ListActivity{
Button uninstallButton;
PackageManager packageManager;
AppListAdapter listAdapter;
// すべてのアプリケーションリストを取得
public void loadApplications(){
listAdapter = new AppListAdapter(this);
// パッケージマネージャー
PackageManager pm = getPackageManager();
// 端末にインストールされているすべてのアプリケーションを取得
List<PackageInfo> packageInfoList = pm.getInstalledPackages(0);
for (int i=0; i<packageInfoList.size(); i++){
PackageInfo packageInfo = (PackageInfo) packageInfoList.get(i);
String isSystemApp;
Drawable appIcon;
// システムアプリかどうかを判定
if ((packageInfo.applicationInfo.flags & packageInfo.applicationInfo.FLAG_SYSTEM) <= 0)
isSystemApp = "いいえ";
else
isSystemApp = "はい";
if (packageInfo.applicationInfo.loadIcon(pm) != null)
appIcon = (Drawable)packageInfo.applicationInfo.loadIcon(pm);
else
appIcon = (Drawable) getResources().getDrawable(R.drawable.ic_launcher);
listAdapter.addItem(String.valueOf(packageInfo.applicationInfo.loadLabel(pm)),
isSystemApp,
appIcon,
packageInfo.applicationInfo.packageName,
false);
}
setListAdapter(listAdapter);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_list_layout);
loadApplications();
uninstallButton = (Button) findViewById(R.id.btn_uninstall);
uninstallButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int j=0; j<listAdapter.getItemCount(); j++){
// アプリケーションが選択されている場合
if (listAdapter.isItemSelected(j)){
String appName = (String)
listAdapter.getItemName(j);
final String packageName = listAdapter.getItemPackageName(j);
new AlertDialog.Builder(AppUninstallerActivity.this)
.setTitle("アプリケーションの削除")
.setMessage(appName + "を削除してもよろしいですか?")
.setPositiveButton("はい", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
uninstallApp(packageName);
loadApplications();
}
})
.setNegativeButton("いいえ", null)
.show();
}
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// メニューをインフレートします
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private boolean uninstallApp (String packageName){
boolean success = true;
try{
// パッケージ名からURIを作成
Uri packageUri = Uri.parse("package:" + packageName);
// Intentを作成
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageUri);
// アンインストールプログラムを実行
startActivity(uninstallIntent);
success = true;
}
catch(Exception e){
success = false;
}
finally{
return success;
}
}
}
// アプリケーションリストのアダプター
class AppListAdapter extends BaseAdapter implements OnClickListener{
public Context context;
public List<AppItem> appItems;
public AppListAdapter(Context context){
this.context = context;
appItems = new ArrayList<AppItem>();
}
@Override
public int getCount() {
return appItems.size();
}
@Override
public Object getItem(int position) {
return appItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
AppItem appItem;
if (convertView == null)
{
appItem = new AppItem(context,
appItems.get(position).getAppName(),
appItems.get(position).getSystemAppFlag(),
appItems.get(position).getAppIcon(),
appItems.get(position).getPackageName(),
appItems.get(position).isSelected());
}
else
{
appItem = (AppItem)convertView;
appItem.setAppName(appItems.get(position).getAppName());
appItem.setSystemAppFlag(appItems.get(position).getSystemAppFlag());
appItem.setAppIcon(appItems.get(position).getAppIcon());
}
CheckBox checkBox = (CheckBox) appItem.getCheckBox();
checkBox.setOnClickListener(this);
Log.d("AppSelection", "Position " + position + " selected: " + appItems.get(position).isSelected());
checkBox.setChecked(appItems.get(position).isSelected());
checkBox.setTag(position);
return appItem;
}
public void addItem(String appName, String systemAppFlag, Drawable appIcon,
String packageName, Boolean isSelected)
{
appItems.add(new AppItem(context, appName, systemAppFlag, appIcon, packageName, isSelected));
}
public boolean isItemSelected(int position) {
return appItems.get(position).isSelected();
}
public String getItemName(int position) {
return appItems.get(position).getAppName();
}
public String getItemPackageName(int position) {
return appItems.get(position).getPackageName();
}
@Override
public void onClick(View v) {
CheckBox checkBox = (CheckBox) v;
int position = Integer.parseInt(v.getTag().toString());
appItems.get(position).setSelected(checkBox.isChecked());
}
}
// リスト内の1行を表すクラス
class AppItem extends LinearLayout{
private CheckBox checkBox;
private TextView appNameTextView;
private TextView systemAppFlagTextView;
private ImageView appIconImageView;
private String packageName;
private boolean isSelected;
public AppItem(Context context, String appName, String systemAppFlag,
Drawable appIcon, String packageName, Boolean isSelected)
{
super(context);
this.setOrientation(HORIZONTAL);
int height = 60;
checkBox = new CheckBox(context);
addView(checkBox,
new LinearLayout.LayoutParams((int)(MainActivity.screenWidth*0.2),height));
appIconImageView = new ImageView(context);
appIconImageView.setImageDrawable(appIcon);
addView(appIconImageView,
new LinearLayout.LayoutParams((int)(MainActivity.screenWidth*0.2),height));
appNameTextView = new TextView(context);
appNameTextView.setText(appName);
addView(appNameTextView,
new LinearLayout.LayoutParams((int)(MainActivity.screenWidth*0.4),height));
systemAppFlagTextView = new TextView(context);
systemAppFlagTextView.setText(systemAppFlag);
addView(systemAppFlagTextView,
new LinearLayout.LayoutParams((int)(MainActivity.screenWidth*0.2),height));
this.packageName = packageName;
this.isSelected = isSelected;
}
public CheckBox getCheckBox() {
return checkBox;
}
public TextView getAppNameTextView() {
return appNameTextView;
}
public TextView getSystemAppFlagTextView() {
return systemAppFlagTextView;
}
public ImageView getAppIconImageView() {
return appIconImageView;
}
public String getPackageName() {
return packageName;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
public String getAppName() {
return appNameTextView.getText().toString();
}
public String getSystemAppFlag() {
return systemAppFlagTextView.getText().toString();
}
public Drawable getAppIcon() {
return appIconImageView.getDrawable();
}
}
合計3つのクラスを実装しました:AppUninstallerActivity、AppListAdapter、AppItemです。AppUninstallerActivityはメインのActivityクラス、AppListAdapterはリストのアダプタークラス、AppItemはリスト内の1行を表すクラスです。AppListAdapterのappItemsリストは、パッケージ名、システムアプリかどうか、選択されているかなど、各パッケージの重要な情報を記録しています。
「アンインストール」ボタンがクリックされると、appItemsリストのすべての要素を走査し、選択されているかどうかを判断し、選択されている場合はアンインストール処理を実行します。