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:gravity="center_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
|
||||
android:id="@+id/nfc_payment_tap_image"
|
||||
android:layout_width="fill_parent"
|
||||
@@ -23,6 +14,15 @@
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
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>
|
||||
<ListView
|
||||
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>
|
||||
<!-- Default query string to search for a print service. -->
|
||||
<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>
|
||||
|
@@ -4755,14 +4755,15 @@
|
||||
<string name="global_font_change_title">Change font size</string>
|
||||
|
||||
<!-- 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 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
|
||||
preferred payment application -->
|
||||
<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_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">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 & pay?</string>
|
||||
<!-- Restrictions settings --><skip/>
|
||||
|
||||
<!-- Restriction settings title [CHAR LIMIT=35] -->
|
||||
|
@@ -61,8 +61,11 @@ public class PaymentBackend {
|
||||
|
||||
for (ApduServiceInfo service : serviceInfos) {
|
||||
PaymentAppInfo appInfo = new PaymentAppInfo();
|
||||
appInfo.caption = service.loadLabel(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.componentName = service.getComponent();
|
||||
appInfos.add(appInfo);
|
||||
|
@@ -21,8 +21,12 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.nfc.cardemulation.ApduServiceInfo;
|
||||
import android.nfc.cardemulation.CardEmulation;
|
||||
import android.nfc.cardemulation.HostApduService;
|
||||
import android.nfc.cardemulation.OffHostApduService;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -31,8 +35,11 @@ import com.android.internal.app.AlertController;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
@@ -81,17 +88,20 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
}
|
||||
|
||||
// Check if passed in service exists
|
||||
boolean found = false;
|
||||
PaymentAppInfo requestedPaymentApp = null;
|
||||
PaymentAppInfo defaultPaymentApp = null;
|
||||
|
||||
List<PaymentAppInfo> services = mBackend.getPaymentAppInfos();
|
||||
for (PaymentAppInfo service : services) {
|
||||
if (component.equals(service.componentName)) {
|
||||
found = true;
|
||||
break;
|
||||
requestedPaymentApp = service;
|
||||
}
|
||||
if (service.isDefault) {
|
||||
defaultPaymentApp = service;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (requestedPaymentApp == null) {
|
||||
Log.e(TAG, "Component " + component + " is not a registered payment service.");
|
||||
return false;
|
||||
}
|
||||
@@ -103,36 +113,18 @@ public final class PaymentDefaultDialog extends AlertActivity implements
|
||||
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;
|
||||
|
||||
// Compose dialog; get
|
||||
final AlertController.AlertParams p = mAlertParams;
|
||||
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 msg = String.format(formatString, newAppInfo.loadLabel(pm));
|
||||
String msg = String.format(formatString, requestedPaymentApp.caption);
|
||||
p.mMessage = msg;
|
||||
} else {
|
||||
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.mPositiveButtonText = getString(R.string.yes);
|
||||
|
@@ -17,12 +17,19 @@
|
||||
package com.android.settings.nfc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
@@ -30,6 +37,7 @@ import android.widget.ImageView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
|
||||
@@ -42,6 +50,8 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
|
||||
private LayoutInflater mInflater;
|
||||
private PaymentBackend mPaymentBackend;
|
||||
|
||||
private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
@@ -50,12 +60,12 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
|
||||
setHasOptionsMenu(false);
|
||||
mPaymentBackend = new PaymentBackend(getActivity());
|
||||
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
PreferenceManager manager = getPreferenceManager();
|
||||
PreferenceScreen screen = manager.createPreferenceScreen(getActivity());
|
||||
|
||||
// Get all payment services
|
||||
List<PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos();
|
||||
if (appInfos != null && appInfos.size() > 0) {
|
||||
@@ -80,17 +90,15 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
|
||||
} else {
|
||||
emptyText.setVisibility(View.GONE);
|
||||
emptyImage.setVisibility(View.GONE);
|
||||
setPreferenceScreen(screen);
|
||||
}
|
||||
setPreferenceScreen(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
View v = mInflater.inflate(R.layout.nfc_payment, container, false);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -108,9 +116,54 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
|
||||
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 {
|
||||
private final OnClickListener listener;
|
||||
private final PaymentAppInfo appInfo;
|
||||
|