react-native passing ArrayBuffer or Uint16Array to native ReadableArray on Android - android

I'm receiving a PCM buffer from websocket onmessage method as result
console.log('cleblanc length of TTS data ' + result.byteLength);
const buff = new Uint16Array(result);
console.log('cleblanc TTS data ' + buff);
RNTtsPlayer.playTts(buff);
and my native method
#ReactMethod
public void playTts(ReadableArray readableArray)
It's causing Malformed calls from JS: field sizes are different
I'd like to pass the data as a ReadableArray, but when I try using ReadableMap and passing result directly it results in the Java layer receiving an empty map. Should I try converting it to a String or is there a way to make this work.

So I wound up converting the ReadableArray to a base64 string like this;
new Buffer(result).toString('base64')
And then simply decoding it in the Java like this;
samples[producerIdx] = Base64.decode(data, Base64.DEFAULT);
producerIdx++;
Where samples is a new byte[32][];

Related

Dart: Error When Subscribing to a Non-Broadcast Mapped Stream

I have a dummy Stream<int> called intialStream and I am mapping it into another stream, called mappedStream. which is supposed to be a new stream as I quote from the documentation of the map method:
Creates a new stream that converts each element of this stream to a
new value using the convert function, and emits the result.
void main() {
Stream<int> initialStream = Stream<int>.value(0);//using broadcast stream instead, makes the code work, as if dart considers the mapped stream to be the same stream as this one when I am using non-broadcast streams !
initialStream.listen(print);
var mappedStream = initialStream.map((nb) => nb + 1);
print(initialStream == mappedStream); // prints false !
mappedStream.listen(print);//error here
}
The problem is that when I try to listen to the mapped stream, I get an error:
Bad state: Stream has already been listened to.
Isn't this supposed to be a new stream and thus I can listen to it separately?
Yes, you do create a new stream when you use map() method, but the new stream also listens on the original stream. So, you cannot listen on the new stream that is created using the methods (map(), where(), expand()...) after adding a subscription to the original stream which is single-subscription.
It's not explicitly stated in docs, but check out the following lines that you might get a general idea:
Methods that modify a stream
The following methods on Stream return a new stream based on the
original stream. Each one waits until someone listens on the new
stream before listening on the original:
Stream<R> cast<R>();
Stream<S> expand<S>(Iterable<S> Function(T element) convert);
Stream<S> map<S>(S Function(T event) convert);
Stream<T> skip(int count);
Stream<T> skipWhile(bool Function(T element) test);
Stream<T> take(int count);
Stream<T> takeWhile(bool Function(T element) test);
Stream<T> where(bool Function(T event) test);
Here, you can say that the new stream will listen on the original one once a subscription is added. Therefore, it will throw error if the original stream is single-subscription and it already has a listener.

Cannot VIew the Data Sent By a TCP Packet Sending Program(Packet Server)

