NfcPaymentPreference.java revision 39b467482d1bf256a111c757e9b7621c6f523271
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.settings.nfc; 17 18import android.app.AlertDialog; 19import android.content.ActivityNotFoundException; 20import android.content.Context; 21import android.content.DialogInterface; 22import android.content.Intent; 23import android.support.v7.preference.PreferenceViewHolder; 24import android.util.Log; 25import android.view.LayoutInflater; 26import android.view.View; 27import android.view.ViewGroup; 28import android.widget.BaseAdapter; 29import android.widget.CompoundButton; 30import android.widget.ImageView; 31import android.widget.RadioButton; 32 33import com.android.settings.CustomDialogPreference; 34import com.android.settings.R; 35import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; 36 37import java.util.List; 38 39public class NfcPaymentPreference extends CustomDialogPreference implements 40 PaymentBackend.Callback, View.OnClickListener { 41 42 private static final String TAG = "NfcPaymentPreference"; 43 44 private final NfcPaymentAdapter mAdapter; 45 private final Context mContext; 46 private final LayoutInflater mLayoutInflater; 47 private final PaymentBackend mPaymentBackend; 48 49 // Fields below only modified on UI thread 50 private ImageView mSettingsButtonView; 51 52 public NfcPaymentPreference(Context context, PaymentBackend backend) { 53 super(context, null); 54 mPaymentBackend = backend; 55 mContext = context; 56 backend.registerCallback(this); 57 mAdapter = new NfcPaymentAdapter(); 58 setDialogTitle(context.getString(R.string.nfc_payment_pay_with)); 59 mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 60 setWidgetLayoutResource(R.layout.preference_widget_settings); 61 62 refresh(); 63 } 64 65 @Override 66 public void onBindViewHolder(PreferenceViewHolder view) { 67 super.onBindViewHolder(view); 68 69 mSettingsButtonView = (ImageView) view.findViewById(R.id.settings_button); 70 mSettingsButtonView.setOnClickListener(this); 71 72 updateSettingsVisibility(); 73 } 74 75 /** 76 * MUST be called on UI thread. 77 */ 78 public void refresh() { 79 List<PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos(); 80 PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp(); 81 if (appInfos != null) { 82 PaymentAppInfo[] apps = appInfos.toArray(new PaymentAppInfo[appInfos.size()]); 83 mAdapter.updateApps(apps, defaultApp); 84 } 85 setTitle(R.string.nfc_payment_default); 86 if (defaultApp != null) { 87 setSummary(defaultApp.label); 88 } else { 89 setSummary(mContext.getString(R.string.nfc_payment_default_not_set)); 90 } 91 updateSettingsVisibility(); 92 } 93 94 @Override 95 protected void onPrepareDialogBuilder(AlertDialog.Builder builder, 96 DialogInterface.OnClickListener listener) { 97 super.onPrepareDialogBuilder(builder, listener); 98 99 builder.setSingleChoiceItems(mAdapter, 0, listener); 100 } 101 102 @Override 103 public void onPaymentAppsChanged() { 104 refresh(); 105 } 106 107 @Override 108 public void onClick(View view) { 109 PaymentAppInfo defaultAppInfo = mPaymentBackend.getDefaultApp(); 110 if (defaultAppInfo != null && defaultAppInfo.settingsComponent != null) { 111 Intent settingsIntent = new Intent(Intent.ACTION_MAIN); 112 settingsIntent.setComponent(defaultAppInfo.settingsComponent); 113 settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 114 try { 115 mContext.startActivity(settingsIntent); 116 } catch (ActivityNotFoundException e) { 117 Log.e(TAG, "Settings activity not found."); 118 } 119 } 120 } 121 122 void updateSettingsVisibility() { 123 if (mSettingsButtonView != null) { 124 PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp(); 125 if (defaultApp == null || defaultApp.settingsComponent == null) { 126 mSettingsButtonView.setVisibility(View.GONE); 127 } else { 128 mSettingsButtonView.setVisibility(View.VISIBLE); 129 130 } 131 } 132 } 133 134 class NfcPaymentAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener, 135 View.OnClickListener { 136 // Only modified on UI thread 137 private PaymentAppInfo[] appInfos; 138 139 public NfcPaymentAdapter() { 140 } 141 142 public void updateApps(PaymentAppInfo[] appInfos, PaymentAppInfo currentDefault) { 143 // Clone app infos, only add those with a banner 144 this.appInfos = appInfos; 145 notifyDataSetChanged(); 146 } 147 148 @Override 149 public int getCount() { 150 return appInfos.length; 151 } 152 153 @Override 154 public PaymentAppInfo getItem(int i) { 155 return appInfos[i]; 156 } 157 158 @Override 159 public long getItemId(int i) { 160 return appInfos[i].componentName.hashCode(); 161 } 162 163 @Override 164 public View getView(int position, View convertView, ViewGroup parent) { 165 ViewHolder holder; 166 PaymentAppInfo appInfo = appInfos[position]; 167 if (convertView == null) { 168 convertView = mLayoutInflater.inflate( 169 R.layout.nfc_payment_option, parent, false); 170 holder = new ViewHolder(); 171 holder.imageView = (ImageView) convertView.findViewById(R.id.banner); 172 holder.radioButton = (RadioButton) convertView.findViewById(R.id.button); 173 convertView.setTag(holder); 174 } else { 175 holder = (ViewHolder) convertView.getTag(); 176 } 177 holder.imageView.setImageDrawable(appInfo.banner); 178 holder.imageView.setTag(appInfo); 179 holder.imageView.setContentDescription(appInfo.label); 180 holder.imageView.setOnClickListener(this); 181 182 // Prevent checked callback getting called on recycled views 183 holder.radioButton.setOnCheckedChangeListener(null); 184 holder.radioButton.setChecked(appInfo.isDefault); 185 holder.radioButton.setContentDescription(appInfo.label); 186 holder.radioButton.setOnCheckedChangeListener(this); 187 holder.radioButton.setTag(appInfo); 188 return convertView; 189 } 190 191 public class ViewHolder { 192 public ImageView imageView; 193 public RadioButton radioButton; 194 } 195 196 @Override 197 public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 198 PaymentAppInfo appInfo = (PaymentAppInfo) compoundButton.getTag(); 199 makeDefault(appInfo); 200 } 201 202 @Override 203 public void onClick(View view) { 204 PaymentAppInfo appInfo = (PaymentAppInfo) view.getTag(); 205 makeDefault(appInfo); 206 } 207 208 void makeDefault(PaymentAppInfo appInfo) { 209 if (!appInfo.isDefault) { 210 mPaymentBackend.setDefaultPaymentApp(appInfo.componentName); 211 } 212 getDialog().dismiss(); 213 } 214 } 215} 216