Android BLE scan/connect/notify - bluetooth-lowenergy

I want to developing an app to communicate with a BLE device.
I have NO experience in developing any sort of Bluetooth application using Android.
if any example source code for app can scan-connect and read some characteristic.
its hard to get a working source code

I'd suggest using Kotlin, you can do exactly what you ask for in Kotlin.
Here's an example of scanning for Bluetooth devices:
fun scanForBluetoothDevices() {
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if (bluetoothAdapter == null) {
// Device doesn't support Bluetooth
}
if (!bluetoothAdapter.isEnabled) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter.bondedDevices
// If there are paired devices
if (pairedDevices?.isNotEmpty() == true) {
// Loop through paired devices
pairedDevices.forEach { device ->
// Add the name and address to an array adapter to show in a ListView
Log.d("Bluetooth", "Device: ${device.name}, ${device.address}")
}
}
}

Related

Simultaneous scanning of barcodes and text(OCR) in xamarin

I have a scanner app where we scan the barcodes and Text on the same camera. I have done this in xamarin with the help of Xamarin.Firebase.IOS.MlKit.
In this when the camera is open, we do continous capturing of image frames, and send the captured image for barcode detection and OCR recognition seperately.
public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
{
lastRunTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
if (lastRunTime - lastAnalysisTime > scanIntervalInMs)
{
lastAnalysisTime = lastRunTime;
try
{
var image = GetImageFromSampleBuffer(sampleBuffer);
if(image == null) return;
var visionImage = new VisionImage(image) {Metadata = metadata };
releaseSampleBuffer(sampleBuffer);
if(isScanningBarcode)
{
DetectBarcodeActionAsync(visionImage);
isScanningBarcode = false;
}
else
{
isScanningBarcode = true;
DetectTextActionAsync(visionImage);
}
}
catch (Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception.Message);
}
}
releaseSampleBuffer(sampleBuffer);
}
//Barcode detection
private async void DetectBarcodeActionAsync(VisionImage image)
{
VisionBarcode[] barcodes = await barcodeDetector.DetectAsync(image);
}
//OCR
private async void DetectTextActionAsync(VisionImage image)
{
VisionText txt = await textRecognizer.ProcessImageAsync(image);
}
This runs properly. But our app is used in package scanning to scan address labels (names of the recipient) and barcodes. So, when the barcodes are damaged or curved/skewed, this MLKit barcode fails to scan such barcodes, and this is quite frustrating for the clients.
Is there a way we can improve upon the MLKIt barcode scanner to scan such damaged barcodes.
I tried the same with some premium scanners like ScanBot and SCandit demo apps, which were able to scan the damaged barcodes quite easily. I had a talk with ScanBot customer service, but they do not provide SIMULTANEOUS barcode and OCR scanning. I am also looking in this ScanDit SDK to accomplish the same.
Can anyone suggest some premium scanners for xamarin app which scans barcodes and OCR in one go. OR any improvements which can be made to existing MLKit scanner so that it can scan damaged/skewed barcodes.

Bi-Directional Communication via IoTHub/Xamarin App/ESP8266

