Force Android TTS to parse time as text? - java

I'm building an app that speaks a custom message that includes the current time. I've noticed that some voices seem to parse the time correctly- that is, when I pass in a string like "The time is now 7:07" it actually speaks it as "seven-oh-seven."
However, other voices insist on saying "the time is now seven colon zero seven." It would be simple enough to write a function to parse it myself, but I'm trying to find something built-in so I won't have to worry about localization. Is there something I can do within TTS (attributed-string-related, maybe?) or even a Java library that will provide me with a localized "text" string of a time? I've dug through the TTS documentation and didn't find anything, and all the Java time-formatting patterns I've seen are numbers-only, no words.

Figured it out- the TtsSpan is what's needed. Took me a while to get the format right; there are basically zero examples out there on how to do this. Here are the basics for what worked for me, if anyone else comes across this with the same need (in kotlin):
var h:Int = Calendar.getInstance().get(Calendar.HOUR)
if (DateFormat.is24HourFormat(ApplicationContext))
h = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
val m:Int = Calendar.getInstance().get(Calendar.MINUTE)
val whenStr = getFormattedTime() // internal function I'm using to format it visually
wholeString = message.replace("|TIME|",whenStr) // my time doesn't always appear at the same place in the custom message
val spannedMsg:Spannable = SpannableString(wholeString)
val span:TtsSpan = TtsSpan.TimeBuilder(h, m).build()
spannedMsg.setSpan(span, wholeString.inexOf(whenStr),wholeString.indexOf(whenStr) + whenStr.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
tts.speak(spannedMsg, TextToSpeech.QUEUE_FLUSH, params, "UTT_ID")
According to the TtsSpan documenation page, there are plenty of other options aside from TimeBuilder, as well, so be sure to check that out if you're looking for different customizations- just be aware that there aren't any code examples.

Related

Protobuf lazy decoding of sub message

I am using proto 3 (java) in my projects . I have some huge protobufs embedded with smaller messages . Is there a way I can acheive partial decoding of only few nested sub messages that I want to look at. The current issue I am having is I need to join this huge proto based record data with another records ,but my join are based on very small sub messages ,so I don't want to decode the entire huge protobuf and be able to only decode the nested message (string id) to join and then only decode the entire protobuf for the joined data.
I tried using the [lazy=true] tagging method , but I don't see any difference in generated code , also I tried benchmarking the deserialization time with and without the lazy key work and it didn't seem to affect at all . Is this feature by default on for all fields? Or is this even possible? I do see there are few classes LazyFields.java and test cases in the protobuf-github so I assume this feature has been implemented.
For those that happen to look at this conversation later and finding it hard to understand, here's what Marc's talking about:
If your object is something like
message MyBigMessage{
string id = 1;
int sourceType = 2 ;
And many other fields here, that would be expensive to parse .......
}
And you get a block of bytes that you have to parse. But you want to only parse messages from a certain source and maybe match a certain id range.
You could first parse those bytes with another message as:
message MyFilterMessage{
string id = 1; //has to be 1 to match
int sourceType = 2 ; //has to be 1 to match
And NOTHING ELSE here.......
}
And then, you could look at sourceType and id. If they match whatever you are filtering for, then, you could go and parse the bytes again, but this time, using MyBigMessage to parse the whole thing.
One other thing to know:
FYI: As of 2017, lazy parsing was disabled in Java (except MessageSet) according to this post:
https://github.com/protocolbuffers/protobuf/issues/3601#issuecomment-341516826
I dont know the current status. Too lazy to try to find out ! :-)

Build code by using Concatenation?

Is there a way i can create code build code by using Concatenation in Android studio/eclipse?
In other words i have 2 sets of strings one for each country i am dealing with ZA and KE. They have 2 different EULA's.
So i would like to pull the string related to the respective country.
String message = mContext.getString(R.string.eula_string_za);
above is an example of the output code. is there someway i can go about "creating" that based on If statements?
String str = "mContext.getString(R.string.eula_string_";
if (something = "ZA") {
str += "za);";
} else {
str += "ke);";
}
so if the country selected is ZA then the output code should be
mContext.getString(R.string.eula_string_za);
and if its KE it should be
mContext.getString(R.string.eula_string_ke);
and then the result will then pull the correct string from strings.xml?
Java is a compiled code, not an executed one,you can't write code this way like in an interpreted language.
The best way to manage different languages in android is to use a string.xml file for each language.
Take a look at this tutorial, it will help you a lot :
Supporting different languages in android
If you want to go this route you could try to use reflection. Have a look at Class.getField(…) if you want to use reflection.
Instead of first building a code string using a if statement you can also use the same if statement to find the correct string:
String str;
if (something.equals("ZA")) {
str = mContext.getString(R.string.eula_string_za);
} else {
str = mContext.getString(R.string.eula_string_ke);
}
Note that your condition something = "ZA" does not do what you think it does: It assigns something the string "ZA" and then evaluates itself to "ZA", so this would not even compile. The correct way would be something == "ZA", but even this does not work in the general case. You need to use String.equals(…). Some even argue you should use it the other way around (i.e. "ZA".equals(something)) to avoid a NullPointerException…
Another possibility would be to first build a Map from county to the corresponding string ID for all the EULAs you have and then asking the Map to return the correct one.
But probably the cleanest solution would be to use Androids built in mechanism, as hkN suggests.

Retrieve first and last name of the current Windows user?

