I am new to android. My BLE device expects only one byte(flag). I tried writing only one byte in a byte array but it never works. While writing an array to another characteristic where it expects 2 bytes works. Is there a way to solve my problem or do I have to ask for device code to be changed?
I am working with this project as my example
public void writeCustomCharacteristicStart() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("00001813-0000-1000-8000-00805f9b34fb"));
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found");
return;
}
/*get the read characteristic from the service*/
byte pom= 1;
byte[] data= new byte[1];
data[0]=pom;
BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("00002a4e-0000-1000-8000-00805f9b34fb"));
if((mWriteCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE)>0 ) {
Log.w(TAG,"Writing started");
mWriteCharacteristic.setValue(data)
}
if(!mBluetoothGatt.writeCharacteristic(mWriteCharacteristic)){
Log.w(TAG, "Failed to write characteristic");
}
Log.w(TAG,"Writing ending");
}
08-06 11:59:57.700 29279-29279/com.example.devicescanactivity E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.devicescanactivity, PID: 29279
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:4084)
at android.view.View.performClick(View.java:4858)
at android.view.View$PerformClick.run(View.java:20167)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5931)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:987)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4079)
at android.view.View.performClick(View.java:4858)
at android.view.View$PerformClick.run(View.java:20167)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5931)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:987)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
Caused by: java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither user 10097 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
at android.os.Parcel.readException(Parcel.java:1549)
at android.os.Parcel.readException(Parcel.java:1502)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.writeCharacteristic(IBluetoothGatt.java:1003)
at android.bluetooth.BluetoothGatt.writeCharacteristic(BluetoothGatt.java:1029)
at com.example.devicescanactivity.BluetoothLeService.writeCustomCharacteristic(BluetoothLeService.java:377)
at com.example.devicescanactivity.DeviceControlActivity.onClickWrite(DeviceControlActivity.java:332)
Here is the error, I don't get the BLUETOOTH_PRIVILEGED error, but I don't get any errors when I write to the characteristic that accepts 2 bytes.
First, to use bluetooth in your app, you need to add the following permissions to your app manifest :
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
It is possible to write a 1 byte value to a BLE characteristic, provided the device expects a 1 byte value.
If there is a length issue, you should see the error in the onCharacteristicWrite() callback:
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.i("TAG", "onCharacteristicWrite() status: " + status + " - UUID: " + characteristic.getUuid());
} else if (status == BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH) {
Log.e("TAG", "onCharacteristicWrite() A write operation failed due to invalid attribute length");
} else {
Log.e("TAG", "onCharacteristicWrite() A write operation failed. Status = " + status);
}
}
Also, I would move the writeCharacteristic() call inside your check for PROPERTY_WRITE to ensure the write operation can be done:
if((mWriteCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0 ) {
Log.i(TAG,"Writing started");
mWriteCharacteristic.setValue(data)
if(!mBluetoothGatt.writeCharacteristic(mWriteCharacteristic)){
Log.e(TAG, "Failed to write characteristic");
}
}
The problem wasn't in what I write in the characteristic it was what characteristic I used. I used HID Control Point which when tested on the computer nRF Connect app worked fine for my device but it would not work on android because of its predefined states. We just changed characteristic to Record Access Control Point and it works for now.
Related
I am currently working on an app which requires a Bluetooth laser meter. So i tried a few lines of code and went through a loads of failures. The last error I get is an NPE because i try to access the array returned by getUuids().
I also tried to connect the app to my airPods and everything worked well.
I am at minSdk 27 and targetSdk 31
All bluetooth permissions (bluetooth, bluetooth_admin) are granted.
the fact is, the laser thing requires an app to work and i wonder if the constructor could have blocked some functionalities. if so, i'll look to buy another one from another brand, if someone could provide me a link to buy a device working for my app.
Here's my bluetooth connect code (pretty generic I guess)
I also tried the static UUID suggested in this post but i now get this socket error which (i think) mean the uuid's not working either:
BluetoothAdapter blueAdapter = BluetoothAdapter.getDefaultAdapter();
if (blueAdapter != null) {
if (blueAdapter.isEnabled()) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
Const.requestAllAppPermissions(this);
return;
}
Set<BluetoothDevice> bondedDevices = blueAdapter.getBondedDevices();
if (bondedDevices.size() > 0) {
Object[] devices = bondedDevices.toArray();
BluetoothDevice device = (BluetoothDevice) devices[0];
System.out.println(device.getName());
if (device.fetchUuidsWithSdp()) {
ParcelUuid[] uuids = device.getUuids();
BluetoothSocket socket = null;
try {
//socket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid());
socket = device.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805f9b54fb"));
socket.connect();
} catch (IOException e) {
e.printStackTrace();
}
}
//outputStream = socket.getOutputStream();
// inStream = socket.getInputStream();
} else {
}
} else {
System.out.println("bluetooth disabled");
}
} else {
System.out.println("No bluetooth built-in");
}
here's the static UUID stacktrace:
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
W/System.err: at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:920)
W/System.err: at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:934)
W/System.err: at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:494)
W/System.err: at com.adici.activities.PlanActivity.lambda$defButton$13$com-adici-activities-PlanActivity(PlanActivity.java:409)
W/System.err: at com.adici.activities.PlanActivity$$ExternalSyntheticLambda10.onClick(Unknown Source:2)
W/System.err: at android.view.View.performClick(View.java:7346)
W/System.err: at android.view.View.performClickInternal(View.java:7312)
W/System.err: at android.view.View.access$3200(View.java:846)
W/System.err: at android.view.View$PerformClick.run(View.java:27794)
W/System.err: at android.os.Handler.handleCallback(Handler.java:873)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err: at android.os.Looper.loop(Looper.java:214)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7100)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
I'm open to any suggestion
Looking at the user manual for the Leica DISTO D2 it states the device uses Bluetooth Smart, also known as Bluetooth Low Energy (BLE). You won't be able to connect to it using Bluetooth Sockets (Bluetooth Classic).
Please follow the Android documentation on BLE to develop your app. To debug the connection beforehand, please install a generic BLE scanner such as nRF Connect and investigate the services and characteristics the device offers.
I have an IoT device with BLE on it and also I have a smartphone which support BLE protocol.
I am using RxAndroidBle: com.polidea.rxandroidble2:rxandroidble:1.11.1
The problem is to communicate each other. I have established connection:
#OnClick(R.id.connectButton)
void onConnectButton() {
if (rxBleDevice == null) {
if (myViewModel.getMacAddress().getValue() != null) {
if (!myViewModel.getMacAddress().getValue().isEmpty()) {
// get BLE device
rxBleDevice = SampleApplication.getRxBleClient(this.getActivity())
.getBleDevice(myViewModel.getMacAddress().getValue());
// establish connection
connectionObservable = rxBleDevice.establishConnection(false)
.takeUntil(disconnectTriggerSubject);
// .compose(ReplayingShare.instance());
/*
reason: no instance(s) of type variable(s) T exist so that ReplayingShare<T> conforms to
ObservableTransformer<? super RxBleConnection, ? extends R
*/
statusTextView.setText(R.string.connected);
}
}
} else {
triggerDisconnect();
statusTextView.setText(R.string.disconnected);
}
}
and then I just use the connectionObservable to send data like this:
if (rxBleDevice != null) {
// if (isConnected()) {
final Disposable disposable = connectionObservable
.firstOrError()
.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(uuid, HexString.hexToBytes(data)))
.subscribe(
bytes -> onWriteSuccess(bytes),
throwable -> onWriteFailure(throwable)
);
compositeDisposable.add(disposable);
// }
}
The error what I always got is:
Already connected to device with MAC address EA:A5:34:E6:28:2E, but if i try to isConnected() always says that they are not connected. Is there a way to send data every 300 ms to IoT device?
Full stack trace below.
I/VideoFragment: Write error:
com.polidea.rxandroidble2.exceptions.BleAlreadyConnectedException: Already connected to device with MAC address EA:A5:34:E6:28:2E
at com.polidea.rxandroidble2.internal.RxBleDeviceImpl$1.call(RxBleDeviceImpl.java:84)
at com.polidea.rxandroidble2.internal.RxBleDeviceImpl$1.call(RxBleDeviceImpl.java:72)
at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:33)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableTakeUntil.subscribeActual(ObservableTakeUntil.java:38)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableElementAtSingle.subscribeActual(ObservableElementAtSingle.java:37)
at io.reactivex.Single.subscribe(Single.java:3666)
at io.reactivex.internal.operators.single.SingleFlatMap.subscribeActual(SingleFlatMap.java:36)
at io.reactivex.Single.subscribe(Single.java:3666)
at io.reactivex.Single.subscribe(Single.java:3652)
at com.example.automotive.Fragments.VideoFragment$1.onMove(VideoFragment.java:275)
at io.github.controlwear.virtual.joystick.android.JoystickView$2.run(JoystickView.java:860)
at android.os.Handler.handleCallback(Handler.java:914)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7560)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
isConnected method:
private boolean isConnected() {
return rxBleDevice.getConnectionState() == RxBleConnection.RxBleConnectionState.CONNECTED;
}
Is there a way to send data every 300 ms to IoT device?
Of course there is. If there is no external source of the data to send one could use code similar to:
bleDevice.establishConnection(false)
.flatMap(rxBleConnection ->
Observable.interval(300, TimeUnit.MILLISECONDS)
.flatMap(ignored -> rxBleConnection.writeCharacteristic(uuid, HexString.hexToBytes(data)))
)
.subscribe(
ignored -> {},
error -> { /* log or something */ }
);
The above assumes nothing else is subscribing to bleDevice.establishConnection(false) at the same time.
I think what you wanted to ask is why you get this exception and how to live with it. This exception was introduced to protect users from calling a stateful BLE transmission from multiple places in the code and messing it up. There is a wiki page about it.
You can share a Observable<RxBleConnection by using RxReplayingShare for instance. Then you will not get BleAlreadyConnectedException. You have tried that but apparently commented out the line because the compiler couldn't find out what is the type of object it will replay/share. Perhaps specifying it with ReplayingShare.<RxBleConnection>instance() would help?
I have a problem with connecting my client socket in the Android bluetooth API.
I already read these posts: this one, this one, this one and this one
According to these posts I made my code like the following but it still not work:
class MainActivity : AppCompatActivity()
{
private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
private var connectThread: ConnectThread? = null
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (bluetoothAdapter != null)
{
if (!bluetoothAdapter.isEnabled)
bluetoothAdapter.enable()
val devices = bluetoothAdapter.bondedDevices.toTypedArray()
if (devices.isNotEmpty())
{
connectThread = ConnectThread(devices[0])
connectThread!!.run()
}
}
else
Log.i("BluetoothTest", "No bluetooth supported")
}
override fun onDestroy()
{
super.onDestroy()
connectThread!!.cancel()
}
private inner class ConnectThread(device: BluetoothDevice) : Thread()
{
//private val socket = device.createRfcommSocketToServiceRecord(UUID.fromString ("00001101-0000-1000-8000-00805F9B34FB"))
private val socket = device.javaClass.getMethod("createRfcommSocket", (Int::class
.javaPrimitiveType)).invoke(device, 2) as BluetoothSocket
override fun run()
{
bluetoothAdapter.cancelDiscovery()
socket.connect()
}
fun cancel()
{
socket.close()
}
}
}
Here is the logs with the returned error that comes on socket.connect():
--------- beginning of crash
05-15 15:59:19.553 24176-24176/com.bluetoothtest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bluetoothtest, PID: 24176
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bluetoothtest/com.bluetoothtest.MainActivity}: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:685)
at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:697)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:374)
at com.bluetoothtest.MainActivity.onCreate(MainActivity.kt:36)
at android.app.Activity.performCreate(Activity.java:6999)
at android.app.Activity.performCreate(Activity.java:6990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
It seems that the problem appeared after Android 4.3 because of the port value of the socket
I am on Android 7.1 and 8.1
Does someone knows how to make bluetooth work on Android ?
Finally, the root cause was because the socket's inputStream couldn't be read. That's because there was no open socket with the same UUID on the server side.
See https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r30/core/java/android/bluetooth/BluetoothSocket.java
So to fix the problem we need a listening socket with the same UUID on the other side, for me it was a raspberry in python:
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "YOUR UUID"
advertise_service( server_sock, "SampleServer", service_id = uuid, service_classes = [ uuid, SERIAL_PORT_CLASS ], profiles = [ SERIAL_PORT_PROFILE ])
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
except IOError:
pass
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
from https://github.com/karulis/pybluez/blob/master/examples/simple/rfcomm-server.py
I can successfully write to an RN4020 module from my Android device. An LED lights up on the module to indicate successful receipt of transmission and I can see the ASCII character transmitted to RN4020 on an Arduino terminal.
The problem is: when I try to send characters in quick succession (for example, each time when a button on my Android app is pressed very quickly) then after 5 to 10 successful transmissions:
RN4020 stops receiving: the LED to indicate Rx never turns on and I can't see transmitted characters on the terminal.
Most times Android device doesn't recognize that the write failed but sometimes I get the following error:
D/BluetoothGatt: writeCharacteristic: mDeviceBusy = true, and return false
My code to write to BLE (everytime a button is clicked I call sendDataToRN4020):
public boolean sendDataToRN4020(char instruction){
//check mBluetoothGatt is available
if (mBluetoothGatt == null) {
Log.e(TAG, "lost connection");
return false;
}
BluetoothGattService Service = mBluetoothGatt.getService(UUID.fromString("<address uuid>"));
if (Service == null) {
Log.e(TAG, "service not found!");
return false;
}
BluetoothGattCharacteristic charac = Service.getCharacteristic(UUID.fromString("<service uuid>"));
if (charac == null) {
Log.e(TAG, "char not found!");
return false;
}
byte[] value = new byte[1];
value[0] = (byte) (instruction);
charac.setValue(value);
boolean status = mBluetoothGatt.writeCharacteristic(charac);
return status;
}
This is my callback for writeCharacteristic:
#Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.i(TAG, "Successful transmission");
}
}
This may not be an Answer to your problem but I have not enough reputation to comment so I made an answer, I worked in an application using BLE to transfer data, I ran into a problem similar in which the app stops transmission even when the BLE device it's displaying that there's connection, this was because I had a scanner for compatible BLE devices, sometimes the app connects to a device multiple times because the app is constantly scanning for signals, don't know if you are doing something similar but I would recommend the following, before making a connection make sure that if there's a previous one, disconnect:
public static void connect(final String address, final String devicename, Context context) {
mContext = context;
if (mBluetoothAdapter != null && address != null) {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device != null) {
forceDisconnect();
Log.i(TAG,"starting connection");
mBluetoothGatt = device.connectGatt(context, false, mGattCallback);
}
}
This is the method to disconnect:
public static void forceDisconnect(){
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect(); // from any connected device
if (mBluetoothGatt != null) mBluetoothGatt.close();
mBluetoothGatt = null;
}
I'm not sure if this is going to be of any help, what I can tell you is that after I did this adjustments to my code I was able to send data from the BLE device without issues, perhaps it's worth knowing how is your connection code to the BLE device, anyways hope it helps.
The problem was eventually resolved. The code in the question runs perfectly on a recently released Android device. The reason the failure was happening was that the device being used for testing at the time of posting this question was at least 3 years old. Newer devices have more robust support for BLE.
First upon all this is not a duplicate question or have been answered on stackoverflow or xamarin forums. On xamarin forums this problem/question is still under discussion so i have posted it here.
So the problem with my app and also bunch of others which have been developed in Xamarin.Android reporting crashes (opt-in and opt-out) on Google's play console.
App actually not crashing. It just reporting automated crash reports to Google's play console.
Following is crash Stack Traces for Android 6.0 and 7.0 :
java.lang.RuntimeException:
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException:
at java.lang.reflect.Method.invoke(Native Method:0)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:726)
In Android 5.1 and 5.0 :
java.lang.RuntimeException:
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.reflect.InvocationTargetException:
at java.lang.reflect.Method.invoke(Native Method:0)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
For Android 4.2 and 4.4 :
java.lang.RuntimeException:
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method:0)
Caused by: java.lang.reflect.InvocationTargetException:
at java.lang.reflect.Method.invokeNative(Native Method:0)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
Seems this exception occurring majorly in Android 6.0 and 7.0. Above is the only stack traces google play console provided for my and other developers app. There is not any detailed trace available yet.
For my app, crash reported whenever notification received on app. It impacting all of the app users at exact same time when they received notification.
Images of crash reports at the time of notification recieved
Following is the my FCM code :
MainActivity :
Task.Run(() =>
{
var instanceid = FirebaseInstanceId.Instance;
instanceid.DeleteInstanceId();
Log.Debug("TAG", "{0} {1}", instanceid.Token, instanceid.GetToken(this.GetString(Resource.String.gcm_defaultSenderId), Firebase.Messaging.FirebaseMessaging.InstanceIdScope));
});
Token Registration :
[Service]
[IntentFilter(new[] {
"com.google.firebase.INSTANCE_ID_EVENT"
})]
class MyFirebaseIIDService : FirebaseInstanceIdService
{
const string TAG = "MyFirebaseIIDService";
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
}
void SendRegistrationToServer(string token) { }
}
OnMessageReceived :
[Service]
[IntentFilter(new[] {
"com.google.firebase.MESSAGING_EVENT"
})]
class MyFireMessagingService : FirebaseMessagingService
{
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
var title = string.Empty;
if (message.Data.Count > 0)
{
//Log.Debug(Tag, "Message data payload: " + message.Data);
title = message.Data["title"];
}
SendNotificatios(title);
}
public void SendNotificatios( string Header)
{
Notification.Builder builder = new Notification.Builder(this);
builder.SetSmallIcon(Resource.Drawable.Icon);
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
PendingIntent pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
builder.SetContentIntent(pendingIntent);
// builder.SetLargeIcon(BitmapFactory.DecodeResource(Resources, Resource.Drawable.Icon));
builder.SetContentTitle(Header);
builder.SetPriority(1);
builder.SetContentText("read more..");
builder.SetVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
builder.SetSound(Android.Net.Uri.Parse("android.resource://" + Application.PackageName + "/" + Resource.Raw.demonstrative));
builder.SetAutoCancel(true);
Random r = new Random();
int uniw = r.Next(1, 10);
NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(uniw, builder.Build());
}
}
Note : Notification works fine, just whenever notification arrived app reported crash to Google play console.
Please if anyone have any knowledge related to this problem will be helpful. TIA