Working on a new product at work that will be using an ESP8266, Xamarin app, and the Azure IoTHub to enable bidirectional communication for customer's devices.
We've got C2D (Cloud 2 Device) and D2C (Device 2 Cloud) communication working properly on both the app and the ESP, but we are not finding any information on setting up the IoTHub to interpret incoming Telemetry messages, process their respective "To:" field and put them back in to the C2D topic, which should allow our target device to receive it.
What we have tried:
Logic Apps. Were able to trigger on incoming messages to the queue, but not sure what HTTP request to do in order to forward it back in to the C2D event hub.
We have successfully been able to forward each message in to a queue, but the PCL library for Xamarin is not capable of connecting to Azure Service Bus Queues (bummer).
I found a reference for an intern at Microsoft developing direct device to device communication for a garage door opener, but the library she is using is only available for UWP apps, which isn't all that convenient, when we really want to target iOS, Android and UWP (reason for choosing Xamarin in the first place).
https://blogs.windows.com/buildingapps/2016/09/08/device-to-device-communication-with-azure-iot-hub/#ykPJrVE734GpSEzV.97
Has anyone been able to trigger C2D conditional events using the Azure portal?
Through some conversations with Microsoft Azure team, we determined that a webjob combined with a route to a queue was the best solution for us.
All messages are routed to the queue and as they arrive in the queue, the webjob processes the message and sends the message on using a ServiceBus Messaging object to send the cloud to device response message.
Here's the code for anyone who wants to use it.
As long as the original sender of the message specifies the "To" property in the brokered message, it will be delivered to that device in the registry. You will need the Service Bus and Azure.Messaging NuGet packages in order to use this. This code will copy the entire message and send the whole thing to the desired registry device.
private const string queueName = "<queue_name>";
private const string IoTHubConnectionString = "HostName=<your_host>;SharedAccessKeyName=<your_service_user>;SharedAccessKey=<your sas>";
// This function will get triggered/executed when a new message is written
// on an Azure Queue called <queue_name>.
public static void ReceiveQueueMessages(
[ServiceBusTrigger(queueName)] BrokeredMessage message,
TextWriter log)
{
if (message.To == null)
{
//message = null
return;
}
else
{
//Retrieve the message body regardless of the content as a stream
Stream stream = message.GetBody<Stream>();
StreamReader reader;
if (stream != null)
reader = new StreamReader(stream);
else
reader = null;
string s;
Message serviceMessage;
if ( reader != null )
{
s = reader.ReadToEnd();
serviceMessage = new Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes(s));
}
else
{
serviceMessage = new Microsoft.Azure.Devices.Message();
}
foreach (KeyValuePair<string, object> property in message.Properties)
{
serviceMessage.Properties.Add(property.Key, property.Value.ToString());
}
SendToIoTHub(message.To.ToString(), serviceMessage);
}
}
static async void SendToIoTHub(string target, Microsoft.Azure.Devices.Message message)
{
// Write it back out to the target device
ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(IoTHubConnectionString);
var serviceMessage = message;
serviceMessage.Ack = DeliveryAcknowledgement.Full;
serviceMessage.MessageId = Guid.NewGuid().ToString();
try
{
await serviceClient.SendAsync(target, serviceMessage);
}
catch
{
await serviceClient.CloseAsync();
return;
}
await serviceClient.CloseAsync();
}

Push Notification using RHMAP

I am trying to send push notification using RHMAP to iOS devices. Can anyone please let me know how to send push notification to specific device ID using RHMAP. I am able to send notification to all the devices but not to a specific device.
I couldn't find anything regarding this in RHMAP documentation also.
RHMAP has a lot of documented material and examples about push notifications.
The information that you are looking for is in the section "2.3.4.2. Recipient filtering"[1] of the Product features documentation.
"alias - user identification, such as a user name or an e-mail representing a single person (with possibly multiple devices). Intended to enable a unicast communication model."
For more information and examples you can check to fh.push client API[2] and fh.push cloud API[3]. There you can find the following example with filter criteria in the push notifications.
Push a message for specific deviceType in a specific Client App
var message = {
alert: "hello from FH"
},
options = {
apps: ["3uzl1ebi6utciy56majgqlj8"], // list of App IDs
criteria: {
deviceType: "android"
}
};
$fh.push(message, options,
function (err, res) {
if (err) {
console.log(err.toString());
} else {
console.log("status : " + res.status);
}
});
In the example above, for you implement your method using alias, you need to change the deviceType for alias as the following example.
alias: [] // Set here the alias that you are looking for
The following is an example for Android.
import com.feedhenry.sdk.PushConfig;
..........
......
...
private void register() {
PushConfig p = new PushConfig();
p.setAlias("my-alias");
FH.pushRegister(p, new FHActCallback() {
#Override
public void success(FHResponse fhResponse) {
startActivity(new Intent(RegisterActivity.this, MessagesActivity.class));
}
#Override
public void fail(FHResponse fhResponse) {
Toast.makeText(getApplicationContext(),
fhResponse.getErrorMessage(), Toast.LENGTH_SHORT).show();
finish();
}
});
}
[1] - https://access.redhat.com/documentation/en-us/red_hat_mobile_application_platform_hosted/3/html-single/product_features/#sending-notifications
[2] - https://access.redhat.com/documentation/en-us/red_hat_mobile_application_platform_hosted/3/html-single/client_api/#fh-push
[3] - https://access.redhat.com/documentation/en-us/red_hat_mobile_application_platform_hosted/3/html-single/cloud_api/#fh-push
You can set an alias for the device and use that alias to send the notification to it.
As you don't mention which SDK (Objective-C, Swift, Cordova) are you using I can't help you on how to set the alias as it's different for each of them, if you provide more information I can try to help you.

