File access and retrieval within an android library - android

There must be some sort of small technical error that I am performing here that I cannot get a grasp on. The file is in the raw/ directory of the AndroidLibrary, and access to different files are being used just fine in this manner. Perhaps there is a slight error here that I keep glazing over?
Note: The raw resource is in an uncompressed format so that it can be read in with a .jet extension so that there are not any complaints by the internal file system.
Edit (Update): Apparently in order to get the stream open, the openRawResourceFd was not enough. In addition to that I needed to call assetDescriptor.createInputStream(); If I did not, the stream would not behave properly. Odd, as I would expect the openRawResourceFd to do the trick.
AssetFileDescriptor assetDescriptor = resources.openRawResourceFd(com.grubulon.R.raw.testing_patches);
BufferedReader bufferedInputStream = new BufferedReader(new FileReader(assetDescriptor.getFileDescriptor()));
colorSpace = bufferedInputStream.readLine();
while ((currentLine = bufferedInputStream.readLine()) != null)
{
rgbValues = currentLine.split("\\t");
red = Integer.parseInt(rgbValues[0]);
green = Integer.parseInt(rgbValues[1]);
blue = Integer.parseInt(rgbValues[2]);
rgbPatches.add(new RgbColorValue(red, green, blue));
}
bufferedInputStream.close();
assetDescriptor.close();
The file itself is really only an Excel spreadsheet of RGB color values that are being read in with tabs in between them. The tab component does not seem to be the issue, but the first line is a garble of lots and lots of text. Not the color space, or values at all for that matter. I am not sure what is going on here.
File example:
RGB
0 0 0
17 17 17
34 34 34
51 51 51
68 68 68
85 85 85
102 102 102
119 119 119
136 136 136
153 153 153
170 170 170
187 187 187
204 204 204
221 221 221
238 238 238
255 255 255
255 0 0
0 255 0
0 0 255
The following is an example of what is coming across in the Logcat even though there should be very little text coming across from the file.

The following based upon the update above is what has resolved the problem. Notice the line after the assetDescriptor is created with the openRawResourceFd call.
AssetFileDescriptor assetDescriptor = resources.openRawResourceFd(com.grubulon.R.raw.testing_patches);
assetDescriptor.createInputStream();
BufferedReader bufferedInputStream = new BufferedReader(new FileReader(assetDescriptor.getFileDescriptor()));
colorSpace = bufferedInputStream.readLine();
while ((currentLine = bufferedInputStream.readLine()) != null)
{
rgbValues = currentLine.split("\\t");
red = Integer.parseInt(rgbValues[0]);
green = Integer.parseInt(rgbValues[1]);
blue = Integer.parseInt(rgbValues[2]);
rgbPatches.add(new RgbColorValue(red, green, blue));
}
bufferedInputStream.close();
assetDescriptor.close();

Related

How to parse multiline response of 09 04 PID from OBD adapter in Android

I am getting raw data from OBD adapter, It is getting parsed for single line but for multiline response I am not able to parse.
I used below code to parse
String hexaData = getResult(); // getResult is here the raw data("4904014A4D422A490402333637364904033135303049040400000000") after parsing I am getting parsed value(JMB*36761500) which is correct and only working for single line
Log.i("CalID_hexa", hexaData);
final String result = getResult();
String workingData;
if (result.contains(":")) {//CAN(ISO-15765) protocol.
workingData = result.replaceAll(".:", "").substring(9);//9 is xxx49040701, xxx is bytes of information to follow.
Matcher m = Pattern.compile("[^a-z0-9 ]", Pattern.CASE_INSENSITIVE).matcher(convertHexToString(workingData));
if(m.find()) workingData = result.replaceAll("0:49", "").replaceAll(".:", "");
} else {//ISO9141-2, KWP2000 Fast and KWP2000 5Kbps (ISO15031) protocols.
workingData = result.replaceAll("49040.", "");
}
calId = convertHexToString(workingData).replaceAll("[\u0000-\u001f]", "");
L.stringStringHashMap.put("CAL_ID",calId);
public String convertHexToString(String hex) {
StringBuilder sb = new StringBuilder();
//49204c6f7665204a617661 split into two characters 49, 20, 4c...
for (int i = 0; i < hex.length() - 1; i += 2) {
//grab the hex in pairs
String output = hex.substring(i, (i + 2));
//convert hex to decimal
int decimal = Integer.parseInt(output, 16);
//convert the decimal to character
sb.append((char) decimal);
}
return sb.toString();
}
How to parse multiline response like below response on PID 09 04 from OBD Adapter:
18 DA F1 11 10 13 49 04 01 33 37 38
18 DA F1 1D 10 13 49 04 01 33 37 38
18 DA F1 11 21 30 35 2D 52 59 45 2D
18 DA F1 11 22 41 37 34 30 00 00 55
18 DA F1 1D 21 30 36 2D 52 59 45 2D
18 DA F1 1D 22 41 37 37 30 00 00 55
How can I parse the above?
If you want to parse multiple line responses as single line responses then you can first form the array from the multiple line response separating the lines by character \n. After forming the array of responses, you can join the strings in one single line.
You have two issues here. The first is that you sent your request using a broadcast address, that's why two ECUs (namely, 18 DA F1 11 and 18 DA F1 1D) answered to your request. You either have to sort these out or ask only one ECU directly.
The second is you should learn about ISO 15765-2 (also named ISO-TP), which is a transport protocol, much like TCP (or rather IP) is for Ethernet. https://en.wikipedia.org/wiki/ISO_15765-2 contains a rough outline.
A general notice: If you're serious about implementing OBD2 communication, write a layered architecture, in which the communication layer (BLE, TTY, TCP, etc.) sits below the vehicle protocol which ISO-TP sits on top of. On the actual application layer you can then decode the individual PIDs and their measurements.

