Gluon Attach Service. SMS Not Sent - java

following the steps gluonfx attach service between graalvm and android , I was able to do the messaging defined under
public class AndroidSmsService implements SmsService { ...
#Override
public void sendSms(Message message) {
if (message != null) {
_logger.log(Level.INFO, "AndroidSmsService#sendSms phone: {0}, sms : {1} ", new Object[]{message.getPhone(), message.getSms()});
String phone = message.getPhone();
String sms = message.getSms();
if (phone != null && phone.length() > 0 && sms != null && sms.length() > 0) {
sendSms(phone, sms);
}
}
}
private native void sendSms(String phone, String sms);
}
through the JNI Interface, I am able to call sendSms(String phone,String message) defined under
public class DalvikSmsService { ...
private void sendSms(String phone, String message) {
try {
String formattedNumber = PhoneNumberUtils.formatNumber(phone);
Log.i(TAG, "sendSMS phone : " + formattedNumber + ", sms : " + message);
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(formattedNumber, null, message, null, null);
} catch (Exception exc) {
exc.printStackTrace();
Log.i(TAG, "sendSMS sending failed, please try again");
}
}
}
my AndroidManifest.xml file
...
<uses-permission android:name="android.permission.SEND_SMS"/>
<application>
<service android:name="com.gluonhq.helloandroid.DalvikSmsService"
android:permission="android.permission.SEND_SMS"
android:exported="true"/>
<activity android:name=".PermissionRequestActivity"/>
...
the logs clearly show the method is called (with the phone number edited out)
01-13 08:45:56.760: D/GraalGluon(4546): ATTACH_DALVIK, tid = 4587, existed? 1, dalvikEnv at 0x799ff67ca470
01-13 08:45:56.763: I/DalvikSmsService(4546): sendSMS phone : 256-701-XYZXYZ, sms : Hello JavaFx Message
01-13 08:45:56.780: D/SmsNumberUtils(936): enter filterDestAddr. destAddr="[dH0eoa3ufMriilJ2cZIb3LD2V7g]"
01-13 08:45:56.782: D/SmsNumberUtils(936): destAddr is not formatted.
01-13 08:45:56.782: D/SmsNumberUtils(936): leave filterDestAddr, new destAddr="[dH0eoa3ufMriilJ2cZIb3LD2V7g]"
01-13 08:45:56.798: D/GraalGluon(4546): DETACH_DALVIK, tid = 4587, existed = 1, env at 0x799ff67ca470
BUT this message is never delivered !!!!. what could I be doing wrongly???

Related

Send push notification using Java Springboot server and Expo React native client

