I found several answers on this issue, but it's not working for me. If you click a phone number in an email or on a website, a default dialer popup comes up to select the dialer/skype etc.
I'm trying to get my app in that list - so I don't want to handle the actual call, but open the activity and show the number the user clicked on.
I've tried this:
<receiver android:name=".MyOutgoingCallHandler">
<intent-filter>
<action android:name="android.intent.action.ACTION_DIAL" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
But it's not showing in the list. What intent should I filter for?
If you want to add an Activity to the list of Activitys that will be shown to the user as possible phone dialers, you need to have an Activity and the <activity> definition must contain this intent-filter> in the manifest:
<activity ...>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
What you've got is a BroadcastReceiver that will receive the outgoing call Intent. That's something different.
The official Android Developers blog has covered this process. You can read all about it there.
Your intent filter looks like it has the correct action, so it may be that you have not requested the correct Android permission.
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
Here is how the Android Developers blog suggest you declare the broadcast receiver.
<manifest>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application>
...
<receiver android:name=MyOutgoingCallHandler">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
...
</application>
</manifest>
Related
MY PLIGHT EXPLAINED
I cannot figure out or find out to stop my Activity from launching itself. This is necessary as I am making a dir manager that has intent filter to open any file, in attempt to easily locate and rename it. For instance clicking a file from notification to be opened by my app for renaming.
MY PLIGHT SUMMARIESED
But it makes no sense to run this intent if you are already in my app. Thus I want to programatically stop my app from being a choice in this case.
MY TRIES FOR SOLUTION
I have tried many stuff. Google, android reference on ActivityInfo. I even tried creating my own activity chooser dialog. Which doesnt work 100% accurately. If it did I could simply omit my activity from the list.
I humbly seek assistance.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="jav.android.dir_mgr">
<uses-sdk android:minSdkVersion="12" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:icon="#mipmap/app_icon"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".DirectoryExplorer"
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.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<activity
android:name=".SelectionWindow"
android:screenOrientation="portrait"
android:label="Selection Window"
android:allowEmbedded="true">
<intent-filter>
. <action android:name="jav.android.dir_mgr.SELECT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
You can use EXTRA_EXCLUDE_COMPONENTS to exclude your own application from the list shown to the user. See the documentation which states:
You can exclude specific targets by providing
Intent.EXTRA_EXCLUDE_COMPONENTS. This is to be used only to remove
targets you have control over. A common use case is to hide your app’s
share targets when your users share from within your app as their
intent is likely to share outside your app.
Add Intent.EXTRA_EXCLUDE_COMPONENTS to your intent after calling
Intent.createChooser()
So, from what I understand, you need a way to check if your app is in focus or not. If that's so, try using ActivityManager.getRunningAppProcesses() which will return a list of application processes that are running on the device.
From there you can iterate through processes that are running on the device and check if your app is listed there and that it's of RunningAppProcessInfo.IMPORTANCE_FOREGROUND.
EDIT: I assume you are using pending intents, then you won't be able to check if your app is already running in the above way. Try using a "launch intent" for your app as explained in this answer.
I hope I understood your plight correctly.
One way to solve your problem is to programmatically unregister your activity from listening to a certain intent-filter value. So let's say you have an activity declared as:
<activity android:name=".FileHandlerActivity">
<intent-filter>
<action android:name="you-file-rename-action-name-here"/>
</intent-filter>
</activity>
Do this in your app:
PackageManager pm = getApplicationContext().getPackageManager();
ComponentName component = new ComponentName(getPackageName(),
getPackageName()+".FileHandlerActivity");
pm.setComponentEnabledSetting(component,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
Please let me know if this works.
I want to launch my application by scanning an NFC tag containing an Android Application Record. However, this app shouldn't have a launcher icon, so I can't use CATEGORY_LAUNCHER.
My problem is that if I comment out the CATEGORY_LAUNCHER line in the manifest, the app is not launched anymore (a search is performed on Google Play instead):
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.my">
<application android:label="#string/app_name">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--<category android:name="android.intent.category.LAUNCHER" />-->
</intent-filter>
</activity>
</application>
</manifest>
I also tried adding the following intent filter but with no luck:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
What should I do to make it work? Should I add code in MainActivity to handle the NDEF_DISCOVERED intent?
The typical way to do this is to add another record (MIME type, NFC Forum external type, or URI) to the tag in addition to the Android Application Record (AAR). In that case, the AAR must be the last (or at least not the first) record of the NDEF message on the tag.
You can then catch the tag discovery by filtering for that specific data type (i.e. the type of the first record of the NDEF message on your tag) using the NDEF_DISCOVERED intent filter. E.g. for an NFC Forum external type:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="vnd.android.nfc"
android:host="ext"
android:pathPrefix="/yourdomain.com:yourtypename"/>
</intent-filter>
</activity>
In that case, the AAR will make sure that your app gets precedence over any other apps that registered for the same type and that Play Store is opend for your app if it's not already installed.
If you do not register any activity for a matching NDEF_DISCOVERED intent filter, the AAR will cause the first activity that has a MAIN/LAUNCHER intent filter (in that case Android won't pass a handle to the tag to your activity though). Hence, if you neither register for NDEF_DISCOVERED intents nor for MAIN/LAUNCHER intents, the AAR mechanism won't work.
But what if you want your tag to only contain an AAR and no other records?
You could do this by registering an intent filter for the AAR itself. The AAR is an NFC Forum external type with the type name "urn:nfc:ext:android.com:pkg", so you could use the following intent filter:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="vnd.android.nfc" android:host="ext"
android:pathPrefix="/android.com:pkg" />
</intent-filter>
I got it working by setting a custom mimeType in the intent-filter, like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.my">
<application android:label="#string/app_name">
<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.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/vnd.app.my" />
</intent-filter>
</activity>
</application>
</manifest>
Then creating an NdefRecord to write on the tag with:
NdefRecord.createMime("application/vnd.app.my", null);
This doesn't take advantage of the AAR which, from what I understand, works at the application level (and not at the activity level) and ensures that only my app can be launched. But I guess that a custom MIME type like this is good enough.
I've been walking through the steps required to allow Android to recognize an app as a potential default Messaging (SMS/MMS) app detailed here and I've followed through on several posts on SO that have up-voted answers that fallback to the instructions outlined on the blog posting.
However, even after following these instructions, which I believe I have done so correctly, I'm still not able to get my app to appear in the system dialog which will allow me to choose which app I want as the default Messaging client. I can't help but feel like I'm still missing something in the manifest but I'm not too sure. If anyone has any advice on this, I'd really appreciate it.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gregfmartin.smsdemo">
<uses-sdk android:minSdkVersion="19"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:name=".ApplicationCore"
android:theme="#style/SmsDemo">
<!-- Listens for incoming SMS Messages -->
<receiver android:name=".components.receivers.SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_DELIVER"/>
</intent-filter>
</receiver>
<!-- Listens for incoming MMS Messages -->
<receiver android:name=".components.receivers.MmsReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER"/>
<data android:mimeType="application/vnd.wap.mms-message"/>
</intent-filter>
</receiver>
<!-- Activity -->
<activity android:name=".Main">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".components.activities.ConversationThreadViewer">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="sms"/>
<data android:scheme="smsto"/>
<data android:scheme="mms"/>
<data android:scheme="mmsto"/>
</intent-filter>
</activity>
<!-- Headless SMS Handler -->
<service android:name=".components.services.HeadlessSmsSenderService"
android:permission="android.permission.SEND_RESPONSE_VIA_MESSAGE"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="sms"/>
<data android:scheme="smsto"/>
<data android:scheme="mms"/>
<data android:scheme="mmsto"/>
</intent-filter>
</service>
</application>
</manifest>
You need to add the category
android.intent.category.APP_MESSAGING
Refer http://developer.android.com/reference/android/content/Intent.html#CATEGORY_APP_MESSAGING
I finally figured out what was going on. I know I kicked myself after I figured it out and facepalmed for about ten minutes.
The Service, HeadlessSmsSenderService, the permission is supposed to be android.permission.SEND_RESPOND_VIA_MESSAGE not android.permission.SEND_RESPONSE_VIA_MESSAGE.
Respond/Response
Seriously? Send Respond?
What caught it was I copied and pasted the manifest from the Google Blog Post and just made a new app really quick that used it and low and behold, it showed up in the system dialog. So then I ran a diff against it and my manifest and everything matched up save for that misspelling (and the organizational changes that I had).
The nasty part about this is that there are some permissions and Intent Actions that IntelliJ won't automatically catch while you're typing them. I'm also not sure if Lint will catch these types of semantic errors or not. For all intents and purposes, the app will compile and run cleanly. No output was found on logcat so really this was a near totally silent issue.
Thanks for all of your help!
I have created an application that successively adds appointments to a calendar. However i wish now to be able to click the "New Event" button in a calendar program eg. aCalendar and have my program popup. and i think i am a little lost.
in my AndroidManifest.xml
<receiver
android:name="com.johnny.CalendarAdd"
android:enabled="true"
>
<intent-filter>
<data android:pathPrefix="vnd.android.cursor.item/event" />
<action android:name="android.intent.action.EDIT" />
</intent-filter>
</receiver>
tryed to change it to.
<activity android:name="CalendarAdd">
<intent-filter>
<data android:pathPrefix="vnd.android.cursor.item/event" />
<action android:name="android.intent.action.EDIT" />
</intent-filter>
</activity>
In class file
package com.johnny;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class CalendarTest extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("CalendarAdd", "CalendarAdd.onReceive called!");
}
}
when i click the "New Event" button i don't get my app in the list.
I have had a look-around and think i have missed something simple or i am Totally on the wrong path.
Thanks for any Help in advance.
You can't achieve it using Broadcast Receiver, Broadcast intent-filter will work only when some app broadcast that particular intent, e.g connectivity state got changed, screen got turned off, battery low etc are correct example of system broadcasts. While create calendar event can't be a broadcast & thats why you can't receive it.
From android documentation regarding Broadcast Receivers:
A broadcast receiver is a component that responds to system-wide
broadcast announcements. Many broadcasts originate from the system—for
example, a broadcast announcing that the screen has turned off, the
battery is low, or a picture was captured. Applications can also
initiate broadcasts—for example, to let other applications know that
some data has been downloaded to the device and is available for them
to use. Although broadcast receivers don't display a user interface,
they may create a status bar notification to alert the user when a
broadcast event occurs. More commonly, though, a broadcast receiver is
just a "gateway" to other components and is intended to do a very
minimal amount of work. For instance, it might initiate a service to
perform some work based on the event.
For achieving desired functionality, you need to register intent-filter for your activity.
Also your manifest should contain read/write calendar permission and event edit/insert intent-filter, e.g.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.CalanderTest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8"/>
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/event" />
</intent-filter>
</activity>
</application>
</manifest>
for testing it out do below in onclick of some test button:-
#Override
public void onClick(View view) {
super.onClick(view);
if (view.getId()==R.id.create_event)
{
Intent i = new Intent(Intent.ACTION_INSERT);
i.setType("vnd.android.cursor.item/event");
startActivity(i);
}
}
On clicking of my test button i got menu like in below image, so above code works fine to show your app in App chooser dialog for adding/editing calendar events.
Now in your activity you can handle this intent using getIntent() and perform action accordingly.
You can have a look here for extras supported by Calendar event.
Like Events.TITLE,Events.EVENT_LOCATION etc. If you are going to create your own calendar event creator, then you need to handle all such extras Gracefully, for awesome user experience.
Place the <intent-filter> you defined inside your <activity> instead. The user should be given a list of apps (including yours) that can handle that action, so they can select yours if they want to.
<receiver>s are for receiving BroadcastIntents, which are a bit different.
Use <receiver> as you originally did, and android:name should be com.johnny.CalendarTest if you wish to register your receiver, since your receiver class name is CalendarTest.
See here
android:name
Required name of the class implementing the receiver, deriving from BroadcastReceiver.
However i wish now to be able to click the "New Event" button in a
calendar program eg. aCalendar and have my program popup.
Have you tried the various action and category filter declarations in your <intent-filter>.
For instance:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.OPENABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/myapp" />
</intent-filter>
See if any of those help you.
See also: http://developer.android.com/reference/android/content/Intent.html
From CalendarController, I can almost be sure that these intent are explicit intent with specific component set. For example, in launchEditEvent method.
private void launchEditEvent(long eventId, long startMillis, long endMillis, boolean edit) {
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
Intent intent = new Intent(Intent.ACTION_EDIT, uri);
intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
intent.setClass(mContext, EditEventActivity.class);
intent.putExtra(EVENT_EDIT_ON_LAUNCH, edit);
mEventId = eventId;
mContext.startActivity(intent);
}
The intent is set to be handled by EditEventActivity. So it is impossible to receive such intents in your application. I think the Calendar App make it as an explicit intent because it regard this as an in-app event. If this is not an explicit intent, your code should work, because the component in Calendar App is almost same with what you did.
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/event" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
</intent-filter>
The aCalendar New Event Intent is as this.
{act=android.intent.action.EDIT typ=vnd.android.cursor.item/event flg=0x20000000 cmp=org.withouthat.acalendar/.edit.EditActivity (has extras)}
And Google Calendar App New Event Intent is as this.
{act=android.intent.action.VIEW cmp=com.android.calendar/.event.EditEventActivity
They are explicit intent.
Your can not receive this intent in your app.
More about intent click here
<activity android:name="com.johny.CalendarTest"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:host="com.android.calendar" />
<data android:host="calendar" />
<data android:scheme="content" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:mimeType="vnd.android.cursor.item/event" />
</intent-filter>
</activity>
This was the exact code i used and got to work.
Most of The Answers helped in getting the response.
The reward went to the person who put most effort into it and achieved what was a result.
The old answers show me the direction, but I had to do a small modification to make it work:
<activity
android:name=".YourActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
</intent-filter>
</activity>
Hey. I am developing an application using the Twitter4j api. In order to allow the application and get an access token, I launch the browser with the callback parameters which I had set in the manifest file.
<data android:scheme="scheme" android:host="authenticatorapp"></data>
After allowing the application, the browser calls the following and fails with a not found message.
scheme://authenticatorapp?oauth_token=n5vd99dfnmnf...
I tried it both on the emulator and the device.
In the emulator, LogCat gives me this :
12-12 15:04:05.743: ERROR/browser(230): onReceivedError -10 scheme://authenticatorapp?oauth_token=Jj...M&oauth_verifier=3ZfuY... The protocol is not supported.
-- The manifest file :
<activity android:name=".AuthenticatorApp"
android:launchMode="singleInstance"
>
<intent-filter>
<category android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:scheme="scheme" android:host="authenticatorapp"></data>
</intent-filter>
</activity>
<!-- Broadcast Receiver that will process AppWidget updates -->
<receiver android:name=".ZaytungWidget" android:label="#string/widget_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/tweet_metadata" />
</receiver>
<!-- Service to perform web API queries -->
<service android:name=".ZaytungWidget$UpdateService" />
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
Can you please post the whole manifest file?
I found the following question which may be useful later on: OAuth instance state in Android
The question linked to the following example application, which may be helpful:
http://code.google.com/p/jpoco/source/browse/trunk/jpoco-android-app/AndroidManifest.xml
This is what I have in my working Manifest.xml, where org.gpsagenda.OAUTH is the activity doing the Authenticating.
<activity android:name="org.gpsagenda.OAUTH" >
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="gpsagenda" android:host="twitt" />
</intent-filter>
</activity>
If you're developing a native app, you don't use the callback parameters, but need to let the user enter the pin in your app somewhere - which he gets when you open the authorization_url in a browser or probably more comfortably within your app in a webview.
You could also automatically fetch the pin after the user has clicked on 'yes' in the authorization twitter webpage, but not sure if it's against the twitter ToS.