I've been using StackOverflow for years now, always finding answers to my questions before even asking them, but today I'm stuck.
As I happen to have a working POS terminal (the EMV Chip&Pin kind), I wanted to look into host card emulation.
The terminal works with the latest version of Tapp, so I know that the terminal is good and that my N7 with Kitkat can actually do payment (or at least the terminal do a series of good sounding bleeps and bloops, and the tablet launch Tapp's enrollment screen).
So I've read the manual(s) and written a bunch of lines with the objective of seeing something arrive on my HostApduService.
It partially works as I can find my dummy "card" in the Tap&Pay settings of the tablet.
But the "payment" part doesn't work: just two high-pitched bleeps from the POS terminal and nothing on the tablet. My HostApduService is not called.
I've tried all kind of different AIDs: real ones and silly ones, short and long, but nothing works.
When using Tapp, the LogCat says :
11-17 14:51:47.690: D/BrcmNfcJni(3183): RoutingManager::stackCallback: event=0x18
11-17 14:51:47.690: D/HostEmulationManager(3183): notifyHostEmulationActivated
11-17 14:51:47.690: D/BrcmNfcJni(3183): RoutingManager::stackCallback: event=0x17
11-17 14:51:47.690: D/BrcmNfcJni(3183): RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=20
11-17 14:51:47.690: D/HostEmulationManager(3183): notifyHostEmulationData
11-17 14:51:47.700: D/HostEmulationManager(3183): Service already bound as payment service.
11-17 14:51:47.700: D/HostEmulationManager(3183): Binding to existing service
11-17 14:51:49.932: D/BrcmNfcJni(3183): RoutingManager::stackCallback: event=0x19
11-17 14:51:49.932: D/HostEmulationManager(3183): notifyHostEmulationDeactivated
11-17 14:51:49.932: E/BrcmNfcNfa(3183): UICC[0x0] is not activated
And with my code, the LogCat is :
11-17 14:41:52.079: D/BrcmNfcJni(3183): RoutingManager::stackCallback: event=0x18
11-17 14:41:52.079: D/HostEmulationManager(3183): notifyHostEmulationActivated
11-17 14:41:52.089: D/BrcmNfcJni(3183): RoutingManager::stackCallback: event=0x17
11-17 14:41:52.089: D/BrcmNfcJni(3183): RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=20
11-17 14:41:52.089: D/HostEmulationManager(3183): notifyHostEmulationData
11-17 14:41:53.340: D/BrcmNfcJni(3183): RoutingManager::stackCallback: event=0x19
11-17 14:41:53.340: D/HostEmulationManager(3183): notifyHostEmulationDeactivated
11-17 14:41:53.340: E/BrcmNfcNfa(3183): UICC[0x0] is not activated
Obviously with my code, the OS doesn't bind the HCE intent to my service. But why?
You'll find below my manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.remolagi.hcetestbanque2"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc.hce"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="net.remolagi.hcetestbanque2.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyHCEService"
android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE" >
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="#xml/apduservice" />
</service>
</application>
</manifest>
my apduservice.xml :
<?xml version="1.0" encoding="UTF-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/servicedesc"
android:requireDeviceUnlock="true"
android:apduServiceBanner="#drawable/payment_banner">
<aid-group android:description="#string/aiddescription"
android:category="payment">
<aid-filter android:name="A0000000031010"/>
</aid-group>
</host-apdu-service>
And for good measure, the service (as you can see at the moment, it does nothing except Logging) :
package net.remolagi.hcetestbanque2;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.util.Log;
public class MyHCEService extends HostApduService {
private static final String TAG = "MyHCEService";
#Override
public void onDeactivated(int arg0) {
Log.i(TAG, "OnDeactivated - arg0 : " + String.valueOf(arg0));
// TODO Auto-generated method stub
}
#Override
public byte[] processCommandApdu(byte[] arg0, Bundle arg1) {
Log.i(TAG, "Hooza ! processCommandApdu");
return arg0;
}
}
If you have ideas on why it doesn't work, I'll be forever grateful. For now, I'm stumped.
Regards
Philippe
The first applet that will be selected by a EMV terminal is the PPSE applet, so you can try to add it also to your AID filters:
<aid-filter android:name="325041592E5359532E4444463031"/>
I don't know why you are trying to emulate payment with HCE but this will never be approved by Visa and MasterCard since for EMV transaction you need a cryptographic keys that need to be stored in secure environment. In the best case the HCE can be used for card not present transactions.
host-apdu-service structure example:
For HCE application is really necessary to include PPSE AID entry:
apduservice.xml file:
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/servicedesc"
android:requireDeviceUnlock="false" >
<aid-group
android:category="payment"
android:description="#string/aiddescription" >
<!-- Visa Proximity Payment System Environment - PPSE (2PAY.SYS.DDF01) -->
<aid-filter android:name="325041592E5359532E4444463031" />
<!-- VISA Debit/Credit (Classic) -->
<aid-filter android:name="A0000000031010" />
<!-- VISA Credit -->
<aid-filter android:name="A000000003101001" />
<!-- VISA Debit -->
<aid-filter android:name="A000000003101002" />
<!-- VISA Electron (Debit) -->
<aid-filter android:name="A0000000032010" />
<!-- V PAY -->
<aid-filter android:name="A0000000032020" />
<!-- VISA Interlink -->
<aid-filter android:name="A0000000033010" />
<!-- MasterCard PayPass -->
<aid-filter android:name="A00000000401" />
<!-- MasterCard Credit -->
<aid-filter android:name="A0000000041010" />
<!-- American Express -->
<aid-filter android:name="A000000025" />
<!-- BRADESCO -->
<aid-filter android:name="F0000000030001" />
</aid-group>
</host-apdu-service>
In 2013, best answer said "I don't know why you are trying to emulate payment with HCE but this will never be approved by Visa and MasterCard". Oh then MasterCard would not have an official SDK to develop HCE payment applications right? How can you be so sure? For those reading this now, yes of course you can develop an Android HCE app, MasterCard has tons of documents about the best practices. However, it is not publicly open to everyone. I don't know if there is a way to get the SDK and the documents without working with an issuer. You may use EMVCo Books which are open to public, but it may be hard to implement the whole system using only those guides.
About secure environments, for instance, an RSA public key is multiplication of two big prime numbers. If you can find those prime numbers in time, you can be the master of the whole world. But you cannot find those numbers without trying for years (depending on key sizes) with today's computing power, which is proved by mathematicians with better vision than someone in this thread, I'm not going to say who. Whole internet works with public key encryption, you don't always need secure hardwares to keep your data private. There will always be a way, because you cannot reach infinite. When you do, it becomes finite, which doesn't make any sense, lol.
Lastly, "Someone can know everything, in a place where no one knows anything" (F.Y.)
I have noticed during my experiments that the POS device will try to select AID of its supported card scheme. You can check for supported schemes on the device by looking at symbols such as "Visa", "Mastercard" etc. There is a list of AIDs for these schemes at http://en.wikipedia.org/wiki/EMV down the page. So for example, if POS supports Mastercard credit/debit cards, you can try registering AID of mastercard:A0000000041010 as aid-filter in apduservice.xml without registering the AID for PPSE. Give it a go and let me know if it works please.
Edit: Please note that I have been using Vivo tech POS readers.
A list with the PPSE, Mastercard and Visa:
<aid-group android:description="paymentGroup" android:category="payment">
<aid-filter android:name="325041592E5359532E4444463031" android:description="ppse"/>
<aid-filter android:name="A0000000041010" android:description="MasterCard"/>
<aid-filter android:name="A0000000031010" android:description="Visa"/>
</aid-group>
Related
We have implemented android shortcuts. Testing of App actions on physical devices was fine, except for an issue with English Articles.
When English Articles appear as a part of a statement, the statement is not recognized as an action, and Assistant does not redirected to the app. For example, 'add note to Express Scheduler' is recognized, while 'add a note to Express Scheduler' is not.
My question is whether anybody have experienced similar issues?
Please, see capabilities segment extracted from shortcuts.xml. I am using actions.intent.CREATE_THING and actions.intent.GET_THING BIIs. I've listed one example above: 'add note to Express Scheduler' is recognized, while 'add a note to Express Scheduler' is not.
<capability android:name="actions.intent.CREATE_THING">
<intent>
<url-template android:value="https://vijac.ca/schedule{?name,description}" />
<parameter
android:name="thing.name"
android:key="name"
android:required="false" />
<parameter
android:name="thing.description"
android:key="description"
android:required="false" />
</intent>
</capability>
<capability android:name="actions.intent.GET_THING">
<intent>
<url-template android:value="https://vijac.ca/search{?name}" />
<parameter
android:name="thing.name"
android:key="name" />
</intent>
</capability>enter code here
Thank you!
I think what may be happening is that you have a very generic name of the thing ("a note"), when it is expecting to handle specific names which normally don't need an article ("Pixel 4", "Stairway to Heaven").
You may want to try one of these to address the problem:
The thing.name parameter for that BII allows for an inline inventory which is a way of setting allowable values and alises for those values. You can create an inventory item for note that has aliases such as "a note" and "note".
Consider using the actions.intent.CREATE_DIGITAL_DOCUMENT BII which indicates that it supports phrases such as "Create a note".
I have an android project and i want to use facebook account kit. I did all settings but when i run the project, i am getting this message;
E/AndroidRuntime: 500: Initialization error: 503: The Client Token must be specified in the string resource file as com.facebook.accountkit.ClientToken
But i specified it in strings.xml
<string name="ACCOUNT_KIT_CLIENT_TOKEN">***</string>
AndroidManifest.xml
<meta-data android:name="com.facebook.accountkit.ClientToken"
android:value="#string/ACCOUNT_KIT_CLIENT_TOKEN" />
Waiting for your helps, thank you.
For me solution was adding following to the manifest file:
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>
<meta-data android:name="com.facebook.accountkit.ApplicationName"
android:value="#string/app_name"/>
<meta-data
android:name="com.facebook.accountkit.ClientToken"
android:value="#string/ACCOUNT_KIT_CLIENT_TOKEN" />
And the creating the respective String resources as:
facebook_app_id with app id, found at top-left corner next to navigation pane of facebook developer console for your app.
app_name which is already defined generally in your string resource file with the name of your app.
ACCOUNT_KIT_CLIENT_TOKEN with value found at Settings>advanced in navigation drawer of facebook developer console. Then go to Security, there you will find "Client Token". Use this client token value for value of this String resource.
This worked for me. Hope this helps.
You should have something like this in string resources (you have to get the app_id)
<string name="facebook_app_id">2077942129****</string>
and in you Manifest:
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
Check the attached to find to solution click on your products then go account-kit-->settings
I am working on HCE based App that will require payment through NFC at POS terminal.
I have followed the HCE article on android developers site and I am able to add the banner for card during installation through below code :
<host-apdu-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:requireDeviceUnlock="true"
android:apduServiceBanner="#drawable/servicebanner">
<aid-group android:category="payment"
android:description="#string/paymentGroup" >
<aid-filter ... />
</aid-group>
</host-apdu-service>
But I want to add the banner when the user clicks on ADD CARD button in my app.
Can we add the banner image dynamically on button click ?
Thanks
Where can I find the complete list of the type used in MediaCodec.createDecoderByType (String type)?
Google's document only gives a partial list.
Update[2015-06-03]
Per pskink's tip, I ran a piece of code to extract all the decode's MIME types on an Asus MeMO tablet. Here is the list
video/avc
video/3gpp
video/mp4v-es
audio/3gpp
audio/amr-wb
audio/mp4a-latm
audio/flac
audio/mp4a-latm
Using the method suggested by fadden(adb shell cat /system/etc/media_codecs.xml), I got the following
<MediaCodec name="OMX.WMT.decoder.h263" type="video/3gpp" >
<Quirk name="requires-allocate-on-output-ports" />
</MediaCodec>
<MediaCodec name="OMX.WMT.decoder.avc" type="video/avc" >
<Quirk name="requires-allocate-on-output-ports" />
</MediaCodec>
<MediaCodec name="OMX.WMT.decoder.mpeg2v" type="video/mpeg2" >
<Quirk name="requires-allocate-on-output-ports" />
</MediaCodec>
<MediaCodec name="OMX.google.mp3.decoder" type="audio/mpeg" />
<MediaCodec name="OMX.google.amrnb.decoder" type="audio/3gpp" />
<MediaCodec name="OMX.google.amrwb.decoder" type="audio/amr-wb" />
<MediaCodec name="OMX.google.aac.decoder" type="audio/mp4a-latm" />
<MediaCodec name="OMX.google.g711.alaw.decoder" type="audio/g711-alaw" />
<MediaCodec name="OMX.google.g711.mlaw.decoder" type="audio/g711-mlaw" />
<MediaCodec name="OMX.google.vorbis.decoder" type="audio/vorbis" />
<MediaCodec name="OMX.google.mpeg4.decoder" type="video/mp4v-es" />
<MediaCodec name="OMX.google.h263.decoder" type="video/3gpp" />
<MediaCodec name="OMX.google.h264.decoder" type="video/avc" />
<MediaCodec name="OMX.google.vpx.decoder" type="video/x-vnd.on2.vp8" />
Now I am suspecting that not every decoder declared in media_codecs.xml has been actually implemented.
Update[2015-06-13]
Very useful information provided by #fadden:
CDD sections 5.1.1 - 5.1.3 "Video Codecs" list all audio, image and video codecs that all Android devices are required to support. I am not sure how many devices meet the requirement. My two Android devices miss many required codecs.
List of codecs is completely dependent on a particular device. You have to enum all available codecs using MediaCodecList and call MediaCodec.createDecoderByType for the right one.
I have implemented google map in my app.But its display only blank grids.I have done changes in AndroidManifest.xml file and also included API key in layout file of map activity.
This may sound silly, but I kept encountering this problem until I realized that the <uses-permission> tags need to be direct children to the <manifest> element, rather than the <application> element. I had erroneously been putting them right after the <uses-library> tag. So the final structure of your AndroidManifest.xml file should be something like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<uses-sdk ... />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application ... >
<activity ... >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps" />
</application>
</manifest>
Hope this helps anyone who was making the same mistake!
I was having the same problems until I realised that in the API console I had enabled
Google Maps API v2
and not the
Google Maps Android API v2
Once I enabled it everything was fine.
The problem is the code API. Use the following function to see if the Key Google Maps is correct:
private String getShaKey() {
//fucnion para saber si esta bien registrado el codigo de googlemaps
//ME SALE EXCEPTION DE NOMBRE NO ENCONTRADO?¿?¿
String strRet="";
try {
PackageInfo info = getPackageManager().getPackageInfo("your.package.name",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
//Log.v(TAG, "KeyHash:" + Base64.encodeToString(md.digest(),
strRet="KeyHash:" + Base64.encodeToString(md.digest(),Base64.DEFAULT);
}
} catch (NameNotFoundException e) {
//e.printStackTrace();
strRet="EXCEPTION NOMBRE NO ENCONTRADO";
} catch (NoSuchAlgorithmException e) {
//e.printStackTrace();
strRet="EXCEPTION ALGORITMO NO";
}
return strRet;
}
This happens to me also. On the first time I successfully launched the Google maps, in works fine, on the second day, the entire map(default view) is rendered only in half while the other half are filled with tiles only, after changing some properties in the map, it all went to tiles only.
Now, what I did is I renew my API key and everything went fine.
This happened to me when I launched the map as intent (Intent intent = new Intent(android.content.Intent.ACTION_VIEW, mapUrl) ...). The map was created empty and did not load anything. The map showed my icon as "logged in user" in the top right corner, but no error messages at all. Everything worked flawlessly on the emulator. Finally, I checked the normal Google Map App and it was empty too.
Solution: Remove my Google account from Settings App of the development device. It took me several hours to figure that out. No clue what that was, but maybe it saves someone time to know.
I had the same problem. I added this line on the Manifest.xml and everything is working fine now :
<uses-library android:name="com.google.android.maps" />