I'm trying to develop a small app which receives some data via sockets and based on the data it receives,it prints a toast message for the user.I' getting the data,but the data apparently cannot be read properly.Here is the relavent portion for the same.
int red = -1;
byte[] buffer = new byte[1024]; // a read buffer of 5KiB
byte[] redData;
while ((red = cs.getInputStream().read(buffer)) > -1) {
String redDataTextappend;
redData = new byte[red];
redDataTextappend = new String(redData);
Log.w("Data got",redDataTextappend);
if (redDataTextappend == "hi")
{
//Display Toast message using runonUIThread(new Runnable);
}
else
{//Display Message Using runonUITHread(new Runnable);
}
This code runs on a separate thread as android does not allow networking operations on a separate thread.
The 4 Diamonds is the data displayed by the android studio and cs is the name of the socket which accepts connections.
Thanks.
You are simply printing the String that encodes to zero bytes since you never copy the data that is read in.
It would make more sense to convert the byte array to a hex string if the array contains arbitrary data: see the answers to this question for options for that.
If the array contains the encoding of a String in some charset, for example UTF-8, then do the following:
byte[] redData = Arrays.copyOf(buffer, red);
String redDataTextappend = new String(redData, Charset.forName("UTF-8"));
Log.w("Data got",redDataTextappend);

How to send ArrayList<ParcelableCustomObject> from Android Wear using the MessageAPI?

I have an ArrayList of parcelable custom items:
ArrayList<AudioLog> audioLogs = getAudioLogs();
I want to send this from the watch to the phone using the MessageAPI:
Wearable.MessageApi.sendMessage(googleClient, node.getId(), path, audioLogs).await();
BUT, I need to convert the entire ArrayList and its contents to a byte[], as the sendMessage method takes - (GoogleClient client, int id, String path, byte[] message).
To convert each of my parcelable AudioLog objects, I have a custom Util class that marshals and unmarshals each of them to a byte[]. I just need a similar class that can convert the whole ArrayList and its contents to a byte[] in the one go, if that's possible, thanks.
You should create a DataMap object, which can be converted into a byte array.
DataMap audioLogMap = new DataMap();
ArrayList<DataMap> audioLogArrayList = new ArrayList<>();
for (AudioLog audioLog: audioLogs) {
DataMap audioLogMap = new DataMap();
//TODO: copy something from audioLog to audioLogMap
audioLogArrayList.add(audioLogMap);
}
audioLogMap.putDataMapArrayList("key", audioLogArrayList);
byte[] audioLogByteArray = audioLogMap.toByteArray();

How to compress Ti.utils.base64encode and decompress using .Net method?

Does anyone know how to compress Ti.Utils.base64encode??
for example i have this code :
uploadFile = Ti.Filesystem.getFile(pathFile, listing[_fileCtr].toString());
uploadFileName = listing[_fileCtr].toString();
encodedFile = Ti.Utils.base64encode(uploadFile.read()).toString();
//Send Image to .NET web service
And this is the method in my web services for decompressing image from titanium (if i can compress my image before):
static byte[] Decompress(byte[] input)
{
using (MemoryStream output = new MemoryStream(input))
{
using (GZipStream zip = new GZipStream(output, CompressionMode.Decompress))
{
List<byte> bytes = new List<byte>();
int b = zip.ReadByte();
while (b != -1)
{
bytes.Add((byte)b);
b = zip.ReadByte();
}
return bytes.ToArray();
}
}
Until now, i can't find some method for compressing my byte array so i can decompress them using my .NET method..
If u guys have any information about my problem, please tell me..
Many thanks.. :)
In .Net you can use System.Convert.FromBase64String to converts the specified string, which encodes binary data as base-64 digits, to an equivalent 8-bit unsigned integer array.
System.Convert.FromBase64String(encodedString);

Android String Parsing

I am writing an android app that recieves data over bluetooth. The bytes comming in can be of any size example: 00023>024935928598235>9284>
As you can see each set is seperated by ">". The data comes in extremely fast. I would like some ideas for an implementation. See my problem is that I need to read the data into a byte array that can and then convert it to a string and split them according to the delimeter of ">".
so in the above example:
00023
024935928598235
9284
If i set byte[] data = new byte[8] then when reading the incomming data it might get 00023>02 which is not what i want. I'm not sure how to implement something like this. Any ideas?
Here's one approach. You'll have to implement the readDataFromBluetooth() and somehow set dataAvailable, but this should get you on the right track.
byte[] data = new byte[1024];
List<String> chunks = new LinkedList<String>();
StringBuilder chunk = new StringBuilder();
while (dataAvailable) {
data = readDataFromBluetooth();
for (byte b : data) {
if (b == '<') {
chunks.add(chunk.toString());
chunk.setLength(0);
} else {
chunk.append(b);
}
}
}
if (chunk.length() > 0)
chunks.add(chunk.toString());
I would recommend using a buffered stream, but maybe a bit bigger that 8 bytes, as you suggest, and the read one and one character from the beginning of the stream, accumulating the string. When you encounter a ">", send the value you have accumulated off to a queue for a background thread processing. Use standard producer/consumer implementation techniques (e.g. the Monitor pattern) to communicate via the queue.

Categories

Resources