I'm trying to show chainging rssi on the list that shows scanned device.
[enter image description here][1]
I want to express chainging rssi value at rssi : _____ from the picture.
I'm able to get chainging rssi value on log, like the picture.
[enter image description here][2]
Please help me.
You will need a scan intervall, that "refreshes" the RSSI by rescanning for devices. Sth. like this:
public void scanLeDevice(final boolean enable)
{
final static int SCAN_PERIOD = 2000; //2s
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
final BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
//to start or stop scanning (true/false)
if (enable)
{
// Stops scanning after a pre-defined scan period
mHandler.postDelayed(new Runnable()
{
#Override
public void run()
{
mBluetoothAdapter.stopLeScan(mLeScanCallback);
if (mGatt == null)
offScan();
}
}, SCAN_PERIOD);
mBluetoothAdapter.startLeScan(mLeScanCallback);
}
else
{
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
Related
I am trying to get the rssi value of a connected bluetooth device in my android program.
Below is the code:
gatt = mDevice.connectGatt(getApplicationContext(), false, new BluetoothGattCallback() {
#Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
Log.d(TAG, "rssi is : " + rssi);
((TextView) findViewById(R.id.rssiValue)).setText(rssi);
}
});
gatt.readRemoteRssi();
But the method onReadRemoteRssi doesnot return any value.
Please help me with the issue.
if(ContextCompat.checkSelfPermission(RSSI.this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
RSSI.this,
new String[] {
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_FINE_LOCATION
},
1
);
}
Make sure that the mDevice variable retrieved from BlueetoothAdapter is not null
Lastly make sure the permissions are set, the above code will give you required privileges to get Bluetooth bonded device(s).
In my app, I have a searchbox which allows users to filter as they type. For some reason I can't get an InfinteProgress to properly display while the filtering is being executed.
Here's my code:
Pass 1
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
Display.getInstance().invokeAndBlock(new Runnable() {
#Override
public void run() {
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
Display.getInstance().callSerially(new Runnable() {
#Override
public void run() {
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
});
}
});
}
In this version, the infinite progress shows up in the proper position, but it doesn't spin.
Pass 2
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
}
}
In this version, the magnifier icon just flashes briefly, but the InfiniteProgress spinner is never visible.
I get the same results on the simulator and on an Android device.
How can I get the InfiniteProgress to spin while the search is taking place?
invokeAndBlock opens a new thread and thus violates the EDT as you access UI components on a separate thread.
Try using callSerially instead to postpone the following code into the next EDT cycle although I'm not sure that will help as everything is still happening on the EDT.
Alternatively I'm guessing the method isVisible takes time, so you can enclose that call alone in invokeAndBlock.
To understand invokeAndBlock check out the developer guide https://www.codenameone.com/manual/edt.html
Android 4.4 tested in Eclipse.
I've followed the lines as developers said. So in my fragment I put:
public void tomarfoto() {
// Check Camera
if (MainActivity.if_cam) {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
this.startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
} else {
//Toast.makeText(getActivity(), "Camera not supported", Toast.LENGTH_LONG).show();
}
}
After that, I set this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(getActivity(), "Image saved to:\n" +data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
The problem is that data intent is null and provokes this:
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=android:fragment:0, request=1888, result=-1, data=null}
to activity {com.myapp.MainActivity}: java.lang.NullPointerException
I don't understand so much but apparently the onActivityResult is disconnected from the fragment who has called it so, it can't receive data results. How can I solve this?. The launchMode="singleTask" or singleInstance is not my problem, I didn't settled this.
The pictures are saved properly in the directory held by fileUri. Help.
this will be my first post and I will do my best to be clear and concise. I've checked some of the other posts on this forum but was unable to find a satisfactory answer.
My question pertains to the use of JavaFX and the jSSC(java simple serial connection) library. I've designed a very simple GUI application that will host four different charts. Two of the charts will display readings from temperature and solar sensors for the past hour, while the other two display that data over an extended period -- a 14-hour period. Eventually I would like to make that more flexible and set the application to "sleep" when the readings become roughly zero (night).
How can I stream data to display this data in real time?
After referencing several sources online and from "JavaFX 8 Intro. by Example", I've been able to construct most of the serial connection class. I'm having trouble processing the data readings, so that it can be displayed on the chart.
public class SerialComm implements SerialPortEventListener {
Date time = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("mm");
boolean connected;
StringBuilder sb;
private SerialPort serialPort;
final StringProperty line = new SimpleStringProperty("");
//Not sure this is necessary
private static final String [] PORT_NAMES = {
"/dev/tty.usbmodem1411", // Mac OS X
"COM11", // Windows
};
//Baud rate of communication transfer with serial device
public static final int DATA_RATE = 9600;
//Create a connection with the serial device
public boolean connect() {
String [] ports = SerialPortList.getPortNames();
//First, Find an instance of serial port as set in PORT_NAMES.
for (String port : ports) {
System.out.print("Ports: " + port);
serialPort = new SerialPort(port);
}
if (serialPort == null) {
System.out.println("Could not find device.");
return false;
}
//Operation to perform is port is found
try {
// open serial port
if(serialPort.openPort()) {
System.out.println("Connected");
// set port parameters
serialPort.setParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex); }
}
});
}
} catch (Exception e) {
System.out.println("ErrOr");
e.printStackTrace();
System.err.println(e.toString());
}
return serialPort != null;
}
#Override
public void serialEvent(SerialPortEvent spe) {
throw new UnsupportedOperationException("Not supported yet.");
}
public StringProperty getLine() {
return line;
}
}
Within the try block, I understand the port parameters, but the eventListener is where I am having difficulty. The significance of the stringbuilder is to append data the new data as it is read from the device.
How will I account for the two sensor readings? Would I do that by creating separate data rates to differentiate between the incoming data from each sensor??
I hope that this is clear and that I've provided enough information but not too much. Thank you for any assistance.
-------------------------------UPDATE--------------------------
Since your reply Jose, I've started to make the additions to my code. Adding the listener within the JavaFX class, I'm running into some issues. I keep getting a NullPointerException, which I believe is the String[]data not being initialized by any data from the SerialCommunication class.
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
} catch (Exception e) {
System.err.println(e.toString());
}
I'm adding the time to the data being read. As Jose mentioned below, I've added tags to the data variables within the arduino code, I'm using: Serial.print("Solar:"); Serial.println(solarData);
Rough code of the JavaFx listener:
serialPort.getLine().addListener((ov, t, t1) -> {
Platform.runLater(()-> {
String [] data = t1.split(":");
try {
//data[0] is the timestamp
//data[1] will contain the label printed by arduino "Solar: data"
switch (data[1]) {
case "Solar":
data[0].replace("Solar:" , "");
solarSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
case "Temperature":
temperatureSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
}
Is the reason this code has NullPointerException a result of the String [] data array being uninitialized?
Exception Error
Ports: /dev/tty.usbmodem1411Connected
Exception in thread "EventThread /dev/tty.usbmodem1411" java.lang.NullPointerException
at SerialComm.lambda$connect$0(SerialComm.java:61)
at SerialComm$$Lambda$1/1661773475.serialEvent(Unknown Source)
at jssc.SerialPort$LinuxEventThread.run(SerialPort.java:1299)
The SerialPortEventListener defined in the jssc library allows listening for serial port events. One of those events is the RXCHAR event, that occurs when the Arduino board is sending some data and some bytes are on the input buffer.
event.getEventValue() returns an int with the byte count, and serialPort.readString(event.getEventValue()) get the String format from those bytes.
Note that this method does not return a full line, so you need to listen to carriage return and line feed characters. Once you find "\r\n", you can get the line, and reset the StringBuilder for the next one:
sb.append(serialPort.readString(event.getEventValue()));
String str=sb.toString();
if(str.endsWith("\r\n")){
line.set(str.substring(0,str.indexOf("\r\n")));
sb=new StringBuilder();
}
where line is an observable String:
final StringProperty line=new SimpleStringProperty("");
On the Arduino side, if you want to send values from different sensors at different rates, I suggest you define on the Arduino sketch some identification string for each sensor, and you print for each value the id of its sensor.
For instance, these will be the readings you will get with the serial event listener:
ID1,val1
ID1,val2
ID2,val3
ID1,val4
ID3,val5
...
Finally, on the JavaFX thread, define a listener to changes in line and process the String to get the sensor and the value. Something like this:
serial.getLine().addListener(
(ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
Platform.runLater(()->{
String[] data=newValue.split("\\,");
if(data[0].equals("ID1"){
// add to chart from sensor 1, value data[1];
} else if(data[0].equals("ID2"){
// add to chart from sensor 2, value data[1];
} else if(data[0].equals("ID3"){
// add to chart from sensor 3, value data[1];
}
});
});
Note you need to add Platform.runLater(), since the thread that gets the data from serial port and updates line is not on the JavaFX thread.
From my experience, on the Arduino side, add a comma or something to separate the different values when you print and when you receive that string in Java simply split that string by commas.
String[] stringSeparate = str.split(",");
I'm having a difficult time getting my health bar to sync through the server on Unity using RPCs. In my game, the characters have health bars over their heads that are supposed to update for the entire server. That way you can just look at another player and see their health bar. The problem is that even though I send the information through the network and it's received, the actual physical bar doesn't change in scale. The player who sends the call has their bar changed though.
Here's a screenshot of the issue: http://i.imgur.com/g2GozZv.png
When I send the RPC, It does change the other player's health value, but does nothing to the scale.
I did the following code and it doesn't work:
void Start()
{
if(!networkView.isMine)
{
enabled = false;
}
}
void Update ()
{
if(Input.GetKey(KeyCode.Alpha2))
{
Minus_Health();
}
}
public void Minus_Health()
{
health -= 10;
healthBarLength = (float)health / (float)maxHealth / 5.1f;
healthBar.scale = new Vector2(healthBarLength, healthBar.scale.y);
Update_HP(health, maxHealth, healthBar.scale);
}
public void Update_HP(int hp, int maxHP, Vector3 bar)
{
networkView.RPC("Update_Health",RPCMode.All, hp, maxHP, bar);
}
[RPC]
public void Update_Health(int value, int value2, Vector3 bar)
{
health = value;
maxHealth = value2;
healthBar.scale = new Vector2(bar.x, bar.y);
}
I've also tried this, with no luck either:
void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
if (stream.isWriting)
{
Vector3 networkHealth = healthBar.scale;
stream.Serialize(ref networkHealth);
}
else
{
Vector3 networkHealth = Vector3.zero;
stream.Serialize(ref networkHealth);
healthBar.scale = networkHealth;
}
}
I found the problem. The code itself was working great (and you're right pek, that bar parameter was just tedious).
The problem was actually with the ex2D plugin I was using for the health bar. On each exSprite there is a camera view, set to the user's main camera. Because it was set to my camera on player instantiate, it was only seeing my bar through my camera, thus not updating the other bar via client / server side. By clicking on the texture and setting the ex2D exSprite's Camera to None, I can now see both bars being updated / scaled properly.
In hopes that this can help anyone looking for how to do health bars over a network, here is the final code I'm using:
using UnityEngine;
using System.Collections;
public class PlayerStats : MonoBehaviour
{
public int health;
public int maxHealth;
public float healthBarLength = 0;
public exSprite healthBar;
void Start()
{
if(!networkView.isMine)
{
enabled = false;
}
}
void Update ()
{
if(Input.GetKey(KeyCode.Alpha2))
{
Minus_Health();
Update_HP(health, maxHealth);
}
}
public void Minus_Health()
{
health -= 10;
}
public void Update_HP(int hp, int maxHP)
{
networkView.RPC("Update_Health", RPCMode.AllBuffered, hp, maxHP);
}
[RPC]
public void Update_Health(int value, int value2)
{
health = value;
maxHealth = value2;
healthBarLength = (float)value / (float)value2 / 5.1f;
healthBar.scale = new Vector2(healthBarLength, healthBar.scale.y);
}
}
Also, a small tip for those who get errors when setting the exSprite Camera to None; You need to update your ex2D plugin.
Thanks for the help pek and I hope this can help someone! :)
If all the parameters in Update Health are correct, then there might be something else that is affecting the scale.
Also, if value and value2 are sent correctly, then there is no need for the bar parameter:
[RPC]
public void Update_Health(int value, int value2)
{
health = value;
maxHealth = value2;
healthBarLength = (float)health / (float)maxHealth / 5.1f;
healthBar.scale = new Vector2(healthBarLength, healthBar.scale.y);
}