My serser uses Java with SpringBoot and my client is an expo react native app which uses typescript.
I am really blocked by this feature: I want to sens push notifications. I tried a lot of methods, but I didn't succeed.
On the client side I am using the method described in expo documentation: https://docs.expo.dev/push-notifications/overview/.
When I use their tool to send test notifications(https://expo.dev/notifications), I receive them on my device.
I didn't manage to send notifications from my client app. I tried all I found on the Inthernet. When I used FirebaseMessagingService and I used the server key from the firebase project as token, I received the SENDER_ID_MISMATCH error.
#Service
public class FirebaseMessagingService {
private final FirebaseMessaging firebaseMessaging;
public FirebaseMessagingService(FirebaseMessaging firebaseMessaging) {
this.firebaseMessaging = firebaseMessaging;
}
public String sendNotification(Note note, String topic) throws FirebaseMessagingException {
Notification notification = Notification
.builder()
.setTitle(note.getSubject())
.setBody(note.getContent())
.setImage(note.getImage())
.build();
Message message = Message
.builder()
.setNotification(notification)
.putAllData(note.getData())
.setToken(topic)
.build();
return firebaseMessaging.send(message);
}
}
I also found the expo-server-sdk-java but I couldn't manage to integrate it.
Any heeeeelp, pleaseeee?
not sure if it's the best practice but it works fine for me.
My pom
<dependency>
<groupId>io.github.jav</groupId>
<artifactId>expo-server-sdk</artifactId>
<version>1.1.0</version>
</dependency>
Then in the java class
private static void sendPushNotification(String token, String titulo, String mensaje, Map<String, Object> data) throws PushClientException {
if (!PushClient.isExponentPushToken(token)) throw new Error("Token:" + token + " is not a valid token.");
ExpoPushMessage expoPushMessage = new ExpoPushMessage();
expoPushMessage.getTo().add(token);
expoPushMessage.setTitle(titulo);
expoPushMessage.setBody(mensaje);
expoPushMessage.setData(data);
List<ExpoPushMessage> expoPushMessages = new ArrayList<>();
expoPushMessages.add(expoPushMessage);
PushClient client = new PushClient();
List<List<ExpoPushMessage>> chunks = client.chunkPushNotifications(expoPushMessages);
List<CompletableFuture<List<ExpoPushTicket>>> messageRepliesFutures = new ArrayList<>();
for (List<ExpoPushMessage> chunk : chunks) {
messageRepliesFutures.add(client.sendPushNotificationsAsync(chunk));
}
// Wait for each completable future to finish
List<ExpoPushTicket> allTickets = new ArrayList<>();
for (CompletableFuture<List<ExpoPushTicket>> messageReplyFuture : messageRepliesFutures) {
try {
allTickets.addAll(messageReplyFuture.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
List<ExpoPushMessageTicketPair<ExpoPushMessage>> zippedMessagesTickets = client.zipMessagesTickets(expoPushMessages, allTickets);
List<ExpoPushMessageTicketPair<ExpoPushMessage>> okTicketMessages = client.filterAllSuccessfulMessages(zippedMessagesTickets);
String okTicketMessagesString = okTicketMessages.stream().map(p -> "Title: " + p.message.getTitle() + ", Id:" + p.ticket.getId()).collect(Collectors.joining(","));
LOGGER.info("Recieved OK ticket for " + okTicketMessages.size() + " messages: " + okTicketMessagesString);
List<ExpoPushMessageTicketPair<ExpoPushMessage>> errorTicketMessages = client.filterAllMessagesWithError(zippedMessagesTickets);
String errorTicketMessagesString = errorTicketMessages.stream().map(p -> "Title: " + p.message.getTitle() + ", Error: " + p.ticket.getDetails().getError()).collect(Collectors.joining(","));
LOGGER.error("Recieved ERROR ticket for " + errorTicketMessages.size() + " messages: " + errorTicketMessagesString);
/**
// Countdown 30s
int wait = 30;
for (int i = wait; i >= 0; i--) {
System.out.print("Waiting for " + wait + " seconds. " + i + "s\r");
Thread.sleep(1000);
}
System.out.println("Fetching reciepts...");
List<String> ticketIds = (client.getTicketIdsFromPairs(okTicketMessages));
CompletableFuture<List<ExpoPushReceipt>> receiptFutures = client.getPushNotificationReceiptsAsync(ticketIds);
List<ExpoPushReceipt> receipts = new ArrayList<>();
try {
receipts = receiptFutures.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
System.out.println("Recieved " + receipts.size() + " receipts:");
for (ExpoPushReceipt reciept : receipts) {
System.out.println("Receipt for id: " + reciept.getId() + " had status: " + reciept.getStatus());
}
*/
}
In the App.js from react native project with EXPO 44 i take expo token in this way
async function registerForPushNotificationsAsync() {
let token;
if (isDevice) {
const { status: existingStatus } =
await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== "granted") {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== "granted") {
alert("Failed to get push token for push notification!");
return;
}
token = (await Notifications.getExpoPushTokenAsync()).data;
}
if (Platform.OS === "android") {
Notifications.setNotificationChannelAsync("default", {
name: "default",
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: "#FF231F7C",
});
}
return token;
}
effect from App.js
useEffect(() => {
initFirebaseApp();
registerForPushNotificationsAsync().then(async (token) => {
//store in some place token
});
// This listener is fired whenever a notification is received while the app is foregrounded
notificationListener.current =
Notifications.addNotificationReceivedListener(handleNotification);
// This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
responseListener.current =
Notifications.addNotificationResponseReceivedListener(
handleNotificationResponse
);
return () => {
Notifications.removeNotificationSubscription(
notificationListener.current
);
Notifications.removeNotificationSubscription(responseListener.current);
};
}, []);
notification handlers in App.js
const handleNotification = (response) => {
// console.log(response);
};
const handleNotificationResponse = (response) => {
// console.log(response)
};
I hope this helps you
Docs
Expo SDK documentation
Expo docs reference

How to read incoming MMS and SMS messages on Android

I know this is a big topic, as seen here and here, so I just wanted to post how I solved both the issue of receiving incoming MMS and SMS messages and the issue of grabbing data from those MMS and SMS messages on Android 9.0 version 28+ using Xamarin.Forms. This code can easily be translated to Java. Here is the completed Android app so you can try it yourself. It also shows how to do some Azure machine learning if you're interested in that.
For Broadcast Receivers:
Classes, registering class instances , permissions needed.
Note that the broadcast receivers were added dynamically, they can be added statically using Xamarin's intent-filter decorator , or (if you're not using Xamarin) the AndroidManifest.xml file.
Here is a code snippet to show how to parse incoming SMS data with a Broadcast Receiver:
public override void OnReceive(Context context, Intent intent)
{
Log.Info(TAG, "Intent action received: " + intent.Action);
// Retrieve message from the intent and analyze it.
SmsMessage msg = Android.Provider.Telephony.Sms.Intents.GetMessagesFromIntent(intent)[0];
string message = msg.DisplayMessageBody;
(string, bool) result = MMSReceiver.CleanUpMessage(message);
// If there were one or more rooster words.
if (result.Item2)
{
string title = "Rooster Text Received From: " + msg.DisplayOriginatingAddress;
DependencyService.Get<INotificationManager>().ScheduleNotification(title, result.Item1);
}
}
And here is a code snippet to show how to parse incoming MMS data with a Broadcast Receiver:
public override void OnReceive(Context context, Intent intent)
{
Log.Info(TAG, "Intent action received: " + intent.Action);
// Get the MMS ID. Adapted from: https://stackoverflow.com/questions/10065249/how-to-get-mms-id-android-application
ContentResolver contentResolver = AndroidApp.Context.ContentResolver;
Android.Net.Uri mmsInboxUri = Android.Net.Uri.Parse("content://mms");
Android.Database.ICursor mmsInboxCursor = contentResolver.Query(mmsInboxUri, new string[]
{"_id","msg_box","ct_t","date"}, "msg_box=1 or msg_box=2", null, null);
int id = -1;
if (mmsInboxCursor != null)
{
try
{
if (mmsInboxCursor.MoveToFirst())
{
id = Int32.Parse(mmsInboxCursor.GetString(0));
Log.Info(TAG, "Id is this: " + mmsInboxCursor.GetString(0));
}
}
catch (System.Exception error)
{
Log.Error(TAG, "Error requesting the MMS ID: " + error.Message);
}
}// if (mmsInboxCursor != null)
// Get text and picture from MMS message. Adapted from: https://stackoverflow.com/questions/3012287/how-to-read-mms-data-in-android
string message = ""; // text
Android.Graphics.Bitmap bitmap = null; // picture
string selectionPart = "mid=" + id;
Android.Net.Uri mmsTextUri = Android.Net.Uri.Parse("content://mms/part");
Android.Database.ICursor cursor = contentResolver.Query(mmsTextUri, null,
selectionPart, null, null);
if (cursor.MoveToFirst())
{
do
{
string partId = cursor.GetString(cursor.GetColumnIndex("_id"));
string type = cursor.GetString(cursor.GetColumnIndex("ct"));
// Get text.
if ("text/plain".Equals(type))
{
string data = cursor.GetString(cursor.GetColumnIndex("_data"));
if (data != null)
{
message = GetMmsText(partId);
Log.Info(TAG, "Body is this: " + message);
}
else
{
message = cursor.GetString(cursor.GetColumnIndex("text"));
Log.Info(TAG, "Body is this: " + message);
}
}
//Get picture.
if ("image/jpeg".Equals(type) || "image/bmp".Equals(type) ||
"image/gif".Equals(type) || "image/jpg".Equals(type) ||
"image/png".Equals(type))
{
bitmap = GetMmsImage(partId);
}
} while (cursor.MoveToNext());
}// if (cursor.MoveToFirst())
}

Disable 10 seconds timeout on BroadcastReceiver. Android Development

I have a IncomingSmsReceiver class that receives a sms message but the problem is it takes a while to receive the text message, I know that the BroadcastReceiver class automatically stop the process if it's listening for more the 10 seconds, is there any way to disable this?
heres my code:
public class IncomingSmsReceiver extends BroadcastReceiver {
private ShowDialogInterface callback;
public void onReceive(Context context, Intent intent) {
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
String messageBody = "no data";
String messageFrom = "no data";
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
messageBody = smsMessage.getMessageBody();
messageFrom = smsMessage.getDisplayOriginatingAddress();
}
if(callback != null) {
callback.smsDetails(messageFrom, messageBody);
}
}
}
public void registerReceiver(ShowDialogInterface receiverCallback) {
this.callback = receiverCallback;
}
// Show different UI elements to notifying the user of an incoming SMS
public interface ShowDialogInterface {
void smsDetails(String from, String message);
}
}
Here is my debug error:
enter image description here
Best Regards,
Noob Android_dev
You can start service from your BroadcastReceiver and do all job in it. It's a standard way to do such things.

