printf equivalent for Android dev? - android

I'm just getting my toes wet. Using Eclipse, and am not far beyond HelloAndroid. If I have a gallery image loaded onto the screen, and I want to play around with getPixel, where do I send the resulting RGB value output so that I can read it?
Thanks.

Define a:
private static final String TAG = "YOUR TAG";
Use the Log class doing:
Log.d(TAG, "RGB is " + rgb);
You can see logs with logcat.

I believe the proper way would be to write:
Log.d(TAG, String.format("RGB is %d", rgb));

Related

android: How to create an hyperlink to a code line using Log.d

I am learning logging in android code using android studio and emulator
I found that the following command shows a traceback with hyperlink to the code location
Log.d("TAG", "Message with stack trace info", new Throwable());
the image of logcat with hyperlink is
How can i create only the hyperlink part in my log message, without any traceback output
Try this, for example:
import android.util.Log;
public class Logger {
public static void log(String tag, String message) {
String caller = getCallerInfo(new Throwable().getStackTrace());
Log.d(tag, message + caller);
}
private static String getCallerInfo(StackTraceElement[] stacks) {
if (stacks == null || stacks.length < 1) {
return "";
}
StackTraceElement stack = stacks[1];
return String.format(" (%s:%s)", stack.getFileName(), stack.getLineNumber());
}
}
And call it from any where in your code
Logger.log("Manowar", "Today is the good day to die");
As of now the answer by #Cao Mạnh Quang was not giving me the Hyperlink.
The specific String format required for it's generation is this:
return String.format(" %s(%s:%s)", traceE.getClassName(), traceE.getFileName(), traceE.getLineNumber());
which is just the same as:
return stackTraceElement.toString();
so you may as well just do that.
Nothing was working for me...
My guess is that...
This hyperlink is generated by a preconfigured String specification format.
this format follows the className + "(" + fileName + ":" + lineNumber + ")"
If any of those parameters are missing, the hyperlink will not be generated.
There are a couple questions that arise from this:
Is this specification hard coded as a consensus of each LogCat display (IDE side interacts directly with String)
OR
Is this specification hardcoded into the Java code itself? (Java side interprets String generates hyperlink signal + IDE side interprets hyperlink signal and generates it)
The difference between which of these options is the one, would imply whether hyperlink generation is possible simply by changing the required configuration for the Logcat to generate the link either at IDE config level... OR at Java level.
Maybe it is not possible, and this configuration format cannot be changed....
Btw I am sure there must be some super hacky way to achieve this, maybe a way not so intuitive... or maybe it just requires some digging on the IDE config options...

System.out.print with // prints the code Blue. What is the meaning of this?

System.out.println(TAG + " //METHOD_STARTED// - //start_firebase_and_get_userID//");
Why if I write these in my app, it comes in blue in the console after the //?
It appears to be mistaking it for a hyperlink.
//METHOD_STARTED// is a valid protocol-relative URL (domain names don't have to have dots if they're on your local network), and it seems that Android Studio/IntelliJ's link detection is falling for it. Of course, it's not valid in this case, because there's no protocol in the log output for it to be relative to, so really this is a bug.

Android Logcat very strange behavior when getting empty string

So I came across something strange that made me loose some time. I have been trying to print the content of an ArrayList containing string elements, sometimes, an element might contain an empty string, which is fine and absolutely my intention.
So I have something like this:
List<String> l = new ArrayList<String>();
//adding strings in l, sometimes it's an empty string
for (int i=0; i < l.size(); i++) {
Log.w("element in l : ", l.get(i));
}
So here, when the loop is gonna hit the empty string, logcat is simply NOT going to print it out BUT (and here is the root of my confusion), if you have a message following the one that failed to display, suddenly the failed message is going to show up as if it contained the new logcat message. For example if you try logging an empty string like this
Log.w(TAG, <empty string here>);
Logcat is going to output nothing at first, then, when it has a NEW message to display this is what it prints out (in this case the new message is some warning about AudioTrack):
08-21 17:06:02.265 13047-13047/company.myapp W/TAG﹕ [ 08-21 17:06:05.411 766: 937 W/AudioTrack ]
AUDIO_OUTPUT_FLAG_FAST denied by client
I'm interested in knowing how this happens, maybe it can help someone else not getting super confused like I did. I suppose trying to log an empty string triggers some kind of buffer that sits there until it gets something to print, is this a bug?
That is an interesting question. I just tried this in LogRabbit and am able to see the same result.
I took a quick browse through the android source and see that Log.W(...) ends up in native code and getting handled in logd_write.c
This basically writes the data to /dev/log/main (or one of the other logs)
You can get those logs like this:
adb pull /dev/log/events .
adb pull /dev/log/main .
adb pull /dev/log/radio .
adb pull /dev/log/system .
You will need to press cntl-C otherwise the copy will happen forever.
Looking in the raw log in /dev/log/main I see the message does get logged:
<8b>F×U^_<8c>^Y^U^Emfl_MessageList^#Before Empty^#^R^#^#^#!z^#^#!z^#^#
<8b>F×U^_<8c>^Y^U^Emfl_MessageList^#^#^]^#^#^#!z^#^#!z^#^#
<8b>F×U^_ <8c>^Y^U^Emfl_MessageList^#After Empty^#7^#^#^#^#^E^#^#^Z^E^#^#
That gets decoded by struct found in logger.h So I think this is a problem in adb. pull the source code from here: (looks like quite a few of undocumented commands there)
This is the primary function
static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
char* log_tags = getenv("ANDROID_LOG_TAGS");
std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
if (!strcmp(argv[0], "longcat")) {
cmd += " -v long";
}
--argc;
++argv;
while (argc-- > 0) {
cmd += " " + escape_arg(*argv++);
}
return send_shell_command(transport, serial, cmd);
}
Looking in there I see that all logcat does is basically this:
adb shell
> exec logcat
So I think the root of the problem is in logcat itself. Logcat.cpp calls into log_read.c
Based on my quick read through things what I think is happening is the message is not terminated properly. The empty message does not show up until another message is appended and the first message overruns and shows the second message because it has the appropriate termination.

