Following on from this question, I'm also having trouble getting a Bluetooth watcher to receive advertisements on HoloLens 2. I've run through the example here with no luck running scenario 2 on my laptop and scenario 1 on my HoloLens.
My HoloLens does not appear to be triggering any received events. I've tried restarting the HoloLens and checking for updates. I'm currently running OS build 20346.1403.
Would greatly appreciate any help troubleshooting. I have been able to get the regular BluetoothLE sample to run correctly, however my eventual goal is to get all this to run from within a Unity application and again for some reason the watcher isn't receiving any events with the regular BluetoothLE code from my Unity application.
If anyone has experience with Unity and bluetoothLE examples I'd very much like to learn more about it.
using TMPro;
using UnityEngine;
#if WINDOWS_UWP
using Windows.Devices.Bluetooth.Advertisement;
using System.Runtime.InteropServices.WindowsRuntime;
#endif
public class GPSReceiver : MonoBehaviour
{
public TextMeshProUGUI debugText;
#if WINDOWS_UWP
BluetoothLEAdvertisementWatcher watcher;
#endif
public static ushort BEACON_ID = 1775;
public EventProcessor eventProcessor;
void Awake()
{
#if WINDOWS_UWP
watcher = new BluetoothLEAdvertisementWatcher();
BluetoothLEManufacturerData manufacturerData = new BluetoothLEManufacturerData
{
CompanyId = BEACON_ID
};
watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);
watcher.Received += Watcher_Received;
watcher.Start();
debugText.text = "Watcher status: " + watcher.Status.ToString() + " " + watcher.ScanningMode.ToString();
#endif
}
#if WINDOWS_UWP
private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
debugText.text = "received bytes";
ushort identifier = args.Advertisement.ManufacturerData[0].CompanyId;
byte[] data = args.Advertisement.ManufacturerData[0].Data.ToArray();
// Updates to Unity UI don't seem to work nicely from this callback so just store a reference to the data for later processing.
eventProcessor.QueueData(data);
}
#endif
}
Related
I have the configuration in Unity and Firebase correctly, I receive the notifications on the mobile when I send them through the firebase panel, when I tap on the notification the app opens without problems, but when I try to retrieve the message data such as the title in the app, it crashes and closes. When I retrieve only the token, it does show it.
This is the code that I am using, if anyone knows what it is due to, I would appreciate if you have the solution, the app does not generate any error in the log, it simply closes when I add the line of code: textDisplay_2.text = notification.Title ;
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PushNot : MonoBehaviour
{
public TextMeshProUGUI textDisplay_1;
public TextMeshProUGUI textDisplay_2;
// Start is called before the first frame update
public void Start()
{
textDisplay_1.text = "inicia app";
Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}
public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
{
UnityEngine.Debug.Log("Received Registration Token: " + token.Token);
textDisplay_1.text = token.Token;
}
public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
{
UnityEngine.Debug.Log("Received a new message from: " + e.Message.From);
var notification = e.Message.Notification;
textDisplay_2.text = notification.Title;
}
}
`
I need to retrieve the data of the push message such as the title and body and display them in two text components, the app closes when placing the line of code textDisplay_2.text = notification.Title; without showing any error in the log.
Unity editor version: 2020.3.20f1
Firebase Unity SDK version: firebase_unity_sdk_8.6.2
Additional SDKs: Admob SDK
Platform Unity editor on Windows
Platform targeting: Android
Scripting Runtime: IL2CPP
API Compability Level: .NET 4.x
Issue
Crashlytics is stuck like this, but the analytics is getting data.
I'm already installed Crashlytics SDK on my project and added configurations like on the document but skip part 4: that symbol thing.
( https://firebase.google.com/docs/crashlytics/get-started?platform=unity ) to my script
so my script becomes like this:
public static FirebaseManager Instance;
private FirebaseApp app;
private void Awake()
{
Instance = this;
}
private void Start()
{
InitFB();
}
private void InitFB()
{
// Initialize Firebase
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
{
var dependencyStatus = task.Result;
if (dependencyStatus == DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
// Crashlytics will use the DefaultInstance, as well;
// this ensures that Crashlytics is initialized.
app = FirebaseApp.DefaultInstance;
FirebaseApp.LogLevel = LogLevel.Debug;
Debug.Log(dependencyStatus);
// Set a flag here for indicating that your project is ready to use Firebase.
}
else
{
Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
}
then implement for tests like the doc ( https://firebase.google.com/docs/crashlytics/test-implementation?platform=unity )
Test script
int updatesBeforeException;
// Start is called before the first frame update
void Start()
{
updatesBeforeException = 0;
}
private void Update()
{
// Call the exception-throwing method here so that it's run
// every frame update
throwExceptionEvery60Updates();
}
// A method that tests your Crashlytics implementation by throwing an
// exception every 60 frame updates. You should see non-fatal errors in the
// Firebase console a few minutes after running your app with this method.
void throwExceptionEvery60Updates()
{
if (updatesBeforeException > 0)
{
updatesBeforeException--;
}
else
{
// Set the counter to 60 updates
updatesBeforeException = 60;
// Throw an exception to test your Crashlytics implementation
throw new System.Exception("test exception please ignore");
}
}
When I run the app on the editor, initialize return available then I test crash it work
am I doing wrong here?
Now I am using Gluon plugin and it is very helpful to start working with JavaFXPorts. I have my application ready and I can use it on computers and phones. I tested on phone with system android. Application is working good but only with my server.
I take care of the different resolutions and I think that it is good for now.
I want to have Turn-based Multiplayer Application but I have still big problem with using Google Play Service. Tutorial which show how to use this services for turn-based multiplayer application is written in pure android and use Activity. My question is maybe very simple but If I have my application view from "fxml" how to use it as an tutorial Activity?
I want to do auto-matching for my application and next I want override method takeTurn() to suit it to my application.
For example, how can I change thing like that (code below) to application in JavaFX?
I must use google services from my JavaFX(src/main/java folder) class in addition AndroidPlatformProvider.java and all methods must be in src/android/java folder. I know that I must use PlatformService and PlatformProvider. I did it as in the examples: HelloPlatform and SMSTracker .
I use methods from my interface PlatformProvider but application still crashes. :(
I only use Provider from my code of JavaFX and I don't have android Activity. I don't know how to use these method without Activity or View:
- public void onActivityResult(int request, int response, Intent data)
- public void playTurn(View view)
Can I call from google service methods to methods from my controller for view (fxml).
I don't know how these methods should working with JavaFX.
public class TbmpGameActivity extends Activity {
...
#Override
public void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
...
if (request == RC_SELECT_PLAYERS) {
if (response != Activity.RESULT_OK) {
// user canceled
return;
}
// Get the invitee list.
final ArrayList<String> invitees =
data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);
// Get auto-match criteria.
Bundle autoMatchCriteria = null;
int minAutoMatchPlayers = data.getIntExtra(
Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0);
int maxAutoMatchPlayers = data.getIntExtra(
Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0);
if (minAutoMatchPlayers > 0) {
autoMatchCriteria = RoomConfig.createAutoMatchCriteria(
minAutoMatchPlayers, maxAutoMatchPlayers, 0);
} else {
autoMatchCriteria = null;
}
TurnBasedMatchConfig tbmc = TurnBasedMatchConfig.builder()
.addInvitedPlayers(invitees)
.setAutoMatchCriteria(autoMatchCriteria)
.build();
// Create and start the match.
Games.TurnBasedMultiplayer
.createMatch(mGoogleApiClient, tbmc)
.setResultCallback(new MatchInitiatedCallback());
}
}
}
or something like that:
// Call this method when a player has completed his turn and wants to
// go onto the next player, which may be himself.
public void playTurn(View view) {
// Get the next participant in the game-defined way, possibly round-robin.
String nextParticipantId = getNextParticipantId();
// Get the updated state. In this example, we simply retrieve a
// text string from the view. In your game, there may be more
// complicated state.
mTurnData = mDataView.getText().toString();
// At this point, you might want to show a waiting dialog so that
// the current player does not try to submit turn actions twice.
showSpinner();
// Invoke the next turn. We are converting our data to a byte array.
Games.TurnBasedMultiplayer
.takeTurn(mGoogleApiClient, mMatch.getMatchId(),
mTurnData.getBytes(Charset.forName("UTF-16")),
nextParticipantId)
.setResultCallback(this);
}
Latest version of the jfxmobile plugin (1.0.3) includes recent changes in Dalvik SDK that contains the port of JavaFX 8 to android.
In FXActivity class, it has been added a very convenient method to listen to results of intents: setOnActivityResultHandler().
This means you shouldn't add new activities to your app, and only use FXActivity. You should add an Intent to it, and set a proper result handler to the FXActivity.
Have a look at this recent post at Gluon's site. It explains how to access native services, based on the case of taking a picture with the device's camera, and waiting to get the result of it to resume the app.
Basically, this is what it is required in this case:
public void takePicture() {
// create intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
...
// Add result handler
FXActivity.getInstance().setOnActivityResultHandler((requestCode, resultCode, data) -> {
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {
...
}
});
// launch activity
FXActivity.getInstance().startActivityForResult(intent, TAKE_PICTURE);
}
Try this approach with your app.
I'm currently working on ListViews in Fragments. The Listviews are loaded by Cursorloader, but without ContentManager. So the code looks like this and it works:
#Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
Log.d("SoapERP", "onCreateLoader");
CursorLoader loader = new CursorLoader(getActivity()) {
final DBHelper dbhelper1= new DBHelper(getActivity());
#Override
public Cursor loadInBackground() {
Cursor c = null;
dbhelper1.open();
c = dbhelper1.fetchAllMatnameswithID();
// dbhelper1.close();
return c;
}
};
return loader;
My problem is that I get an LogCat-Error-Message that the database wasn't closed. But if I use dbhelper.close(); I get the Error "Database is already closed" wich is also understandable because it is just before the return statement. After the return statement code is not reachable and if I declare DBHelper dbhelper1 final the program crashes without any information in logcat. So what is my fail???
Finally I found here the right statement as of Dianne Hackborn from android framework development: "A content provider is created when its hosting process is created, and remains around for as long as the process does, so there is no need to close the database -- it will get closed as part of the kernel cleaning up the process's resources when the process is killed. Dianne Hackborn Android framework engineer hack...#android.com " - so let's use Content Provider.
I have simple serial port program that is supposed to read the serial port and echo back the characters typed. I can get this to work fine by polling the serial recieved with a timer, but I'd like to use the dataReceived event instead. For some reason the event will occur once but never again.
SerialPort bsp;
public Form1()
{
InitializeComponent();
bsp = new SerialPort("COM2", 2400, Parity.None, 8, StopBits.One);
bsp.DataReceived +=new SerialDataReceivedEventHandler(whasup);
System.Threading.Thread.Sleep(1000);
bsp.Open();
}
void whasup(object sender, SerialDataReceivedEventArgs e)
{
char[] text = new char[100];
int temp = bsp.BytesToRead;
string j = temp.ToString();
bsp.Read(text, 0, temp);
bsp.Write(text, 0, temp);
}
I've tried porting this to a PC and it works great, but on this Windows CE device it really doesn't want to cooperate. I know the serial object is still open because i've had a timer running spitting text out of the Win CE device even after it stop echoing back its receive data. I also had the timer output bsp.BytesToRead, and I could see that value climb as I typed more keys in on my PC that talked serially to the Windows CE device. Am I missing something?
We suffered similar problems with Read() but managed it with ReadExisting() instead, to always read the whole buffer. It may be this fact that allows the next event to be raised.
The Sleep(500) was included because the event is raised as soon as the first byte is written to the buffer. Through some trial/error and in the knowledge that the messages we were reading never exceeded a particular length, we knew they'd be fully written within (and in fact long before) 500ms of the event.
A bit hit/miss and I'd be more than happy to see a 'correct' solution from a serial expert!
The code:
private SerialPort port;
private object readLock = new object();
private SerialManager()
{
port = new SerialPort(SerialPort, BaudRate, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.None;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// Lock to subsequent DataReceived events
lock (readLock)
{
Thread.Sleep(500);
string data = port.ReadExisting();
}
}