Let's say I have a server app that declares a custom permission called com.testpackage.mypermission, which is needed to start ServerActivity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testpackage.myserver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<permission android:name="com.testpackage.mypermission" android:label="my_permission" android:protectionLevel="signature"></permission>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:permission="com.testpackage.mypermission"
android:name=".ServerActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
Then I have a client app that request com.testpackage.mypermission in its Manifest:
<uses-permission android:name="com.testpackage.mypermission" />
I know that if the 2 apps are signed with different certificates, client app won't be able to start com.testpackage.myserver.ServerActivity because of protectionLevel=signature.
My question is:
If server app is already installed, and then I want to install
client app, are their signatures checked at that moment? Or is it only checked at run time when you do startActivity(ServerActivity) in client app?
From my experience the answer to Q.1 seems to be runtime only. This confuses me, because standard system permissions (eg. android.permission.CAMERA) are checked at install time. So are custom permission and standard permission treated differently?
Thanks
Related
Following is the AndroidManifest.xml for a Simple Bluetooth pairing Android Project
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetoothglassend"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="19" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="19" />
<uses-permission
android:name="android.permission.BLUETOOTH_PRIVILEGED"
android:maxSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Although not required, I've added permissions for all BLUETOOTH parameters I can find. Yet, I get this error :
java.lang.SecurityException: Need BLUETOOTH permission: Neither user 10145 nor current process has android.permission.BLUETOOTH.
Any Ideas?
As an additional note, I imported this project in Android Studio from Intellij
The maxSdkVersion attribute version is for telling the highest API level at which this permission should be granted to your app. Setting this attribute is useful if the permission your app requires is no longer needed beginning at a certain API level.
For example, beginning with Android 4.4 (API level 19), it's no longer necessary for your app to request the WRITE_EXTERNAL_STORAGE permission when your app wants to write to its own application-specific directories on external storage (the directories provided by getExternalFilesDir()). However, the permission is required for API level 18 and lower. So you can declare that this permission is needed only up to API level 18 with a declaration such as this:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
This way, beginning with API level 19, the system will no longer grant your app the WRITE_EXTERNAL_STORAGE permission.
So the error was that even lollipop needs you to ask permission for accessing bluetooth.
Looks like it was a pretty straightforward solution. I was testing on Android Lollipop ( > maxSdkVersion ) hence the error.
I have developped an applicaction that basically download a file from a Server via Bluetooth and store it in the memory of the mobile phone.
I read what is needed to publish and application in http://developer.android.com/tools/publishing/publishing_overview.html
and I followed the steps:
Remove any "android:debuggable" in the Android Manifest.
Remove any Log calls
Sign the file: Right click on the project->Export -> Android ->
Export Android Application ... during the process I use an
AppKey.keystored that I created before.
I apply Zipalign
http://developer.android.com/tools/publishing/app-signing.html#signing-manually
Once I finish that I upload the App to the Google Play Store.
I downloaded it with three diferent devices, with the following version of Android:
4.2.2 (It is the one I used to develop, debbug and test the App while writting it on Eclipse)
4.3
4.4
But it only works properly in the device with 4.2.2. In the other two devices the Application crash when I launch it.
This is the Android manifest of the Application, all the code is too long to upload it here. But I feel there problem must be or in the manifest or in the way I'm exporting/signing the file.apk
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cliente_bluetooth"
android:versionCode="3"
android:versionName="1.3" >
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.cliente_bluetooth.Cliente_Bluetooth"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is the link of the App in the Play Store:
https://play.google.com/store/apps/details?id=com.cliente_bluetooth
Can anyone find a mistake in the process of publishing? am I skipping or missunderstanding any step?
Thank you very much for your time
Basically, I searched through all the internet and found big, fat zero about that.
My app is using sms sending service and I need SMS_SEND permission. When I add it and run - Eclipse says that I have errors in my code AND antivirus alert that they blocked Android.Trojan.SMS_SEND.NR. I don't care about the latter - because it doesn't show up without SMS_SEND permission.
All I found is in Lint Error Checking:
"Looks for permissions that are only granted to system apps
Permissions with the protection level signature or signatureOrSystem are only granted to system apps. If an app is a regular non-system app, it will never be able to use these permissions."
BUT what matters the most - other app tha use that permission is fine. So what could happened? I need that service to be in that app.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypackage.etc"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.SEND_SMS" />
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<activity
android:name=".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>
</application>
Your Android AV Software (F-Secure?) is blocking the code probably based on heuristics or signature. As most if not all Android AV Software is worthless I'd remove that first. Assuming you are not using a rooted device it must simply be picking this up from a manifest scan or some use of the Package Manager.
The "signature or signatureOrSystem" is not applicable to the SEND_SMS permission and whilst you may find a use for using the signature permission cross (identically signed) applications, it is unlikely you are using this.
Please show us your manifest.
I am trying to upload my apk to the google store and it says You uploaded a debuggable APK. For security reasons you need to disable debugging before it can be published in Google Play.
I have added android:debuggable="false" and i am signing it in release mode with a unique key still I am getting the error. I am building using xamarin
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mycompApp.MyApp" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<application android:label="MyApp" android:icon="#drawable/Icon" android:hardwareAccelerated="true" android:debuggable="false">
<activity android:name=".MainActivity" android:label="MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"></activity>
<!-- Only C2DM servers can send messages for the app. If permission is not set - any other app can generate it -->
</application>
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The problem was that the androidmanifest.xml was showing some windows encoding instaed of and this was not throwing any error in xamarin. i changed it to utf-8 and it got uploaded
Xamarin Studio doesn't always update well changes in AndroidManifest. I could solve the same issue by manually deleting the Droid/obj/Release/android folder in my project directory, then clean + build + package. The new package was accepted by Google Play.
I try to write files to the external SD card in a from InstrumentationTestCase2 derived test case for pure testing purposes. This works all well when android.permission.WRITE_EXTERNAL_STORAGE is configured in the AndroidManifest.xml file of the application under test, but does not work if this setting is only present in the AndroidManifest.xml file of the test project.
Naturally, I don't want to add this permission to the main manifest, since I only need this capability during my functional tests. How can I achieve that?
In short you should add the same android:sharedUserId for both application's manifest and test project's manifest and declare necessary permission for the test project.
This workaround comes from the fact that Android actually assigns permissions to linux user accounts (uids) but not to application themselves (by default every application gets its own uid so it looks like permissions are set per an application).
Applictions that are signed with the same certificate can however share the same uid. As a consequence they have a common set of permissions. For example, I can have application A that requests WRITE_EXTERNAL_STORAGE permission and application B that requests INTERNET permission. Both A and B are signed by the same certificate (let's say debug one). In AndroidManifest.xml files for A and B android:sharedUserId="test.shared.id" is declared in <manifest> tag. Then both A and B can access network and write to sdcard even though they declare only part of needed permissions because permissions are assigned per uid. Of course, this works only if both A and B are actually installed.
Here is an example of how to set up in case of the test project. The AndroidManifest.xml for application:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.example.testproject.uid">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name="com.example.testproject.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>
</application>
</manifest>
And the AndroidManifest.xml for a test project
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject.test"
android:sharedUserId="com.example.testproject.uid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.testproject" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
The drawback of this solution is that the application is able to write to external storage too when test package is installed. If it accidentally writes something to a storage it may remain unnoticed until release when the package will be signed with a different key.
Some additional information about shared UIDs can be found at http://developer.android.com/guide/topics/security/permissions.html#userid.
There is another easy answer.
Set the permission in src/debug/AndroidManifest.xml. If the file doesn't exist, create it.
By default, AndroidTest uses debug as BuildType, so if you define your testing permissions there, then the manifest merging process will add these permissions to your UI test build.
Here is the Manifest with new permissions. Note that I didn't include the package attribute because it will be inherited from lower priority level manifest.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
Also, if you want to apply these permissions to a buildType other than debug, then just move your new AndroidManifest.xml to the folder you want, and use this:
android {
...
testBuildType 'release' // or other buildType you might have like 'testUI'
}