Android Bluetooth Chat App & Sending Spotify Song Names

I'm am fairly new to Android, and I'm trying to develop an app for a small project of mine using an example Bluetooth Chat App and Spotify Media Notifications. I could not provide the links because stack overflow did not let me but they are available online with a quick google search. I was wondering why I was getting this exception and is there any solution to this?
java.lang.NullPointerException
The line numbers correspond to each of the pieces of code below:
Line 269 if (message.length() > 0)
Line 56 public class BluetoothChatFragment extends Fragment
Line 131 sendMessage(artistName);
How my code is set up:
I have a static broadcast receiver set up exactly like the Spotify link below. I grab the song name and artist and package them into strings. Then I have another broadcast receiver in my Bluetooth fragment. I used another one because I did not know how to get the string into the Bluetooth fragment because I needed to call sendMessage() a private method in the fragment class. It seems like the exception is throwing when I call sendMessage(string) in my fragment.
Static Spotify Broadcast Receiver
package com.example.android.bluetoothchat;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.example.android.common.logger.Log;
public class MyBroadcastReceiver extends BroadcastReceiver {
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String QUEUE_CHANGED = SPOTIFY_PACKAGE + ".queuechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
#Override
public void onReceive(Context context, Intent intent) {
// This is sent with all broadcasts, regardless of type. The value is taken from
// System.currentTimeMillis(), which you can compare to in order to determine how
// old the event is.
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
Intent sendBack = new Intent("Received");
String action = intent.getAction();
String artistName;
String trackName;
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
artistName = intent.getStringExtra("artist");
trackName = intent.getStringExtra("track");
String msg = "S a " + artistName + '\0';
String msg2 = "S n " + trackName + '\0';
Log.d("Song", msg);
Log.d("Artist", msg2);
sendBack.putExtra("Song", msg);
sendBack.putExtra("Artist", msg2);
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
boolean playing = intent.getBooleanExtra("playing", false);
// Do something with extracted information
if(playing) {
Log.d("Playing", "S p\0");
sendBack.putExtra("Playing", "S p\0");
}
else {
Log.d("Playing", "S s\0");
sendBack.putExtra("Playing", "S s\0");
}
}
context.sendBroadcast(sendBack);
}
}
Broadcast Receiver in Fragment:
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String artistName = intent.getStringExtra("Song");
String trackName = intent.getStringExtra("Artist");
String playing = intent.getStringExtra("Playing");
Log.d("Please", artistName);
Log.d("Please", trackName);
Log.d("Please", playing);
sendMessage(artistName);
sendMessage(trackName);
sendMessage(playing);
}
};
sendMessage Method():
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
Any help would be much appreciated!
http://developer.android.com/samples/BluetoothChat/index.html
To me it looks like sendMessage gets called with null instead of an actual string. Note that intent.getStringExtra(some_string) can return null, if some_string cannot be found.

How to extract a value from a facebook invite friends onComplete() response

I am implementing Facebook friends invite in my android app and I need to get to how many friends user sent app request so that I can award him some points.
What I have done so far is as below
WebDialog requestsDialog = (new WebDialog.RequestsDialogBuilder(this,
sessiob, params)).setOnCompleteListener(
new OnCompleteListener() {
#Override
public void onComplete(Bundle values,FacebookException error) {
if (error != null) {
} else {
final String requestId = values.getString("request");
final String[] requestArr1 = values.getStringArray("to");
if (requestId != null) {
Log.e("RequestId1",requestId + "\n" + values.toString());
else {
Toast.makeText(Login.this,"Request cancelled", Toast.LENGTH_SHORT).show();
}
}
}
}).build();
And the Bundle value I am getting is Bundle[{to[0]=808411111111111,to[1]=151584774222222, request=879734911111111}]
While my above code final String requestId = values.getString("request"); working fine however values.getStringArray("to"); giving me Null.
I want to know value "to" inside the Bundle is a StringArray or not and if yes then what's wrong in my extraction process.
Check out this example you will find your all answers
Simple facebook

Categories