HCE service and BIND_NFC_SERVICE permission - android

First of all I'm fairly new to programming Android apps. My programing language is Java. I searched for a solution on the web and asked other programmers with no solution.
Situation:
I have developed an application that uses the HCE service. This application is triggered by another device and data is transferred using ISO 7816-4 APDU commands. Everything is working as expected and the app is selected using an AID.
Problem:
The app was developed on a NEXUS 4 with Android 5.1.1 running. By the time I got newer NFC enabled phones on my desk to test the app.
All of them are Android 6 or newer. Non of them is working with my app. It seems that the permission BIND_NFC_SERVICE is not granted. Since the way permissions are handled changed since Android 5 to 6 update I implemented the new method mentioned by Android developer request app permissions (I also checked the related posts here). The permission is just denied with no further information. On the NFC interface the APDU trying to select the app by its AID is returned with 6999 meaning the operation is not allowed.
On a rooted phone I can see that the permission is denied and I tried to grant it manually. But after every start of the app it is denied again and the app can never use it.
Seems like the HCE service itself has to ask for the permission, but how?
Below you can find my AndroidManifest.xml and the build.gradle. I also tried to change to a higher API level.
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.XXXXXXXX.hce_tests">
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-feature
android:name="android.hardware.nfc.hce"
android:required="true" />
<uses-permission android:name="android.permission.BIND_NFC_SERVICE"/>
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
<service
android:name=".MyHostApduService" android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
</intent-filter>
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="#xml/apduservice" />
</service>
<activity android:name=".AutoTuneInterface"></activity>
</application>
</manifest>
build.gradle
android {
compileSdkVersion 23
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "com.example.XXXXXXXX.hce_tests"
minSdkVersion 19
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-
core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
implementation project(':GraphView')
}
Thanks for your help!

BIND_NFC_SERVICE Permission
You are not supposed to request the permission BIND_NFC_SERVICE from your app. This permission is reserved for the NFC system service and this service should be the only application that holds that permission.
Instead, your app needs to enforce this permission when an application tries to bind to your HCE service component. You already do that with
<service android:name=".MyHostApduService"
android:permission="android.permission.BIND_NFC_SERVICE"
That way, Android prevents injection of APDUs into your HCE service by other (malicious) apps, since no (malicious) app could bind to your HCE service.
Error 6999
Why Android does not detect your HCE service and returns 6999 to indicate that the AID was not found, is a trickier question. I could think of a few reasons:
Your service is not explicitly marked as exported (add the attribute android:exported="true" to the service component). However, this should not matter since the HCE service also declares an intent filter which implicitly sets the exported attribute true.
If your app is flagged as a payment app (in apduservice.xml), you will need to make sure that it is the selected payment app ("Tap & pay" in the Settings app).
Some devices do not seem to support HCE and a secure element in parallel and have a switch to choose between the secure element and HCE somewhere in the Settings app (probably also within the Tap & pay settings).

Related

My app is not installing in signed apk mode

I have developed a android application . which is about maintaining the house . i have work with firebase in that application. now the problem is when i install that app in my android phone via usb cable from android studio it's run perfectly. but if i want share the app with someone via share it it's not working. (app not installed) a error come, why . ?? even if i am generate signed apk from android studio then it's also showing the same error . why ? any solution please.
and here the manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sonalirod.alwayswhite">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/lastfinalw"
android:label="#string/app_name"
android:roundIcon="#mipmap/lastfinalw"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Firstscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Login" />
<activity android:name=".Interface" />
<activity android:name=".MainActivity" />
<activity android:name=".Bazar_Data_Input" />
<activity android:name=".MealEntry" />
<activity android:name=".Suggestion" />
<activity android:name=".admininterface" />
<activity android:name=".ALogin" />
<activity android:name=".AdminloginEnter" />
<activity android:name=".Showalldeposit"></activity>
</application>
</manifest>
gradle settings
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.sonalirod.alwayswhite"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
and i am trying to install in android 4.4.2 (api 19-20)
CommonsWare explained it all.
https://commonsware.com/blog/2017/10/31/android-studio-3p0-flag-test-only.html
Distributing APKs outside of GooglePlay to users need then to accept installing from Unknow Sources.
This options is under Settings > Security.. "Unknow sources"
Based in the link form other answer:
"
Android Studio 3.0 sets android:testOnly="true" on APKs that are run from the IDE
For many developers, this is of little consequence. However, if you have ever taken an APK lying around your build/ directory and sent it to somebody, that will only work if you did something other than run the app in Android Studio in order to create that APK, such as:
Built the app using the “Build APK(s)” menu option
Built the app using the assembleDebug or assembleRelease Gradle tasks
Built the app using something else that might use those tasks, such as a CI server
"
Are you building the application as release right?