Android Passing Variables to another activity with # not working as expected

Ok I'm trying to create a link to an activity and it works. However passint it a variable isn't working with # charters:
String hashTagString = tempValues.getDescription().replaceAll("[#]+[A-Za-z0-9-_]+\\b", "$0");
Log.i(Utils.TAG, "hashTagString: " + hashTagString);
The launched activity:
String tag = getIntent().getData().getQueryParameter("tag");
Log.i(Utils.TAG, "tag: " + tag);
Log Cat:
02-24 13:12:04.293: I/PROJECTCARUSO(29591): hashTagString: Everyone loves #hashtags ! Take advantage of them by using them and clicking to search by them.
The activity it launches show this:
02-24 13:13:48.885: I/PROJECTCARUSO(29591): tag:
However if I set it with hard coded values it shows:
02-24 13:14:41.176: I/PROJECTCARUSO(29883): hashTagString: Everyone loves #hashtags ! Take advantage of them by using them and clicking to search by them.
02-24 13:14:41.637: I/PROJECTCARUSO(29883): tag: test
I'd like to pass the whole value, but if i cannot how can I remove all special charaters?
I don't think your regex is being evaluated correctlyTry using the following regex
\\#[A-Za-z0-9\\-_]+
You may need to double escape (\). The \b (word-boundary) at the end of your sequence isn't needed because it will break when it reaches a " anyway and the - in your character class needs escaping otherwise the regex is trying to evaluate a nonsense range instead of treating it as a char
Edit
Now you've clarified your issue the issue with getting a blank tagis this:
String tag = getIntent().getData().getQueryParameter("tag");
It should be
String tag = getIntent().getExtras().getString("tag");
and should be sent as
new Intent(...).putExtra("tag", hashTagString);
Try (\s|\A)#(\w+) that as a Java string is "(\\s|\\A)#(\\w+)".
You can test it in the following site: http://www.regexplanet.com/advanced/java/index.html

EXTRA_AVAILABLE_VOICES always returns eng-GBR only. Why?

I am using the following snippet to log all available (and unavailable) voices currently on phone:
ArrayList<String> availableVoices = intent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
String availStr = "";
for (String lang : availableVoices)
availStr += (lang + ", ");
Log.i(String.valueOf(availableVoices.size()) + " available langs: ", availStr);
ArrayList<String> unavailableVoices = intent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);
String unavailStr = "";
for (String lang : unavailableVoices)
unavailStr += (lang + ", ");
Log.w(String.valueOf(unavailableVoices.size()) + " unavailable langs: ", unavailStr);
The logged result is somehwat bewildering, since I know beyond certainty that I have multiple languages installed and I can even hear the TTS speaking in eng-USA, yet the log shows:
1 available langs: eng-GBR,
30 unavailable langs: ara-XXX, ces-CZE, dan-DNK, deu-DEU, ell-GRC,
eng-AUS, eng-GBR, eng-USA, spa-ESP, spa-MEX, fin-FIN, fra-CAN,
fra-FRA, hun-HUN, ita-ITA, jpn-JPN, kor-KOR, nld-NLD, nor-NOR,
pol-POL, por-BRA, por-PRT, rus-RUS, slk-SVK, swe-SWE, tur-TUR,
zho-HKG, zho-CHN, zho-TWN, tha-THA,
Why is this inconsistent behavior? (note that eng-GBR appears in both the available and unavailable lists...)
It turns out that as far as text-to-speech in Android 2.x goes, it's the wild west out there: Every and any installed 3rd-party TTS engine can modify the output of this EXTRA_AVAILABLE_VOICES function however they desire, regardless whether checked/unchecked or selected/unselected as default.
I just tried uninstalling all TTS engines from my phone, leaving only the hard-coded Pico, and the result match exactly what I expected:
6 available voices: deu-DEU, eng-GBR, eng-USA, spa-ESP, fra-FRA,
ita-ITA,
0 unavailable voices:
I don't mind the output of this function dynamically refer to the currently selected (i.e. default) TTS engine, but the fact is that once a 3rd party TTS engine is installed, this function's output doesn't make any sense, because it ignores any settings.
Also note that the name misleading: It's available languages, not voices!
I am posting this answer with the hope that it will help someone save the time & agony of discovering this the hard way.

Categories

Resources