scheduleLocalNotification in iOS 10 device using iOS 9.3 SDK when in foreground

I am having an issue with scheduling a local notification in an iOS 10 device when using iOS 9.3 SDK, when app is in foreground. Our application is designed in such a way that if we receive a remote notification and application is currently in foreground, we repost it to local so the user can still see the notification when they put the app in background. This works in iOS 9 devices, but not in iOS 10.
Repost code:
dispatch_async(dispatch_get_main_queue(), {
let localNotification = UILocalNotification()
localNotification.userInfo = userInfo;
localNotification.fireDate = NSDate()
localNotification.timeZone = NSTimeZone.localTimeZone()
localNotification.soundName = UILocalNotificationDefaultSoundName
if let apnsPayload = userInfo["aps"] {
if let alert = apnsPayload["alert"] as? NSDictionary {
if let message = alert["body"] as? String {
localNotification.alertBody = message
}
}
if let category = apnsPayload["category"] {
localNotification.category = category as? String
}
}
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
})
I believe the reposting with scheduleLocalNotification is working somewhat correctly because I can see that my didReceiveLocalNotification delegate is getting called in AppDelegate. However, if I pull the notification drop down when putting app in foreground or background there is no notification present.
Has anyone else run into this problem? I have seen a lost of posts with how to use iOS 10 UNUserNotificationCenter, but I do not have access to this in iOS 9.3 SDK.
This seems to be just the new expected handling in iOS 10. If you post a notification while app is in foreground, it will call the didReceiveLocalNotification delegate, however it will not post it to the notification center tray.
To get around this, I am now storing all received notifications in a static array, and then when app goes to background I will schedule the notifications to be sent in 5 seconds, just to give the app time enough to completely go to background.
Creating/Appending the notifications:
/**
Takes a given Dictionary that should correspond to a Remote notification and reposts it (at current time)
as a Local Notification. If the app is in the foreground, then no banner, alert, or sound will play, but the
notification should appear in the Notification Center.
- parameter userInfo: Dictionary that should correspond to a Remote notification.
*/
static func repostLocalNotificationUsingRemote(userInfo: Dictionary<NSObject, AnyObject>) {
let localNotification = UILocalNotification()
localNotification.userInfo = userInfo;
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.timeZone = NSTimeZone.localTimeZone()
localNotification.soundName = UILocalNotificationDefaultSoundName
if let apnsPayload = userInfo["aps"] {
if let alert = apnsPayload["alert"] as? NSDictionary {
if let message = alert["body"] as? String {
localNotification.alertBody = message
}
}
if let category = apnsPayload["category"] {
localNotification.category = category as? String
}
}
// Add notification to queue
localNotificationQueue.append(localNotification)
}
Eventually Sending, called in applicationDidEnterBackground and applicationWillTerminate:
/**
Posts all pending notifications that were received while app was in foreground.
*/
static func postPendingLocalNotificationIfAny() {
for localNotification in localNotificationQueue {
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
localNotificationQueue.removeAll();
}
Ideally we will be updating to iOS 10 SDK and use UNUserNotificationCenter to display notifications in the app, but until then this change matches are current iOS 9 behavior.

Scan for available Wi-Fi networks on BlackBerry

Is there any RIM API available which will help to get the list of available network service or only Wi-Fi networks for a device and set selected network access point for any network communications?
Is it possible for my application to disable the mobile networks like GPRS, WAP, etc.?
Example:
When the application is started it should scan for Wi-Fi connections, even if there are no previous Wi-Fi network access points set on the device, and list the available Wi-Fi connections. Then the user will select the appropriate Wi-Fi connection to connect for any network communication. Outside the application any Internet communication, like the browser or any other application, should be done through the same selected Wi-Fi connection.
The scanning for Wi-Fi and setting the connection is almost similar to BlackBerry Wi-Fi Setup.
I am looking to do this for BlackBerry OS 4.5, 4.7 and 5.0.
Update
The thing is I'm looking for Wi-Fi scanning through application. It's like through the application I am able to scan available Wi-Fi access points or hotspots and set one of access point by selecting it to device, then connect to it for communication.
Basically it's like, how do we set the Wi-Fi connection in "Manage connetion" of BlackBerry? I have to do a similar thing through the applicaiton.
From some BlackBerry forums I got to know there is package in OS v5.0, that is, a net.rim.device.api.wlan.hotspot package to get the Wi-Fi hotspots. But after a long search I didn't find any sample example or much explanation on it. As I am trying to implement by looking into its API documentation, but I did not succeded.
If you have any idea related to this or any sample code it will be very helpful.
Well, to scan for all available networks for the application you can use the NetworkDiagnostic tool from RIM.
Anther piece of code to scan for your phone connectivity and get the best connection string can be found in How to reliably establish a network connection on any BlackBerry device,
/**
* Determines what connection type to use and returns the necessary string to use it.
* #return A string with the connection info
*/
private static String getConnectionString()
{
// This code is based on the connection code developed by Mike Nelson of AccelGolf.
// http://blog.accelgolf.com/2009/05/22/blackberry-cross-carrier-and-cross-network-http-connection
String connectionString = null;
// Simulator behavior is controlled by the USE_MDS_IN_SIMULATOR variable.
if (DeviceInfo.isSimulator())
{
if (UploaderThread.USE_MDS_IN_SIMULATOR)
{
logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is true");
connectionString = ";deviceside=false";
}
else
{
logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is false");
connectionString = ";deviceside=true";
}
}
// Wi-Fi is the preferred transmission method.
else if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
{
logMessage("Device is connected via Wifi.");
connectionString = ";interface=wifi";
}
// Is the carrier network the only way to connect?
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT)
{
logMessage("Carrier coverage.");
String carrierUid = getCarrierBIBSUid();
if (carrierUid == null)
{
// Has carrier coverage, but not BIBS. So use the carrier's TCP network
logMessage("No Uid");
connectionString = ";deviceside=true";
}
else
{
// otherwise, use the Uid to construct a valid carrier BIBS request
logMessage("uid is: " + carrierUid);
connectionString = ";deviceside=false;connectionUID="+carrierUid + ";ConnectionType=mds-public";
}
}
// Check for an MDS connection instead (BlackBerry Enterprise Server).
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS)
{
logMessage("MDS coverage found");
connectionString = ";deviceside=false";
}
// If there is no connection available abort to avoid bugging the user unnecssarily.
else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE)
{
logMessage("There is no available connection.");
}
// In theory, all bases are covered so this shouldn't be reachable.
else
{
logMessage("no other options found, assuming device.");
connectionString = ";deviceside=true";
}
return connectionString;
}
/**
* Looks through the phone's service book for a carrier provided BIBS network
* #return The uid used to connect to that network.
*/
private static String getCarrierBIBSUid()
{
ServiceRecord[] records = ServiceBook.getSB().getRecords();
int currentRecord;
for (currentRecord = 0; currentRecord < records.length; currentRecord++)
{
if (records[currentRecord].getCid().toLowerCase().equals("ippp"))
{
if (records[currentRecord].getName().toLowerCase().indexOf("bibs") >= 0)
{
return records[currentRecord].getUid();
}
}
}
return null;
}

Resources