I've got an app that sends a text message as a response after receiving a text message. (Auto Respond) When SMS is enabled in hangouts, my app wasn't sending its messages. I fixed that by doing this:
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
After sending the message, my app also writes that sent message to the user's SMS log (inbox/outbox displayed by messaging apps.)
But now that my SMS receiver is higher priority than Hangouts, the sent message is written to the user's SMS log AFTER the received message when it should be the other way around.
So it shows like this:
Response Message
Received Message - this is what triggered the response
But it should be:
Received Message - triggers response
Response Message
Is there a way for me to wait for the received message to be written before writing the response message? It works fine when SMS is disabled in Hangouts. But since Hangouts is now writing that message instead of the default SMS receiver, it messes things up like crazy.
EDIT: Thanks to Keith's response, this is the code that worked for me:
context.getContentResolver().registerContentObserver(
Uri.parse("content://sms"),
true,
smsObserver);
And this class:
private class SMSObserver extends ContentObserver
{
public SMSObserver()
{
super(null);
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if(!selfChange)
//sendResponse
context.getContentResolver().unregisterContentObserver(this);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if(!selfChange)
//sendResponse
context.getContentResolver().unregisterContentObserver(this);
}
}
I'm not sure if the self change part is necessary, but it works so I'm not changing it.
Try a ContentObserver on the SMS database to listen for when Hangouts writes to the SMS content provider. This approach should be compatible with 4.4/Hangouts as well as earlier versions; you'd just wait until something is written to write your sent message.
Tested two different versions on Android 4.3, Galaxy Nexus:
context.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, myContentObserver);
or
cursor = context.getContentResolver().query(Uri.parse("content://sms/inbox"),
new String[] { SMS_ID, SMS_ADDRESS, SMS_READ },
"read = 0",
null,
null);
cursor.registerContentObserver(myContentObserver);
But I couldn't use the non-Cursor version with sms/inbox for some reason. The downside of the Cursor-based version is that it seems to need to stay open so then you have to be sure to close it later.
Also, neither version is being called when the read status changes.
Related
I'm writing a small android app which has a broadcast receiver for incoming sms messages. Normal text works just fine, but emoji show up as weird characters ().
The relevant code:
class SmsReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val pdus = intent.extras?.get("pdus") as Array<ByteArray>
pdus.map { SmsMessage.createFromPdu(it) }
.forEach { Log.i("Receiver", "Got message ${it.displayMessageBody}") }
}
The message I'm sending to the emulator:
💩💩💩
What I get in my log file:
I/Receiver: Got message
Does anyone know how to get the proper message text?
UPDATE
So after going down a rabbit hole of encodings and the EmojiCompat library, I discovered it's an issue with the emulator itself. When I got hold of a second phone and tried it on an actual device, it just worked. I created a bug with the android developers so hopefully they have a fix: https://issuetracker.google.com/issues/149141727
The message you are sending the emulator is ascii, and the message you are displaying to the log is UTF8, you need to read it as ascii
I am trying to transfer heart rate sensors data from watch to mobile device. On the watch(wearable) side, I am getting message stating that the data has been transferred. I have set the priority of the message(PutDataMapRequest) as urgent on the watch.
However, I am unable to receive the data on the mobile device. Following is my code for AndroidManifest.xml:
<%service android:name=".WearableListenerService1">
<%intent-filter>
<%action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<%data android:host="*" android:scheme="wear" android:pathPrefix= "/healthcare" />
</intent-filter>
</service>
My WearableListenerService1 class is:
public class WearableListenerService1 extends WearableListenerService {
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
String event = messageEvent.getPath();
Log.d("Event ", event);
String [] message = event.split("--");
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
#Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
// super.onDataChanged(dataEventBuffer);
Log.d("Event ", "event data changed");
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
}
I am using following libraries:
compile 'com.google.android.support:wearable:2.0.0-alpha2'
compile 'com.google.android.gms:play-services-wearable:9.4.0'
Acording to this tutorial, make sure that the applicationId in the main app and wearable app are matched (build.gradle files) in order for the WearableListenerService to fire the onDataChanged event. Because when you send some data through mobile app or wear app, it will check for the same package to pass that data. So if you give different name, you won't be able to send or receive data.
You can also check this documentation and related SO threads:
Sending messages from Android Wear to host device
Android Wear sending data to Android phone, but phone appears to never receive it
I found the issue. Android version on my Moto360 was 1.5 whereas I was using developer preview of wear 2.0 on Android Studio.
I added the IntercomIO SDK to our Xamarin.Forms app through a couple binding libraries this week and I'm currently trying to get the Push Notifications to work but soon after I call PushHandlerService.Register(this) in the MainActivity the app crashes saying that it can't find the class com.google.android.gms.gcm.GcmReceiver which isn't even being caught by the try catch block around this call.
Here is the method inside the MainActivity which is responsible for setting up the push notifications on Android.
public void registerForPushNotifications()
{
try
{
GcmClient.CheckDevice(this);
GcmClient.CheckManifest(this);
//Register the app for push notifications.
PushHandlerService.Initialize(this);
//if (!GcmClient.IsRegistered(this))//Temporarily force the app to register for push notifications
{
System.Diagnostics.Debug.WriteLine("Registering");
// Register for GCM
PushHandlerService.Register(this);
}
LocalBroadcastManager lbc = LocalBroadcastManager.GetInstance(this);
PushActionReceiver rec = new PushActionReceiver(this);
lbc.RegisterReceiver(rec, new IntentFilter("pushaction"));
}
catch (Java.Net.MalformedURLException)
{
var e = new Exception("There was an error creating the Mobile Service. Verify the URL");
System.Diagnostics.Debug.Fail(String.Format(#"Exception at {0}: {1}", this.GetType().Name, e.Message));
Insights.Report(e);
}
catch (Exception e)
{
System.Diagnostics.Debug.Fail(String.Format(#"Exception at {0}: {1}", this.GetType().Name, e.Message));
if (e.GetType() != typeof(TaskCanceledException))
Insights.Report(e);
}
}
And in the Manifest I added the receiver definition for Intercom
<receiver android:name="io.intercom.android.sdk.gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"></receiver>
The issue doesn't happen when I don't call PushHandlerService.Register(this) but then obviously I can't receive any push notifications anymore (including the ones from our own system)
What's going on here? I have the libraries and dependancies setup properly but it doesn't seem to be able to find the GcmReceiver class..
Apparently updating to the latest SDK's in the SDK Manager solved this crash. I am still not receiving any push notifications but I'm guessing this is due to a different issue. At least the app doesn't crash anymore when trying to register for the push notifications.
Dale from Intercom here. Are you using any other third party push providers, or do you have your own GCM receiver? It's possible that they are consuming our push and not passing them on. This can be difficult in Xamarin, Phonegap, Cordova ect. as often the registration and receiver services are not available. I have included below a link to our GCM doc and the section that may be most relevant to you. If this doesn't help fix the issue get in touch with us on the cordova repo: https://github.com/intercom/intercom-cordova or reach out to us in your Intercom dashboard/ email us at team#intercom.io.
We have GCM docs here: https://docs.intercom.com/configure-intercom-for-your-product-or-site/configure-intercom-for-mobile/enable-push-notifications-with-intercom-for-android-gcm
The issue that might be causing you difficulty in your setup is:
Step 7. Using Intercom with other GCM setups (Optional)
This only applies to applications that also use GCM for their own content, or use a third party service for GCM. You’ll need to update the your GcmListenerService and the class where you generate your device token.
You should have a class that generates a push device token and sends it to your backend. In addition to sending the token to your backend you will need to forward it to Intercom, like this:
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onHandleIntent(Intent intent) {
InstanceID instanceId = InstanceID.getInstance(this);
String senderId = "YOUR_SENDER_ID";
String token = instanceId.getToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
pushClient.sendTokenToIntercom(getApplication(), token);
}
You should have a class that extends GcmListenerService. That service will consume pushes intended for Intercom. To allow us to draw the Intercom push set up your GcmListenerService, like this:
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onMessageReceived(String from, Bundle message) {
if (intercomPushClient.isIntercomPush(message)) {
intercomPushClient.handlePush(getApplication(), message);
} else {
//DO HOST LOGIC HERE
}
}
I am developing the app where I'm using GCM. I have taken sample GCM example from google samples from github and implemented every thing is fine,But i want to TURNOFF the GCM notifications. I have specified GCM notification turn ON/OFF in another Activity using toggle button.when i click on toggle button it should work accordingly
I found subscribeTopics method in RegistrationIntentService.java
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
similarly i have written Un Subscribe method
To TURN OFF Notifications
private void UnSubscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.unSubscribe(token, "/topics/" + topic, null);
}
}
I'm unable to call UnSubscribeTopics method.Because that method is in RegistrationIntentService.java which extends Intentservice.How can i call method 'UnSubscribeTopics'
I'm still getting notifications and here they are using Intent service.I have gone through internet some are saying to delete token(secret token) or delete instance id,but I'm confused what to do?? and how i do that .I am new to Intent service.here they using broadcast receiver also how can i call that in my activity.
Any help???
Thanks in advance.
You have two options to do that:
'SharedPreferences' you should have a preference that contain the value if the user should be notified or not. You may set the preference value to 'false'. In your 'GCMIntentService', check the value of the preference, if it's false, do nothing.
You may unregister your app to avoid receiving push notifications. You can use 'GCMRegistrar.unregistrar()' to make this happen.
I am using an SMS manager in my app, so when a button is clicked, an SMS is sent,
btnPaket.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
String phoneNo = "0977";
String message = "stanje";
sendSMS(phoneNo, message);
Toast.makeText(getBaseContext(), "Zahtjev za provjeru stanja paketa je poslan, odgovor ocekuj uskoro!", Toast.LENGTH_SHORT).show();
}
});
So when I click on the button, the SMS is sent, and I get an automated response with the state of my SMS, and Internet packets. Is there any way such that a received SMS is automatically opened and shown to the user, without leaving the application, and going to the inbox, or the notifications bar?
I don't think Android allows you to directly open/read text messages (for extremely obvious reasons...), however, you might be able to just launch the SMS inbox from your application.
Reference here to how to launch activities.
EDIT:
This person apparently found out how to open the sms inbox, check his second post.