how to resize the screenshot of Android using adbkit?

I use client.screencap method from adbkit to get the PNG stream and save the image like this:
let stream = await client.screencap(deviceId);
stream.pipe(fs.createWriteStream('output.png'));
Rather, I want to resize it first because the output image is so big ( around 2 - 3 Mb ). So I try to get the buffer of the stream and resize it by reducing width, height (use Jimp library) and save the image.
let stream = await client.screencap(deviceId);
let chunks = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
let buffer = Buffer.concat(chunks);
console.log(buffer);
// resize and save (Use Jimp library to read the buffer and resize)
...
in console.log(buffer), I got
<Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 00 00 01 73 ae ce 1c e9 00 00 00 04 ... 159002 more bytes>
But sometime I got empty buffer like this:
<Buffer >
I don't know why the buffer is empty. Because of client.screencap method is not stable?
Or they are an any better solution to do a thing like this?

Hex transparency in colors [duplicate]

This question already has answers here:
Understanding colors on Android (six characters)
(10 answers)
Closed 6 years ago.
I'm working on implementing a widget transparency option for my app widget although I'm having some trouble getting the hex color values right. Being completely new to hex color transparency I searched around a bit although I couldn't find a specific answer to my question.
I want to set transparency by hex color so let's say my hex color id "#33b5e5" and I want it to be 50% transparent. Then I'll use "#8033b5e5" because 80 is 50%.
I found a useful chart here: http://www.dtp-aus.com/hexadeci.htm . With this data I managed to come up with this:
0% = #00
10% = #16
20% = #32
30% = #48
40% = #64
50% = #80
60% = #96
70% = #112
80% = #128
90% = #144
Now the issues start appearing when I get higher than 100 in hex. Hex color codes can only be 8 symbols long right? For example #11233b5e5 (80%) crashes.
What can I do to enable me to use the higher numbers aswell?
Here's a correct table of percentages to hex values for opacity. E.g. for 50% white you'd use #80FFFFFF. To think in terms of transparency instead, flip the order of the percentages (more opaque = less transparent).
%
Hex
100%
FF
95%
F2
90%
E6
85%
D9
80%
CC
75%
BF
70%
B3
65%
A6
60%
99
55%
8C
50%
80
45%
73
40%
66
35%
59
30%
4D
25%
40
20%
33
15%
26
10%
1A
5%
0D
0%
00
(source question)
Short answer: full table of percentages
You can see the full table of percentages to hex values and run the code in this playground in https://play.golang.org/p/l1JaPYFzDkI .
Ok the table tells the results not how to find the results. The next parts explain how you can calculate yourself.
Short explanation in pseudocode
Percentage to hex values
decimal = percentage * 255 / 100 . ex : decimal = 50*255/100 = 127.5
convert decimal to hexadecimal value . ex: 127.5 in decimal = 7*16ˆ1 + 15 = 7F in hexadecimal
Hex values to percentage
convert the hexaxdecimal value to decimal. ex: D6 = 13*16ˆ1 + 6 = 214
percentage = (value in decimal ) * 100 / 255. ex : 214 *100/255 = 84%
More infos for the conversion decimal <=> hexadecimal
Long answer: how to calculate in your head
The problem can be solved generically by a cross multiplication.
We have a percentage (ranging from 0 to 100 ) and another number (ranging from 0 to 255) then converted to hexadecimal.
100 <==> 255 (FF in hexadecimal)
0 <==> 0 (00 in hexadecimal)
For 1%
1 * 255 / 100 = 2,5
2,5 in hexa is 2 if you round it down.
For 2%
2 * 255 / 100 = 5
5 in hexa is 5 .
The table in the best answer gives the percentage by step of 5%.
How to calculate the numbers between in your head ? Due to the 2.5 increment, add 2 to the first and 3 to the next
95% — F2 // start
96% — F4 // add 2 to F2
97% — F7 // add 3 . Or F2 + 5 = F7
98% — F9 // add 2
99% — FC // add 3. 9 + 3 = 12 in hexa : C
100% — FF // add 2
I prefer to teach how to find the solution rather than showing an answer table you don't know where the results come from.
Give a man a fish and you feed him for a day; teach a man to fish and
you feed him for a lifetime
Color hexadecimal notation is like following: #AARRGGBB
A : alpha
R : red
G : green
B : blue
You should first look at how hexadecimal works. You can write at most FF.
I built this small helper method for an android app, may come of use:
/**
* #param originalColor color, without alpha
* #param alpha from 0.0 to 1.0
* #return
*/
public static String addAlpha(String originalColor, double alpha) {
long alphaFixed = Math.round(alpha * 255);
String alphaHex = Long.toHexString(alphaFixed);
if (alphaHex.length() == 1) {
alphaHex = "0" + alphaHex;
}
originalColor = originalColor.replace("#", "#" + alphaHex);
return originalColor;
}
That chart is not showing percents. "#90" is not "90%".
That chart shows the hexadecimal to decimal conversion. The hex number 90 (typically represented as 0x90) is equivalent to the decimal number 144.
Hexadecimal numbers are base-16, so each digit is a value between 0 and F. The maximum value for a two byte hex value (such as the transparency of a color) is 0xFF, or 255 in decimal. Thus 100% is 0xFF.
try this on google search (or click here)
255 * .2 to hex
it will generate 0x33 as a result.
However, google does not round off values so you can only use 1-digit multipliers. if you want to use say .85, you have to get the rounded-off value of 255 * .85 first, then type (rounded-value here) to hex in google search.
I realize this is an old question, but I came across it when doing something similar.
Using SASS, you have a very elegant way to convert RGBA to hex ARGB: ie-hex-str. I've used it here in a mixin.
#mixin ie8-rgba ($r, $g, $b, $a){
$rgba: rgba($r, $g, $b, $a);
$ie8-rgba: ie-hex-str($rgba);
.lt-ie9 &{
background-color: transparent;
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#{$ie8-rgba}', endColorstr='#{$ie8-rgba}');
}
}
.transparent{
#include ie8-rgba(88,153,131,.8);
background-color: rgba(88,153,131,.8);
}
outputs:
.transparent {
background-color: rgba(88, 153, 131, 0.8);
}
.lt-ie9 .transparent {
background-color: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#CC589983', endColorstr='#CC589983');
zoom: 1;
}
I always keep coming here to check for int/hex alpha value. So, I end up creating a simple method in my java utils class. This method will convert the percentage of transparency to hex value and append to the color code string value.
public static String setColorAlpha(int percentage, String colorCode){
double decValue = ((double)percentage / 100) * 255;
String rawHexColor = colorCode.replace("#","");
StringBuilder str = new StringBuilder(rawHexColor);
if(Integer.toHexString((int)decValue).length() == 1)
str.insert(0, "#0" + Integer.toHexString((int)decValue));
else
str.insert(0, "#" + Integer.toHexString((int)decValue));
return str.toString();
}
So, Utils.setColorAlpha(30, "#000000") will give you #4c000000

