Android > 4.4.2 - Setting Default SMS App - android

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!

Related

How to open an Android application from a webpage

I'm currently trying to open an Android application from a webpage. And to pass two parameters.
I went for the intent solution as it seems that custom scheme are not recommended, and in this case, I don't need a deeplink.
Currently, in debug, the only thing that happens is that my intent url is opened inside chrome and display a white page.
It never opens the application.
This is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MyApp">
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:roundIcon="#mipmap/appicon_round" android:supportsRtl="true">
<activity
android:name="com.MyApp.activity.MainActivity"
android:exported="true"
android:label="MyApp">
<intent-filter>
<action android:name="com.MyApp.LAUNCH"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="MyScheme" android:host="MyHost" android:path="/"/>
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
This is my javascript:
if (navigator.userAgent.match(/Android/i)) {
var uri = "intent://MyApp#Intent;scheme=MyScheme;action=com.MyApp.LAUNCH;package=com.MyApp;S.p=" + p + ";S.c=" + c + ";end";
window.open(uri);
}
I've seen a lot of way of doing this and tried a lot of things, but I don't get what is the good way to do with API 33.
I tried to use "intent:#Intent", "intent://#Intent", I tried with and without data property under activity, I tried my own scheme "MyScheme://".
I would like to avoid using deeplink as I would like to keep my website accessible without launching the app (different goals).
You need to check Handling Android App Link documentation.
Basically, to open the app you need to specify some specific scheme, for example:
<activity
android:name=".MyMapActivity"
android:exported="true"
...>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
</activity>
And the link to open will be: myapp://anypath_here?param1=value1&param2=value2
Try to use a unique scheme, otherwise, you will have an 'Open with..' dialog opening if another app can open it.
To enable link handling verification for your app, add intent filters that match the following format:
<!-- Make sure you explicitly set android:autoVerify to "true". -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- If a user clicks on a shared link that uses the "http" scheme, your
app should be able to delegate that traffic to "https". -->
<data android:scheme="http" />
<data android:scheme="https" />
<!-- Include one or more domains that should be verified. -->
<data android:host="..." />
</intent-filter>
More information you can refer to Verify Android App Links.

Open activity after intent 'click on phone number'

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>

AIR/Android NFC tags are opening the Browser

I'm testing an NFC-enabled Android/AIR application using a Nexus S.
My NFC tag has a sample url on it, e.g. "http://www.google.com".
I'd like to capture the url (or any text) on the tag for use in the app.
When the tag is tapped, the phone instead opens the url in the Browser.
I'm wondering if there is something I'm missing in my manifest, or if links are always handled by the browser. I've looked at the docs and I've even added a scheme for the specific URL, but still no luck.
My manifest is below. Thanks for any input.
<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature android:name="android.hardware.nfc" android:required="true"/>
<application android:debuggable="true">
<activity>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="text/plain" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<data android:mimeType="text/plain" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
A URL on an NFC tag is not the same as a plain text message on an NFC tag. They have different message types. Your manifest lists 2 intent filters for a plain text message (the last one will never be triggered actually, a TAG_DISCOVERED intent will never contain any data from the tag).
For matching your sample URL try instead:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:scheme="http" android:host="www.google.com" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
See also http://developer.android.com/guide/topics/nfc/nfc.html#ndef-disc for a more detailed explanation of NDEF_DISCOVERED and http://developer.android.com/guide/topics/manifest/data-element.html for full documentation of what can go in a <data> element.

Listen Broadcast Before application uninstall

I have installed Avg Antivirus for testing purpose.
After Testing when I have tried to uninstall that Antivirus,Antivirus has prompted me that 'are you sure you want to remove this application?'.
That prompt screen is generated by antivirus application. After that screen I got System prompt with OK and CANCEL Button. so, That prompt was put by antivirus application.
Now my question is...
How can I put prompt screen for user in my application as same as explain above?
I know about "android.intent.action.PACKAGE_REMOVED" but it received after application has been fully uninstall.
Any help is appreciated.
Thank You.
I've added the following intent-filter and now I receive the dialog to chose activity. I think you should play with this filter to display your activity (especially with data part of the filter).
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".UninstallIntentActivity"
android:label="#string/app_name" >
<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" />
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
</activity>
</application>

Oauth Callback not found after allowing the app on Twitter

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.

Categories

Resources