Androidアプリケーションの一括アンインストール機能の実装

スマートフォンのメモリ容量に限りがあるため、複数のアプリケーションを一度にアンインストールする必要が生じることがあります。そのような場合、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リストのすべての要素を走査し、選択されているかどうかを判断し、選択されている場合はアンインストール処理を実行します。

タグ: Android アプリケーション管理 パッケージマネージャー UIアダプター 一括処理

7月7日 16:01 投稿