Synchronize Dataset - Multiple users, multiple timestamps

I'm trying to understand what is the best way to go about doing this:
Basically I will have a bunch of Android/iOS users who will be logging sensor data on their phone, except each user will have its own timestamp depending on when people start the app etc. So say I have two users:
User 1: (5,45), (6,34), (8,32)
User 2: (5,35), (7,32), (9,32)
The format is (time t, and some arbitrary value).
What would be the best way to synchronize the two datasets? Do I have to write an algorithm which is then going to go back and say on User 2, insert the following entry (6,35). So eventually the new data looks like:
User 1: (5,45), (6,34), (7,34), (8,32), (9,32)
User 2: (5,35), (6,35), (7,32), (8,32), (9,32)
This could be very data intensive though, because I am expecting to have about 300 users, and each will have about 36,000 data entries. Any advice would be appreciated - also something I could do on the app side that could help that would be appreciated.
I believe I am going to have to do something like this when I have all my data - but since this is an actively developing project I thought I'd get some advice first.
You could create a DataFrame from each user's data. Then store them all in a Panel. Pandas will line them all up based on the timestamp and you can use the forward fill method, ffill, to propagate the values:
In [62]: df1 = DataFrame([45,34,32], index=[5,6,8], columns=['value'])
In [63]: df2 = DataFrame([35,32,32], index=[5,7,9], columns=['value'])
In [64]: p = Panel({'user1': df1, 'user2': df2})
In [75]: p.ffill().to_frame().unstack()
Out[75]:
user1 user2
minor value value
major
5 45 35
6 34 35
7 34 32
8 32 32
9 32 32
Or, you could do the same thing using just Series and DataFrames. I guess it depends on what you want to do with it:
In [78]: s1 = Series([45,34,32], index=[5,6,8])
In [79]: s2 = Series([35,32,32], index=[5,7,9])
In [80]: df = DataFrame([s1,s2])
In [81]: df
Out[81]:
5 6 7 8 9
0 45 34 NaN 32 NaN
1 35 NaN 32 NaN 32
In [82]: df = DataFrame([s1,s2]).T
In [83]: df
Out[83]:
0 1
5 45 35
6 34 NaN
7 NaN 32
8 32 NaN
9 NaN 32
In [84]: df.ffill()
Out[84]:
0 1
5 45 35
6 34 35
7 34 32
8 32 32
9 32 32

