diff --git a/src/com/android/settings/SmsDefaultDialog.java b/src/com/android/settings/SmsDefaultDialog.java index e2a3fafc98b..a1af02140f7 100644 --- a/src/com/android/settings/SmsDefaultDialog.java +++ b/src/com/android/settings/SmsDefaultDialog.java @@ -20,19 +20,30 @@ import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.provider.Telephony.Sms.Intents; import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.internal.telephony.SmsApplication; import com.android.internal.telephony.SmsApplication.SmsApplicationData; -import com.android.settings.R; + +import java.util.ArrayList; +import java.util.List; public final class SmsDefaultDialog extends AlertActivity implements DialogInterface.OnClickListener { - private ComponentName mNewDefault; private SmsApplicationData mNewSmsApplicationData; @Override @@ -57,6 +68,18 @@ public final class SmsDefaultDialog extends AlertActivity implements break; case BUTTON_NEGATIVE: break; + default: + if (which >= 0) { + AppListAdapter adapter = (AppListAdapter) mAlertParams.mAdapter; + if (!adapter.isSelected(which)) { + String packageName = adapter.getPackageName(which); + if (!TextUtils.isEmpty(packageName)) { + SmsApplication.setDefaultApplication(packageName, this); + setResult(RESULT_OK); + } + } + } + break; } } @@ -66,39 +89,177 @@ public final class SmsDefaultDialog extends AlertActivity implements // No phone, no SMS return false; } - - mNewSmsApplicationData = SmsApplication.getSmsApplicationData(packageName, this); - if (mNewSmsApplicationData == null) { - return false; - } - - SmsApplicationData oldSmsApplicationData = null; - ComponentName oldSmsComponent = SmsApplication.getDefaultSmsApplication(this, true); - if (oldSmsComponent != null) { - oldSmsApplicationData = - SmsApplication.getSmsApplicationData(oldSmsComponent.getPackageName(), this); - if (oldSmsApplicationData.mPackageName.equals(mNewSmsApplicationData.mPackageName)) { - return false; - } - } - - // Compose dialog; get final AlertController.AlertParams p = mAlertParams; p.mTitle = getString(R.string.sms_change_default_dialog_title); - if (oldSmsApplicationData != null) { - p.mMessage = getString(R.string.sms_change_default_dialog_text, - mNewSmsApplicationData.mApplicationName, - oldSmsApplicationData.mApplicationName); + mNewSmsApplicationData = SmsApplication.getSmsApplicationData(packageName, this); + if (mNewSmsApplicationData != null) { + // New default SMS app specified, change to that directly after the confirmation + // dialog. + SmsApplicationData oldSmsApplicationData = null; + ComponentName oldSmsComponent = SmsApplication.getDefaultSmsApplication(this, true); + if (oldSmsComponent != null) { + oldSmsApplicationData = SmsApplication.getSmsApplicationData( + oldSmsComponent.getPackageName(), this); + if (oldSmsApplicationData.mPackageName.equals( + mNewSmsApplicationData.mPackageName)) { + return false; + } + } + + // Compose dialog; get + if (oldSmsApplicationData != null) { + p.mMessage = getString(R.string.sms_change_default_dialog_text, + mNewSmsApplicationData.mApplicationName, + oldSmsApplicationData.mApplicationName); + } else { + p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text, + mNewSmsApplicationData.mApplicationName); + } + p.mPositiveButtonText = getString(R.string.yes); + p.mNegativeButtonText = getString(R.string.no); + p.mPositiveButtonListener = this; + p.mNegativeButtonListener = this; } else { - p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text, - mNewSmsApplicationData.mApplicationName); + // No new default SMS app specified, show a list of all SMS apps and let user to pick + p.mAdapter = new AppListAdapter(); + p.mOnClickListener = this; + p.mNegativeButtonText = getString(R.string.cancel); + p.mNegativeButtonListener = this; } - p.mPositiveButtonText = getString(R.string.yes); - p.mNegativeButtonText = getString(R.string.no); - p.mPositiveButtonListener = this; - p.mNegativeButtonListener = this; setupAlert(); return true; } -} \ No newline at end of file + + /** + * The list of SMS apps with label, icon. Current default SMS app is marked as "default". + */ + private class AppListAdapter extends BaseAdapter { + /** + * SMS app item in the list + */ + private class Item { + final String label; // app label + final Drawable icon; // app icon + final String packgeName; // full app package name + + public Item(String label, Drawable icon, String packageName) { + this.label = label; + this.icon = icon; + this.packgeName = packageName; + } + } + + // The list + private final List mItems; + // The index of selected + private final int mSelectedIndex; + + public AppListAdapter() { + mItems = getItems(); + int selected = getSelectedIndex(); + // Move selected up to the top so it is easy to find + if (selected > 0) { + Item item = mItems.remove(selected); + mItems.add(0, item); + selected = 0; + } + mSelectedIndex = selected; + } + + @Override + public int getCount() { + return mItems != null ? mItems.size() : 0; + } + + @Override + public Object getItem(int position) { + return mItems != null && position < mItems.size() ? mItems.get(position) : null; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Item item = ((Item) getItem(position)); + LayoutInflater inflater = getLayoutInflater(); + View view = inflater.inflate(R.layout.app_preference_item, parent, false); + TextView textView = (TextView) view.findViewById(R.id.app_label); + textView.setText(item.label); + if (position == mSelectedIndex) { + view.findViewById(R.id.default_label).setVisibility(View.VISIBLE); + } else { + view.findViewById(R.id.default_label).setVisibility(View.GONE); + } + ImageView imageView = (ImageView)view.findViewById(R.id.app_image); + imageView.setImageDrawable(item.icon); + return view; + } + + /** + * Get the selected package name by + * + * @param position the index of the item in the list + * @return the package name of selected item + */ + public String getPackageName(int position) { + Item item = (Item) getItem(position); + if (item != null) { + return item.packgeName; + } + return null; + } + + /** + * Check if an item at a position is already selected + * + * @param position the index of the item in the list + * @return true if the item at the position is already selected, false otherwise + */ + public boolean isSelected(int position) { + return position == mSelectedIndex; + } + + // Get the list items by looking for SMS apps + private List getItems() { + PackageManager pm = getPackageManager(); + List items = new ArrayList<>(); + for (SmsApplication.SmsApplicationData app : + SmsApplication.getApplicationCollection(SmsDefaultDialog.this)) { + try { + String packageName = app.mPackageName; + ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0/*flags*/); + if (appInfo != null) { + items.add(new Item( + appInfo.loadLabel(pm).toString(), + appInfo.loadIcon(pm), + packageName)); + } + } catch (PackageManager.NameNotFoundException e) { + // Ignore package can't be found + } + } + return items; + } + + // Get the selected item index by looking for the current default SMS app + private int getSelectedIndex() { + ComponentName appName = SmsApplication.getDefaultSmsApplication( + SmsDefaultDialog.this, true); + if (appName != null) { + String defaultSmsAppPackageName = appName.getPackageName(); + if (!TextUtils.isEmpty(defaultSmsAppPackageName)) { + for (int i = 0; i < mItems.size(); i++) { + if (TextUtils.equals(mItems.get(i).packgeName, defaultSmsAppPackageName)) { + return i; + } + } + } + } + return -1; + } + } +}