Android permissions in regard of Warning of Google Play Developer policy violation: Action Required

I have an app on Google Play Store which I created and shows the location of all the cars that are parked in Kortrijk that are registered by sensors real-time and the app shows all those parked cars and free places to park on a Googlemap mapview.
However, I received a couple of days ago a warning of Google Play Developer that requires an action of a privacy policy.
My manifest is like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.programmeercursussen.parkingkortrijk" >
<!-- Internet permission for network operations -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Creating Permission to receive Google Maps -->
<permission
android:name="be.programmeercursussen.parkingkortrijk.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<application
android:allowBackup="true"
android:icon="#drawable/parking_icon"
android:label="#string/app_name"
android:theme="#style/MaterialTheme" >
-->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my Api key ..." />
<!-- SplashScreen => startup screen -->
<activity
android:name=".SplashScreen"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Main activity -->
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
</activity>
<!-- ParkingDetail activity -->
<activity
android:name=".ParkingDetailActivity"
android:label="#string/title_activity_parking_detail"
android:screenOrientation="portrait" >
</activity>
<!-- StraatParkeren activity -->
<activity
android:name=".StraatParkeren"
android:label="#string/title_activity_straat_parkeren"
android:screenOrientation="portrait" >
</activity>
</application>
In the Developer console it said i've got Get_accounts permission and this is a violation, but this permission isn't hardcoded in the app. But then i found out that Google Play services library automatically adds this i think? So my line for compiling
compile 'com.google.android.gms:play-services:7.5.0"
I changed into the selective API part
compile 'com.google.android.gms:play-services-maps:7.5.0"
Changing this line into this and generate the apk and try to install it, the issue of get_accounts is no longer there in the overview of what the app gets access to when installing on a smartphone.
So my dependencies in build.gradle are now:
dependencies {
/*
find latest gradle versions on : http://gradleplease.appspot.com/
*/
compile fileTree(dir: 'libs', include: ['*.jar'])
// appcompat library
compile 'com.android.support:appcompat-v7:22.2.1'
// material design library
compile 'com.android.support:design:22.2.1'
// recyclerview
compile 'com.android.support:recyclerview-v7:22.2.1'
// cardview
compile 'com.android.support:cardview-v7:22.2.1'
// google play services, selective API (maps) !!!
// https://developers.google.com/android/guides/setup#split
compile 'com.google.android.gms:play-services-maps:7.5.0'
// Jsoup library
compile 'org.jsoup:jsoup:1.8.3'
}
Now, if I generate the apk based on the manifest and build.gradle, it now says when installing the app will get access to:
- approximate location (network-based);
- modify or delete the contents of your SD card
- read the contents of your SD card
- view network state (full Internet access)
I am sure that view network state is required otherwise the app can't read the real-time xml from the Internet.
But I am not sure if approximate location will get me a new privacy violation?
Also I don't know why the app can read, modify or delete the contents of the sd-card as the app shouldn't be using those ... Are there any permission that are automatically set with the manifest and build.gradle?
Thanks for any help in advance,
Grtz Davy
No permissions are set with a standard manifest.
Since you're using a below 8.3 version of the MAPS api, you have to include
WRITE_EXTERNAL_STORAGE which causes the modify or delete content
https://developers.google.com/maps/documentation/android-api/config#specify_android_permissions
The location permission also comes with the MAPS api

Android Wear 2.0 getting location from phone and keeping device supported on Google Play store

