Merge "Latest UX for Tap & pay." into klp-dev

This commit is contained in:
Martijn Coenen
2013-09-26 17:57:47 +00:00
committed by Android (Google) Code Review
11 changed files with 118 additions and 44 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -7,15 +7,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="vertical" > android:orientation="vertical" >
<TextView
android:id="@+id/nfc_payment_empty_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="24sp"
android:visibility="gone"
android:paddingBottom="16dp"
android:text="@string/nfc_payment_no_apps"/>
<ImageView <ImageView
android:id="@+id/nfc_payment_tap_image" android:id="@+id/nfc_payment_tap_image"
android:layout_width="fill_parent" android:layout_width="fill_parent"
@@ -23,6 +14,15 @@
android:gravity="center" android:gravity="center"
android:visibility="gone" android:visibility="gone"
android:src="@drawable/nfc_payment_empty_state"/> android:src="@drawable/nfc_payment_empty_state"/>
<TextView
android:id="@+id/nfc_payment_empty_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="24sp"
android:visibility="gone"
android:paddingTop="16dp"
android:text="@string/nfc_payment_no_apps"/>
</LinearLayout> </LinearLayout>
<ListView <ListView
android:id="@android:id/list" android:id="@android:id/list"

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nfc_payment_menu_item_add_service"
android:title="@string/nfc_payment_menu_item_add_service"
android:showAsAction="ifRoom">
</item>
</menu>

View File

@@ -35,5 +35,7 @@
</string-array> </string-array>
<!-- Default query string to search for a print service. --> <!-- Default query string to search for a print service. -->
<string name="download_print_service_query">market://search?q=print service</string> <string name="download_print_service_query">market://search?q=print service</string>
<!-- Default query string to search for a NFC payment service. -->
<string name="download_nfc_payment_service_query">market://search?q=nfc payment</string>
</resources> </resources>

View File

@@ -4755,14 +4755,15 @@
<string name="global_font_change_title">Change font size</string> <string name="global_font_change_title">Change font size</string>
<!-- NFC payment settings --><skip/> <!-- NFC payment settings --><skip/>
<string name="nfc_payment_settings_title">Payments</string> <string name="nfc_payment_settings_title">Tap &amp; pay</string>
<!-- String shown when there are no NFC payment applications installed --> <!-- String shown when there are no NFC payment applications installed -->
<string name="nfc_payment_no_apps">DO NOT TRANSLATE ME</string> <string name="nfc_payment_no_apps">You have no apps configured for tap &amp; pay with NFC.</string>
<string name="nfc_payment_menu_item_add_service">Find apps</string>
<!-- Label for the dialog that is shown when the user is asked to set a <!-- Label for the dialog that is shown when the user is asked to set a
preferred payment application --> preferred payment application -->
<string name="nfc_payment_set_default_label">Set as your preference?</string> <string name="nfc_payment_set_default_label">Set as your preference?</string>
<string name="nfc_payment_set_default">Always use <xliff:g id="app">%1$s</xliff:g> when you tap and pay?</string> <string name="nfc_payment_set_default">Always use <xliff:g id="app">%1$s</xliff:g> when you tap &amp; pay?</string>
<string name="nfc_payment_set_default_instead_of">Always use <xliff:g id="app">%1$s</xliff:g> instead of <xliff:g id="app">%2$s</xliff:g> when you tap and pay?</string> <string name="nfc_payment_set_default_instead_of">Always use <xliff:g id="app">%1$s</xliff:g> instead of <xliff:g id="app">%2$s</xliff:g> when you tap &amp; pay?</string>
<!-- Restrictions settings --><skip/> <!-- Restrictions settings --><skip/>
<!-- Restriction settings title [CHAR LIMIT=35] --> <!-- Restriction settings title [CHAR LIMIT=35] -->

View File