Send Android h264 capture over a rtp stream

I'm writing a rtp video streamer for android that reads h264 coded data from an Android local socket and packetize it. The thing is that I did it but I keep getting black frames in the client side (Voip).
The communication goes like this: Android -> Asterisk -> Jitsi (Osx) (and reverse)
There are a few things that I haven't understood yet:
1) Android's mediarecorder gives me a raw h264 stream, How can I know when a NAL starts / ends based on that stream? It doesn't have any 0x000001 pattern but it does have a 0x0000 (which I'm assuming is a separator)
EDIT:
Adding more information. These are 2 (first, second) different reads of the input buffer (in order). If I got it right the first 4 bytes should be used to get the NALU length and the 5th one (index 4) is the NALU header.
I'll copy here the byte's values for future usage:
1) 0 0 12 114 101 -72 4 25 -15 -1 -121 -53 .....
length = (114&0xFF) + (12&0xFF)*256 + (0&0xFF)
length -> 3186
forbidden = 101 & 0x80
forbidden -> 0
nri = 101 & 0x60
nri -> 96
nal_unit_type = 101 & 0x1F
nal_unit_type -> 5
2) 0 0 1 -93 97 -32 32 103 -14 93 -1 ....
length = (-93&0xFF) + (1&0xFF)*256 + (0&0xFF)
length -> 419
forbidden = 97 & 0x80
forbidden -> 0
nri = 97 & 0x60
nri -> 96
nal_unit_type = 97 & 0x1F
nal_unit_type -> 1
is this correct?
2) How can I get the NALu timestamp and its length from that stream?
3) For some reason the packets are being marked (Even when I unset the marker). (In case you check the pcap file) [FIXED: I wasn't using the same SSCR for every packet]
Here's a pcap capture of the stream coming from asterisk (wich comes from Android). The Android device is an Asus Transform Prime with Android ICS.
I'm sending the packetization-mode (1) and profile-level-id (42801e) in the sdp, I've also tried sending the sprops (sps: Z0KAHpWgUHxA, psp: aM48gA==) parameter but nothing changed.
Cheers.
There is no "android h264 stream format". Packetization should follow RFC6184 if RTP is used as the transport protocol. The start code is not present of the RTP payload format. What is contained in an RTP packet, depends entirely on the packetization mode which specifies if NAL units may be aggregated, fragmented, etc. Read the RFC section on packetization modes for more info. Packetization mode is usually communicated via SDP.
Timestamp is part of RTP header. Length of a NAL unit again depends on packetization mode.
What do you mean by marked? Do you mean that the RTP marker bit is set? If so, this again must follow the rules laid out in the RFC.

Categories

Resources