Recently I've been making a Bus Checker app for Android Wear 2.0, as a standalone app so that iOS users can also use it.
I am obviously getting the location of the watch to get the local bus stops. This means I need to use the following permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Even though my Huawei Watch can get the location of the "watch" through the phone, when publishing the app to the Google Play store, it only becomes supported with the one device that supports GPS: the LG Watch Urbane 2nd Edition LTE.
I really don't know what to do here, I want to publish my app for devices that don't have GPS and just get GPS from the phone, but to get GPS from the phone I need those permissions and those permissions cause the Huawei Watch and other non-GPS devices to become unsupported.
I have tried adding this to my manifest to test whether the Huawei Watch would become supported:
<uses-feature android:name="android.hardware.LOCATION" android:required="false" />
<uses-feature android:name="android.hardware.location.GPS" android:required="false" />
<uses-feature android:name="android.hardware.location.NETWORK" android:required="false" />
But unfortunately, it didn't work. The compatibility is definitely based on the permissions and not the features required. I also tried this with a blank Hello World app to no avail.
If it is of any relevance, here is my app manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.buschecker.williamvenner.buschecker">
<uses-feature android:name="android.hardware.type.watch" android:required="true" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<application android:allowBackup="true" android:icon="#mipmap/ic_launcher"
android:label="#string/app_name" android:supportsRtl="true"
android:theme="#android:style/Theme.DeviceDefault">
<uses-library android:name="com.google.android.wearable" android:required="false" />
<activity android:name=".MainActivity" android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".BusStopView"
android:theme="#android:style/Theme.DeviceDefault.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
My Gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.buschecker.williamvenner.buschecker"
minSdkVersion 25
targetSdkVersion 25
versionCode 1
versionName "1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:2.0.0-beta2'
compile 'com.google.android.gms:play-services-wearable:10.0.1'
compile 'com.google.android.gms:play-services-location:10.0.1'
compile 'com.mcxiaoke.volley:library:1.0.19'
provided 'com.google.android.wearable:wearable:2.0.0-beta2'
wearApp project(':app')
}
My project structure can be found here.
Some permissions imply feature requirements.
The explicitly in the Manifest declaredared permission requirement ACCESS_FINE_LOCATION in the implies the requirement of android.hardware.location.gps
See Permissions that Imply Feature Requirements
So declaring the feature as not required
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
will not apply and not prevent the Play Store from filtering your app out for GPS-less devices.
To avoid that, remove the request for ACCESS_FINE_LOCATION from your Manifest.
(But declare the feature requests for anroid.hardware.location and android.hardware.location.network as required to ensure the play store keeps filtering out the app for devices without any network hardware.)
And to ensure, your app can use GPS services on devices equipped with it, implement in your code a check, whether LocationManager.GPS_PROVIDER is included in the list of all availible providers.
E.g. as in GPS Manifest: GPS in App is optional, want to make it available to GPS less devices too:
locationManager = (LocationManager)
this.getSystemService(Context.LOCATION_SERVICE);
boolean deviceHasGPS = false;
if (locationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER)) {
deviceHasGPS = true;
}
You should really consider using FusedLocationProvider for the watch because watches like the Huawei one get their location from the phone. FusedLocationProvider makes it easy to not worry about where the location is coming from.
I'm using the fine location permission and have no issues with the app not showing up on the Huawei watch play store.

Setting Android Wear permissions in App with Android Studio

