I am trying to build an application that would replace a default action on Android. The problem is that when action should be performed i get "Select Action" dialog with no checkbox to select it as default. I think i should be getting "Complete Action Using" dialog (which in turn has the checkbox). I do not understand how I can make Android to offer me the "Complete ..." dialog. My manifest file is as:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="si.cetrtapot.mobiris"
android:versionName="1.0"
android:versionCode="1" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc"
android:required="true" />
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:debuggable="true" >
<activity android:name=".ReadTagActivity"
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>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc" />
</activity>
</application>
</manifest>
Can anybody tell me what is wrong?
The way intent-filters work is that the PackageManager has all these applications registered with it via the Manifest that is found per application. Specifically when an application falls un a certain Intent-Filter, it will then be added to the list of applications that have those kinds of Intent-Filters declared in their Manifest.
For instance say my application, handles the: Intent.ACTION_SEND this means that my application will show up in the list of application that hand particular action. Which would include, the default MMS/SMS application and any other applications the user has that has this, including MY application if the user has it installed.
You should begin by understanding what "default action" even means. Understanding this will help you how to solve your problem.
For your reference:
Intent
Intent.CATEGORY_DEFAULT
I do not believe that anything is wrong. I don't believe NFC intents were meant to have a default app unless you have very specific intent filtering for Ndef formatted cards. I did this for my job because we wanted just our app to pop up with our tag. Otherwise it would just be in a list all the time (which is annoying).
Related
We, my company, are facing a problem. We have a phone in public use where we can't be always near the phone. It's a show room where public user can test our Android app.
The problem is :
1) Can we block the phone in our app ? we just pin it but it doesn't block the phone. We found some apps the make something like that but not good results
2) A test user just add a security password to lock the phone. So now, we can't unlock the phone. We need to forbid user to add a lock password but we don't want to add one because if the phone is sleeping, a user should be able to unlock it.
**Edit : ** We can't block user from accessing settings
So, is there a solution for that ? like a "ShowRoom" mod ?
If you need more precisions, please ask.
Thanks
First you need to add the following attribute to your activity:
android:launchMode="singleTask"
Then add two categories to the intent filter :
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.HOME" />
The result could look something like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dummy.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.dummy.app.MainActivity"
android:launchMode="singleTask"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>
</application>
</manifest>
please read this answer to block exiting app
https://stackoverflow.com/a/16333555/5223973
if you want to use any third party app to lock your app you can use any
android parental control apps
We've developed an app that requieres a second app (pro key app) to validate its license. The main (free app) request, via broadcast, to the pro key app to check the license.
The problem is that when the pro key app is closed it never receives the broadcast sent by the main app, to workaround this problem I have to open the pro key app before and then try to verify the license again.
Here is how the main app sends it:
public static void checkLicense(Context context) {
...
Intent checkLicenseIntent = new Intent(Constants.CHECK_LICENSE_INTENT);
context.sendBroadcast(checkLicenseIntent);
...
}
Here is the pro key app's manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ar.com.myapp.prokey"
android:versionCode="2"
android:versionName="1.0.0.1" >
<permission
android:name="ar.com.myapp.prokey.CheckLicense"
android:protectionLevel="signature" />
<uses-permission android:name="ar.com.myapp.ReceiveLicenseCheckResponse" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="ar.com.myapp.prokey.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>
<receiver
android:name="ar.com.myapp.prokey.CheckLicenseReceiver"
android:permission="ar.com.myapp.prokey.CheckLicense" >
<intent-filter >
<action android:name="ar.com.myapp.prokey.CHECK_LICENSE" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</receiver>
<service android:name="ar.com.myapp.prokey.LicenseVerificationService" />
</application>
</manifest>
Is this the way to communicate the apps? Should the broadcast wake up the key pro app or not?
Any ideas?
If your app is in "stopped" state it will not be able to receive any intents. You need to "activate" the app by activating any of its components. If you use setComponent() on the broadcasted intent, the system will activate the app before sending the intent.
Add this line to your code:
Intent checkLicenseIntent = new Intent(Constants.CHECK_LICENSE_INTENT);
checkLicenseIntent.setComponent(new ComponentName("ar.com.myapp.prokey", "ar.com.myapp.prokey.CheckLicenseReceiver"));
context.sendBroadcast(checkLicenseIntent);
You can read more on this article: https://devmaze.wordpress.com/2011/12/05/activating-applications/
Should the broadcast wake up the key pro app or not?
If by "wake up" you mean "fork a process for it", then yes, it will, once you fix your <intent-filter>, by getting rid of the two <category> elements, as your Intent that you are broadcasting does not have a category. Categories are rarely used with broadcasts.
Also bear in mind that custom permissions have security issues.
I am making an app that communicates with a piece of usb hardware made by my company (this is the only app allowed to talk to the usb accessory, it's not a public api). I am having difficulties setting up the proper launch modes in the manifest.
There are three components to the app: the main activity, a login activity, and the USBService.
I'm assuming the intent for the main goes to the login activity, and the intent for the usb goes to the USBService, but I am not sure if I do this, will this start the service if the app is not running? More over, if it does, how do I fetch an already existing service?
What type of structure should I be looking at for the manifest file? (specifically, intent-filters, and appropriate launch modes... I've read a few documents about the launch modes but I am still not sure I quite understand... There should only ever be at most one instance of each activity/service, and they need to communicate together.
edit: it is not necessary for communications to start before the app is open, nor is it necessary to launch the app automatically when the usb is connected.
edit: my manifest as it stands, looks like:
<uses-feature android:name="android.hardware.usb.accessory" />
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="mainpackage.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
<activity
android:name="mainpackage.LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<service android:name="updater.USBService"
android:exported="false" >
<!--
-->
</service>
</application>
in your manifest add
<manifest ...>
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
In this case, the following resource file should be saved in res/xml/device_filter.xml and specifies that any USB device with the specified attributes should be filtered:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
</resources>
Hope this help.
Your manifest looks good,
I think you make a good choice for putting the intent-filter "android.hardware.usb.action.USB_ACCESSORY_ATTACHED" in the mainActivity and start the application in this activity,
and again I think it's a good choice to start your mainActivity in SingleTop launch mode,
because if an instance of the mainActivity already exists at the top of the current task, the system going to launch this activity, no new instance of this activity will be created.
For a best understanding of the different launch mode available in android,
I think this link may help you :
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
To make a long story short I think you'll be all set with this manifest as is.
To Use Android Devices min SDK version should be set to 12 and need to declare following line in AndroidManifest.xml file
<>
<uses-sdk android:minSdkVersion="<version>" />
...
<application>
<uses-library android:name="com.android.future.usb.accessory" />
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
</application>
I've got the following situation with a Phonegap 2.9 Android app:
I declared a custom intent so that the app can be opened from a website.
From within the app, I call an external site I control with a form.
On the page of the external site there's a button that is using the custom intent URL to get back to the app.
This construction works for the iOS version of the app, also using Phonegap.
However, for the Android version the popup of Android is saying it doesn't recognizes the custom URL / intent. When I open my browser and navigate to the same external site and pushes the back button with the custom intent-URL, the app gets started.
After searching hours and hours on stackoverflow and the internet in general, I still can't figure out why it isn't working like expected.
Perhaps good to know is that both the app and the external site are using jQuery Mobile.
The external site is opened from the app using
navigator.app.loadUrl('https://site.external/');
The page is on a HTTPS / SSL location, does this makes any difference?
The manifest looks like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="com.test.app" android:versionName="1.0" android:versionCode="1" android:hardwareAccelerated="true">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
<application android:icon="#drawable/icon" android:label="#string/app_name"
android:hardwareAccelerated="true"
android:debuggable="true"
android:allowBackup="false">
<activity android:name="AppName" android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:exported="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="customurl" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity
android:name="org.apache.cordova.DroidGap"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden">
<intent-filter></intent-filter>
</activity>
</application>
</manifest>
The code in the external page is using javascript to prevent possible problems with Google automatic search:
window.location = 'customurl://back/';
The error I receive when pushing the button with the custom intent:
Application Error
The protocol is not supported. (customurl://back/)
So, how do I get the external website which was accessed from the app to start the app again, so the user gets back to the app? The only possibility I can think of after searching for hours and hours is to close the app when the user navigates away to the external site.
I think you might need to set a host in the intent filter also:
<data android:scheme="customurl" />
<data android:host="somewebsite.com" />
Can you check to see if that makes a difference?
I have a basic clock widget here, it works just fine on versions of android below 4.0, you can long press, select widgets and its right there. But when i try to run it on 4.0 or later emulator or real device, it does not show up in widgets section only in Settings>Storage>Apps. I have tried adding a simple activity that just gives users directions on how to install the widget , that suggestion was given as an answer here: Android 4.0: widgets not appearing? . Unless i did it wrong the widget still does not show up in widget drawer.
Here is my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.widgetexample1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
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>
<receiver android:name=".ExampleAppWidgetProvider"
android:label="8-bit cloud widget 1">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/widget1_info" />
</receiver>
</application>
</manifest>
add below in your manifest.xml.
"android:exported="true".
it might help.
try it.
In your widget metadata xml file check tag <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:xmlns attribute should start with http://.
It looks like you are being hit by a security upgrade which I think happened in HoneyComb.
Basically, in newer versions of Android, you cannot have your widget working, without first launching an Activity.
So add an activity to the project, run it first, and I think your widgets will update.
A good example would be to use a Settings style activity, or perhaps and About box type of thing, to tell the user a bit about your widget. (I use settings in my widgets).
For more info:
Android 4.0: widgets not appearing?