@@ -61,8 +61,11 @@ public class PaymentBackend {
for (ApduServiceInfo service : serviceInfos) { for (ApduServiceInfo service : serviceInfos) {
PaymentAppInfo appInfo = new PaymentAppInfo(); PaymentAppInfo appInfo = new PaymentAppInfo();
appInfo.caption = service.loadLabel(pm);
appInfo.banner = service.loadBanner(pm); appInfo.banner = service.loadBanner(pm);
appInfo.caption = service.getDescription();
if (appInfo.caption == null) {
appInfo.caption = service.loadLabel(pm);
}
appInfo.isDefault = service.getComponent().equals(defaultApp); appInfo.isDefault = service.getComponent().equals(defaultApp);
appInfo.componentName = service.getComponent(); appInfo.componentName = service.getComponent();
appInfos.add(appInfo); appInfos.add(appInfo);

View File

@@ -21,8 +21,12 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.nfc.cardemulation.ApduServiceInfo;
import android.nfc.cardemulation.CardEmulation; import android.nfc.cardemulation.CardEmulation;
import android.nfc.cardemulation.HostApduService;
import android.nfc.cardemulation.OffHostApduService;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
@@ -31,8 +35,11 @@ import com.android.internal.app.AlertController;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
import java.io.IOException;
import java.util.List; import java.util.List;
import org.xmlpull.v1.XmlPullParserException;
public final class PaymentDefaultDialog extends AlertActivity implements public final class PaymentDefaultDialog extends AlertActivity implements
DialogInterface.OnClickListener { DialogInterface.OnClickListener {
@@ -81,17 +88,20 @@ public final class PaymentDefaultDialog extends AlertActivity implements
} }
// Check if passed in service exists // Check if passed in service exists
boolean found = false; PaymentAppInfo requestedPaymentApp = null;
PaymentAppInfo defaultPaymentApp = null;
List<PaymentAppInfo> services = mBackend.getPaymentAppInfos(); List<PaymentAppInfo> services = mBackend.getPaymentAppInfos();
for (PaymentAppInfo service : services) { for (PaymentAppInfo service : services) {
if (component.equals(service.componentName)) { if (component.equals(service.componentName)) {
found = true; requestedPaymentApp = service;
break; }
if (service.isDefault) {
defaultPaymentApp = service;
} }
} }
if (!found) { if (requestedPaymentApp == null) {
Log.e(TAG, "Component " + component + " is not a registered payment service."); Log.e(TAG, "Component " + component + " is not a registered payment service.");
return false; return false;
} }
@@ -103,36 +113,18 @@ public final class PaymentDefaultDialog extends AlertActivity implements
return false; return false;
} }
PackageManager pm = getPackageManager();
ApplicationInfo newAppInfo;
try {
newAppInfo = pm.getApplicationInfo(component.getPackageName(), 0);
} catch (NameNotFoundException e) {
Log.e(TAG, "PM could not load app info for " + component);
return false;
}
ApplicationInfo defaultAppInfo = null;
try {
if (defaultComponent != null) {
defaultAppInfo = pm.getApplicationInfo(defaultComponent.getPackageName(), 0);
}
} catch (NameNotFoundException e) {
Log.e(TAG, "PM could not load app info for " + defaultComponent);
// Continue intentionally
}
mNewDefault = component; mNewDefault = component;
// Compose dialog; get // Compose dialog; get
final AlertController.AlertParams p = mAlertParams; final AlertController.AlertParams p = mAlertParams;
p.mTitle = getString(R.string.nfc_payment_set_default_label); p.mTitle = getString(R.string.nfc_payment_set_default_label);
if (defaultAppInfo == null) { if (defaultPaymentApp == null) {
String formatString = getString(R.string.nfc_payment_set_default); String formatString = getString(R.string.nfc_payment_set_default);
String msg = String.format(formatString, newAppInfo.loadLabel(pm)); String msg = String.format(formatString, requestedPaymentApp.caption);
p.mMessage = msg; p.mMessage = msg;
} else { } else {
String formatString = getString(R.string.nfc_payment_set_default_instead_of); String formatString = getString(R.string.nfc_payment_set_default_instead_of);
String msg = String.format(formatString, newAppInfo.loadLabel(pm), defaultAppInfo.loadLabel(pm)); String msg = String.format(formatString, requestedPaymentApp.caption,
defaultPaymentApp.caption);
p.mMessage = msg; p.mMessage = msg;
} }
p.mPositiveButtonText = getString(R.string.yes); p.mPositiveButtonText = getString(R.string.yes);

View File

@@ -17,12 +17,19 @@
package com.android.settings.nfc; package com.android.settings.nfc;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -30,6 +37,7 @@ import android.widget.ImageView;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.content.PackageMonitor;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
@@ -42,6 +50,8 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
private LayoutInflater mInflater; private LayoutInflater mInflater;
private PaymentBackend mPaymentBackend; private PaymentBackend mPaymentBackend;
private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
@@ -50,12 +60,12 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
setHasOptionsMenu(false); setHasOptionsMenu(false);
mPaymentBackend = new PaymentBackend(getActivity()); mPaymentBackend = new PaymentBackend(getActivity());
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setHasOptionsMenu(true);
} }
public void refresh() { public void refresh() {
PreferenceManager manager = getPreferenceManager(); PreferenceManager manager = getPreferenceManager();
PreferenceScreen screen = manager.createPreferenceScreen(getActivity()); PreferenceScreen screen = manager.createPreferenceScreen(getActivity());
// Get all payment services // Get all payment services
List<PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos(); List<PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos();
if (appInfos != null && appInfos.size() > 0) { if (appInfos != null && appInfos.size() > 0) {
@@ -80,17 +90,15 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
} else { } else {
emptyText.setVisibility(View.GONE); emptyText.setVisibility(View.GONE);
emptyImage.setVisibility(View.GONE); emptyImage.setVisibility(View.GONE);
setPreferenceScreen(screen);
} }
setPreferenceScreen(screen);
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View v = mInflater.inflate(R.layout.nfc_payment, container, false); View v = mInflater.inflate(R.layout.nfc_payment, container, false);
return v; return v;
} }
@@ -108,9 +116,54 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
refresh(); refresh();
} }
@Override
public void onPause() {
mSettingsPackageMonitor.unregister();
super.onPause();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.nfc_payment_settings, menu);
MenuItem menuItem = menu.findItem(R.id.nfc_payment_menu_item_add_service);
menuItem.setIntent(new Intent(Intent.ACTION_VIEW,
Uri.parse(getString(R.string.download_nfc_payment_service_query))));
}
private final Handler mHandler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
refresh();
}
};
private class SettingsPackageMonitor extends PackageMonitor {
@Override
public void onPackageAdded(String packageName, int uid) {
mHandler.obtainMessage().sendToTarget();
}
@Override
public void onPackageAppeared(String packageName, int reason) {
mHandler.obtainMessage().sendToTarget();
}
@Override
public void onPackageDisappeared(String packageName, int reason) {
mHandler.obtainMessage().sendToTarget();
}
@Override
public void onPackageRemoved(String packageName, int uid) {
mHandler.obtainMessage().sendToTarget();
}
}
public static class PaymentAppPreference extends Preference { public static class PaymentAppPreference extends Preference {
private final OnClickListener listener; private final OnClickListener listener;
private final PaymentAppInfo appInfo; private final PaymentAppInfo appInfo;