All:
I got one of those Android Privacy Policy notifications for an Android watch face I wrote. I wrote it in Android Studio, and it has the following permissions:
android.permission.ACCESS_NETWORK_STATE
android.permission.GET_ACCOUNTS
android.permission.INTERNET
android.permission.READ_EXTERNAL_STORAGE
android.permission.USE_CREDENTIALS
android.permission.WAKE_LOCK
android.permission.WRITE_EXTERNAL_STORAGE
com.google.android.c2dm.permission.RECEIVE
I really don't need all of those. I really think I only need the WAKE_LOCK and I think one other one. It shouldn't use any sort of writing, accessing networks, or any of that other stuff.
But the odd thing is, I can't find anywhere in my app where these permissions are located. This is my Wear manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-feature android:name="android.hardware.type.watch" />
<!-- Required to act as a custom watch face. -->
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault" >
<service
android:name=".MorseWatchFace"
android:label="#string/my_digital_name"
android:permission="android.permission.BIND_WALLPAPER" >
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="#drawable/preview_digital" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="#drawable/preview_digital_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
And this is my Mobile manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="monte.morsewatch">
<application android:allowBackup="true" android:label="#string/app_name"
android:icon="#mipmap/ic_launcher" android:theme="#style/AppTheme">
</application>
I know I'm missing something. The email said I had until January 30th to fix it, but I am unsure what I need to change to fix it.
Any help greatly appreciated.
Based from this documentation, the user must now grant permissions to Wear apps separately from the handset versions of the apps. Previously, when a user installed a Wear app, it automatically inherited the set of permissions that the user had granted to the handset version of the app. To declare that your app needs a permission, you're right in putting a <uses-permission> element in your app manifest, as a child of the top-level <manifest> element.
This SO thread might also help on how to remove unwanted permissions in your app.
The extra permissions are probably being added by some part of Google
Play Services - and which probably doesn't need them for what you're
doing.
Solution #1 is to only use the pieces of Google Play Services that you
actually need. In your Wear module's build.gradle file, you might
have an entry that looks like this:
dependencies {
compile com.google.android.gms:play-service:8.4.0
}
However, that will bring in the entire Play Services library -
which requires a number of extra permissions. It might well be that
all you need is this:
compile com.google.android.gms:play-services-wearable:8.4.0
...or perhaps other specific modules. But the point is, don't include
more than you need.
If you've pared the dependencies back as far as you can, and you're
still getting extra permissions in your merged manifest, then you may
need Solution #2 - which I described in detail in a different answer:
https://stackoverflow.com/a/31017339/252080
Hope this helps!

Migrated to Android Studio - now my app requests additional permissions

I just migrated an app from Eclipse to Android Studio. I tried exporting a signed APK and uploaded it to Google Play just to check that everything was working.
That's when I noticed that my app now requests two additional permissions except the ones that I have declared in my manifest! The two permissions are android.permission.WAKE_LOCK and com.google.android.c2dm.permission.RECEIVE.
What's going on here? I haven't changed any code since the last time I uploaded the app, and the manifest doesn't declare these permissions. I'm guessing some Google component is responsible for this, but why did this happen because I migrated to Android Studio? Can I turn off these permissions?
I'm using Google Play Services and Google AdMob, but I've been doing that for a long time without these permissions...
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app"
android:versionCode="70"
android:versionName="7.0" >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="23" />
<application android:name="com.example.app.MyApplication"
android:icon="#mipmap/ic_launcher_icon"
android:label="#string/app_name"
android:allowBackup="true"
android:uiOptions="none">
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity android:name="com.example.app.MainActivity"
android:label="#string/app_name"
android:theme="#style/Theme.MyTheme.App"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.app.OtherActivity"
android:label="#string/otherActivityTitle"
android:theme="#style/Theme.MyTheme.App"
android:parentActivityName="com.example.app.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app.MainActivity" />
</activity>
<activity
android:name="com.example.app.PreferencesActivity"
android:label="#string/prefsTitle" >
</activity>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
</application>
</manifest>
Here's a screenshot of the APK built using Android Studio:
I couldn't change the language to english, but it basically says it's now supporting 22 less devices, requires 2 new permissions and uses OpenGL 2.0+ instead of 1.0+.
Here's a screenshot of the same APK built using Eclipse:
After some more searching I found this thread on Stackoverflow: Android Studio adds unwanted permission after running application on real device.
One of the answers there (not the accepted one) solved my issues. It seems that the Android Studio import process added this dependency to my build.gradle:
compile 'com.google.android.gms:play-services:+'
After changing it to
compile 'com.google.android.gms:play-services-base:8.4.0' // Needed for API Availability test
compile 'com.google.android.gms:play-services-ads:8.4.0'
compile 'com.google.android.gms:play-services-analytics:8.4.0'
the APK no longer requests the unwanted permissions, it targets the same devices as before and uses the same OpenGL version as before - i.e. everything is back the way it was with Eclipse! Except now the file size of the APK is 1 MB smaller as an added bonus!
For people coming here in the future, you might want to investigate what Google Play Services version numbers you should use at Gradle, please and/or Setting up Google Play Services.
Change it to:
android:targetSdkVersion="22"

Categories

Resources