Merge "Latest UX for Tap & pay." into klp-dev
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -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"
|
||||||
|
23
res/menu/nfc_payment_settings.xml
Normal 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>
|
@@ -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>
|
||||||
|
@@ -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 & 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 & 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 & 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 & pay?</string>
|
||||||
<!-- Restrictions settings --><skip/>
|
<!-- Restrictions settings --><skip/>
|
||||||
|
|
||||||
<!-- Restriction settings title [CHAR LIMIT=35] -->
|
<!-- Restriction settings title [CHAR LIMIT=35] -->
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|