I know you can retrieve the username with something like System.getProperty("user.name") but I am looking for a way to retrieve the first and last name of the current user.
Is there a native Java library that does this? Or do you have to plug into the Windows API? Or maybe you have to pull it from Active Directory? This seems relatively easy with .NET but I can't find a way to do it in Java.
As Brian Roach suggested in the comments, it's pretty straight-forward to do this with JNA, since it has a built-in wrapper for Secur32 which wraps the GetUsernameEx() function (which is ultimately the system call wrapped by the .NET library you linked to above).
Use would be something like this:
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.platform.win32.Secur32;
// ...
char[] name = new char[100]; // or whatever is appropriate
Secur32.INSTANCE.GetUserNameEx(
Secur32.EXTENDED_NAME_FORMAT.NameDisplay,
name,
new IntByReference(name.length)
);
String fullName = new String(name).trim();
Note that this will give you the full name in the same format as you'd get typing net user %USERNAME% /domain at the command prompt.
Or just,
String fullName = Secur32Util.getUserNameEx(Secur32.EXTENDED_NAME_FORMAT.NameDisplay);
But it is the same, as the upper answer

Java Unit conversion

I have a database table which stores the units name in full like liters, kilograms, milliliters, milligrams etc.. I need a library to recogonize these units and convert it to the unit I wish to. How do i do this ?
Code Logic:
I will read the unit "liters" from database and i wish to convert it to milli-liters so her the input is "20 liters" and output should be "20000 milli-liters"
I downloaded JScience library but i am not sure how to do this. please tel me how to use that or suggest any alternative. It would be better if you explain me with a code sample. Thanks!!
I'm inclined to say use Frink, but it does WAY more than you need here, although it does solve the problem
20 litres -> milliliters
//gives 20000
And it is just a cool little language. In java you'd have to run it like any other scripting library. The website has loads of info
I'm not aware that JScience provides a facility for parsing strings like "20 liters" (that spelling makes me cringe...), so you'll probably have to handle that yourself, by tokenizing the string into quantities and units.
Once you have that, you can use JScience to convert between units easily enough, although obviously converting from litres to milliltres is trivial. But in principle, it's something like:
Measure<Integer, Volume> input = Measure.valueOf(20, NonSI.LITRE);
Measure<Integer, Volume> output = input.to(SI.MILLI(NonSI.LITRE));
System.out.println(output);

Can I Define Exceptions to Eclipse cleanup rules?

Most often the cleanup rules (Preferences > Java > Code Style > Clean Up) in Eclipse work perfectly and create nice-looking code.
But sometimes, especially with comments and concatenated string snippets (like inline SQL queries), the cleanup just messes things up, and destroys my formatting.
Is there a way to say to Eclipse "Don't touch this block of text! I have formatted it just the way I like, and you would make it just less readable"?
I assume you do not really mean ‘Clean Up’, but the ‘Format source code’ option hidden within. It is configured in Preferences > Java > Code Style > Formatter. And, indeed, there is an option called ‘On/Off Tags’. Sadly, it’s off by default. You would now write it like so:
// #formatter:off
StringBuilder sql = new StringBuilder()
.append("SELECT whatever \n")
.append("FROM some_table");
// #formatter:on
It may well be possible that the accepted answer was correct at the time of writing, however, this was introduced in Eclipse 3.5, if I’m not mistaken.
I have experienced the same problem, and while I don't have a solution, I can tell you how I work around the problem.
Because of how formatting works, I deliberately avoid lines of code that are excessively long. In general, when I keep lines short, it makes better decisions as to how to format the code. This can even work with SQL statements, for example:
public static final String SELECT_SOMETHING = "SELECT"
+ "OBJECTID, THIS, THAT, THEOTHER, THING"
+ " FROM DBNAME.DBSCHEMA.TABLE_T"
+ " WHERE ID = ?";
This statement formats reasonably, because where possible items were split apart and concatenated together. When I don't do this, I get unpredictable results:
public static final String SELECT_SOMETHING = "SELECT OBJECTID, SOMETHING FROM DBNAME.DBSCHEMA.TABLE_T WHERE ID = ?";
For comments, I place them all on a single line when possible, and allow it to word wrap when it does the formatting.
Also, it is possible to change the style using the code formatter to make things work better for your coding style. You may want everyone on the team to use the same format, just to avoid conflicts. Because it is easier to compare changes with other developers, or prior versions using your source control tool, even if it makes parts of your code less readable, using the formatter has still been to my advantage.
Still, I understand your frustration when the formatter makes bad decisions!
Feeling iffy about replying to my own question, but there's a workaround I currently do (note: I have these cleanup rules as a save-action):
Save (with Ctrl/Cmd-S, don't know if it matters how you save) the code, and let Eclipse mess up your formatting. Then just press Ctrl/Cmd-Z to undo, and immediately re-save. The format reverts back to its original format and seems to be saved as intended.
For SQL statements in code, you can put a single-line comment character at the end of each line. Then the formatter can't reformat it. It's uglier than not having to do it, but it's prettier than if Eclipse formats it.
StringBuffer sql = new StringBuffer() //
.append("SELECT whatever \n") //
.append("FROM some_table");
No. (To the best of my knowledge, and I have had the same problem and have looked many times hard and long...)
(for Javadoc comments only)
If I have a block of text that formatted just the way I like, I enclose them by the <pre></pre> tags.
if you don't want a field to become final (i.i: because you want to change it while debugging), you just assign it to itself on the constructor. This would get an eclipse warning, but your field will stay non-final.

Categories

Resources