Android Phrase o-matic - android

I'd like to port this little program to Android, thing is that im level basic -1 at android, what the program does is that it randomly creates a phrase taken from strings in an array. I know how to make a button to show me an xml from the layout resources but thatjust works with textviews that do not change, Could you please tell me which steps to follow in order to display a randomly generated string taken from the array of strings?
heres the code(head first java):
public class PhraseOMatic
{
public static void main (String[] args)
{
String[] wordListOne = {"24/7", "multi-tier", "30,OOO foot", "B-to-B" , "win-win" , "frontend", "web- based" , "pervasive", "smart", "sixsigma", "critical-path", "dynamic"};
String[] wordListTwo = {"empowered", "sticky", "value-added", "oriented", "centric", "distributed", "clustered", "branded", "outaide-the-box", "positioned", "networked", "focused", "leveraged", "aligned", "targeted", "shared", "cooperative", "accelerated"};
String[] wordListThree = {"process", "tipping-point", "solution", "architecture", "core competency", "strategy", "mindshare", "portal", "space", "vision", "paradigm", "session"};
// find out how many words are in each list
int oneLenqth = wordListOne.length;
int twoLength = wordListTwo.length;
int threeLength = wordListThree.length;
// generate .... random numbers
int randl = (int) (Math.random() * oneLenqth);
int rand2 = (int) (Math.random() * twoLength);
int rand3 = (int) (Math.random() * threeLength);
//now build a phrase
String phrase = wordListOne[randl] + " " + wordListTwo[rand2] + " " + wordListThree[rand3];
// print out the phrase
System.out.println("What we need is a " + phrase);
}
}

Related

Dynamic Adding item to list with different list and different adapter

how can I add item to list adapter, but every time I iterate n, it will add to a different list and different adapter, thanks!
//my first code
int n = 1;
while (n != 16) {
Day(n, Fullname);
n +=1 ;
}
//the other one that will add to the list and adapter
private void Day(int n,String Fullname){
String Date = "0" + n + "-" + Month + "-" + Year;
Cursor c = db.GetSpecific(Fullname,Date);
String allowancecount = "";
int intallowancecount = 0;
double totalCom = 0;
while(c.moveToNext()){
String serviceprice = c.getString(4);
String serviceperformedbynumber = c.getString(10);
allowancecount = c.getString(12);
intallowancecount = intallowancecount + Integer.parseInt(allowancecount.trim());
double income = Integer.parseInt(serviceprice.trim())/
Integer.parseInt(serviceperformedbynumber.trim());
totalCom = totalCom + income ;
//here what to do?
String add ="List" + n + ".add(String.valueOf(" + income + "));";
do add;//???????
}
//here what to do?
String Dynamic = "Com" + n + ".setText(String.valueOf(" + totalCom + "))";
do Dynamic ;//?????????
String Dynamicadapter = "Lv" + n + ".setAdapter(adapter" + n + ")";
do Dynamicadapter ;//????????
}
i'm just thinking if this was possible, but if not, i'll do it on the other way i know,open for any suggestions, thanks again.
It isn't possible in Java to assign variable using a variable name. However, there are things that you can use for these types of situations which allow you to almost do this, but everything is created correctly at runtime without the need for dynamic behaviour. For example, you can think about this in terms of using an associative array.
Taken from Wikipedia -https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(mapping)#Java
In Java associative arrays are implemented as "maps"; they are part of
the Java collections framework. Since J2SE 5.0 and the introduction of
generics into Java, collections can have a type specified; for
example, an associative array mapping strings to strings might be
specified
So in light of this, you could use a Map and restructure your code to do the following:
Create your adapter object
Set it's properties (such as setAdapter())
Add it to the map by using i (or whatever you want to use as a key for this)
Access it later on from the map using the key/dynamic 'variable name'
Map<Integer, ArrayAdapter<String>> map = new HashMap<Integer, ArrayAdapter<String>>();
for(int i = 0; i < 10; i++)
{
map.put(i, yourAdapter);
}

Variable not recognized after if argument

In the databse adapter, I'm trying to create a if (a & b) {select count from sqlite} .. full code as below.. however the cat variable is not recognized (as highlighted?
int samsung = 10;
int iphone = 20
public int getChick() {
int cat = 0;
if (red == 1 & blue == 2) {
int pit = (int) DatabaseUtils.longForQuery(db, "SELECT COUNT(*)
FROM table where one >= " + samsung + " and two >= " + iphone, null);
//////>>>>>> this cat is not recognized by eclipse
int cat = 0 + pit;
}
int dog = cat;
return dog;
}
Thing is, I don't see how it is wrong. If you could please point it out to me. Thanks.
you declare cat in the first line of the method and again inside the if statement. you need to remove the int declaration on the second one
Change
int cat = 0 + pit;
to
cat = 0 + pit;
It looks like you're simply declaring it again when you've already declared it.

Android basic math in textview

I am trying to add two numbers and display them in the textview using this code. The problem here is that it doesn't add the numbers, it just displays the entire string.
CharSequence fnum, snum, symbol;
final TextView CalTextBox = (TextView) findViewById(R.id.MainTextview);
symbol = "+"; // addition selected
fnum = CalTextBox.getText(); // store number into fnum
snum = CalTextBox.getText(); //new number will be added in the code and be stored into snum
CalTextBox.setText(""); // delete whats in the text box
CalTextBox.setText(snum + "" + symbol + "" + fnum); // add two numbers
Well, the '+' operator performs concatenation if used on strings (like in this case). To perform a math operation, you have to convert them to numbers first. I think you can use this:
// Convert the 2 String to integer values
int first = Integer.valueOf(fnum);
int second = Integer.valueOf(snum);
// Compute the sum
int sum = first + second;
// Create the String you can use to display in the TextView
String textToDisplay = String.valueOf(sum);
snum = "2";
fnum = "3";
symbol = "+";
snum + "" + symbol + "" + fnum = "2+3"
Instead you should convert String into integer or double and make appropriate controls such as null or empty, or non-numeric then,
int result = Integer.parseInt(snum) + Integer.parseInt(fnum);
CalTextBox.setText("" + result);
For mathematical operations is best to use int, long or double variable types. Instead of CharSequence use for example int.
to get integer (int) from String (text) use:
int fnum, snum, symbol;
int fnum = Integer.parseInt("10"); or
fnum = Integer.parseInt(CalTextBox.getText());
CalTextBox.setText("" + (snum + symbol + fnum));

Android - Set max length of logcat messages

By default, it seems that logcat will truncate any log message that it considers to be "too long". This happens both inside of Eclipse and when running logcat on the command line using adb -d logcat, and is truncating some important debugging messages.
Is there any way to increase the maximum string length supported by logcat to get it to stop truncating the debug information? The official documentation implies that there may not be, but maybe logcat supports some additional options not mentioned there?
Ok, interesting. I was disappointed to see that the answer was "you can't really expand it". My initial thought was to break it up so I could view the whole thing, so here I share with you how I do just that (not that it's anything fancy nor is it near efficient, but it gets the job done in a pinch):
if (sb.length() > 4000) {
Log.v(TAG, "sb.length = " + sb.length());
int chunkCount = sb.length() / 4000; // integer division
for (int i = 0; i <= chunkCount; i++) {
int max = 4000 * (i + 1);
if (max >= sb.length()) {
Log.v(TAG, "chunk " + i + " of " + chunkCount + ":" + sb.substring(4000 * i));
} else {
Log.v(TAG, "chunk " + i + " of " + chunkCount + ":" + sb.substring(4000 * i, max));
}
}
} else {
Log.v(TAG, sb.toString());
}
Edited to show the last string!
Break it up in several pieces recursively.
public static void largeLog(String tag, String content) {
if (content.length() > 4000) {
Log.d(tag, content.substring(0, 4000));
largeLog(tag, content.substring(4000));
} else {
Log.d(tag, content);
}
}
There is a fixed size buffer in logcat for binary logs (/dev/log/events) and this limit is 1024 bytes.
For the non-binary logs there is also a limit:
#define LOGGER_ENTRY_MAX_LEN (4*1024)
#define LOGGER_ENTRY_MAX_PAYLOAD (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
So the real message size for both binary and non-binary logs is ~4076 bytes.
The kernel logger interface imposes this LOGGER_ENTRY_MAX_PAYLOAD limit.
The liblog sources (used by logcat) also say:
The message may have been truncated by the kernel log driver.
I would recommend you the nxlog tool which does not use the logcat binary, but due to the limitations in the kernel I doubt that it will solve your problem. Nevertheless, it might be worth a try. (disclaimer: I'm the author.)
for( String line : logMesg.split("\n") ) {
Log.d( TAG, line );
}
Here is the code I use--it truncates the lines at the 4000 limit while also breaking the line at new lines rather than in the middles of the line. Makes for an easier to read log file.
Usage:
Logger.debugEntire("....");
Implementation:
package ...;
import android.util.Log;
import java.util.Arrays;
public class Logger {
private static final String LOG_TAG = "MyRockingApp";
/** #see <a href="http://stackoverflow.com/a/8899735" /> */
private static final int ENTRY_MAX_LEN = 4000;
/**
* #param args If the last argument is an exception than it prints out the stack trace, and there should be no {}
* or %s placeholder for it.
*/
public static void d(String message, Object... args) {
log(Log.DEBUG, false, message, args);
}
/**
* Display the entire message, showing multiple lines if there are over 4000 characters rather than truncating it.
*/
public static void debugEntire(String message, Object... args) {
log(Log.DEBUG, true, message, args);
}
public static void i(String message, Object... args) {
log(Log.INFO, false, message, args);
}
public static void w(String message, Object... args) {
log(Log.WARN, false, message, args);
}
public static void e(String message, Object... args) {
log(Log.ERROR, false, message, args);
}
private static void log(int priority, boolean ignoreLimit, String message, Object... args) {
String print;
if (args != null && args.length > 0 && args[args.length-1] instanceof Throwable) {
Object[] truncated = Arrays.copyOf(args, args.length -1);
Throwable ex = (Throwable) args[args.length-1];
print = formatMessage(message, truncated) + '\n' + android.util.Log.getStackTraceString(ex);
} else {
print = formatMessage(message, args);
}
if (ignoreLimit) {
while (!print.isEmpty()) {
int lastNewLine = print.lastIndexOf('\n', ENTRY_MAX_LEN);
int nextEnd = lastNewLine != -1 ? lastNewLine : Math.min(ENTRY_MAX_LEN, print.length());
String next = print.substring(0, nextEnd /*exclusive*/);
android.util.Log.println(priority, LOG_TAG, next);
if (lastNewLine != -1) {
// Don't print out the \n twice.
print = print.substring(nextEnd+1);
} else {
print = print.substring(nextEnd);
}
}
} else {
android.util.Log.println(priority, LOG_TAG, print);
}
}
private static String formatMessage(String message, Object... args) {
String formatted;
try {
/*
* {} is used by SLF4J so keep it compatible with that as it's easy to forget to use %s when you are
* switching back and forth between server and client code.
*/
formatted = String.format(message.replaceAll("\\{\\}", "%s"), args);
} catch (Exception ex) {
formatted = message + Arrays.toString(args);
}
return formatted;
}
}
int i = 3000;
while (sb.length() > i) {
Log.e(TAG, "Substring: "+ sb.substring(0, i));
sb = sb.substring(i);
}
Log.e(TAG, "Substring: "+ sb);
The code below is a refinement of what was posted by Mark Buikema. It breaks the string at new lines. Useful for logging long JSON strings.
public static void dLong(String theMsg)
{
final int MAX_INDEX = 4000;
final int MIN_INDEX = 3000;
// String to be logged is longer than the max...
if (theMsg.length() > MAX_INDEX)
{
String theSubstring = theMsg.substring(0, MAX_INDEX);
int theIndex = MAX_INDEX;
// Try to find a substring break at a line end.
theIndex = theSubstring.lastIndexOf('\n');
if (theIndex >= MIN_INDEX)
{
theSubstring = theSubstring.substring(0, theIndex);
}
else
{
theIndex = MAX_INDEX;
}
// Log the substring.
Log.d(APP_LOG_TAG, theSubstring);
// Recursively log the remainder.
dLong(theMsg.substring(theIndex));
}
// String to be logged is shorter than the max...
else
{
Log.d(APP_LOG_TAG, theMsg);
}
}
us this paging logic
/*
* StringBuffer sb - long text which want to show in multiple lines
* int lenth - lenth of line need
*/
public static void showInPage(StringBuffer sb, int lenth) {
System.out.println("sb.length = " + sb.length());
if (sb.length() > lenth) {
int chunkCount = sb.length() / lenth; // integer division
if ((chunkCount % lenth) > 1)
chunkCount++;
for (int i = 0; i < chunkCount; i++) {
int max = lenth * (i + 1);
if (max >= sb.length()) {
System.out.println("");
System.out.println("chunk " + i + " of " + chunkCount + ":"
+ sb.substring(lenth * i));
} else {
System.out.println("");
System.out.println("chunk " + i + " of " + chunkCount + ":"
+ sb.substring(lenth * i, max));
}
}
}
}
providing my own take on Travis's solution,
void d(String msg) {
println(Log.DEBUG, msg);
}
private void println(int priority, String msg) {
int l = msg.length();
int c = Log.println(priority, TAG, msg);
if (c < l) {
return c + println(priority, TAG, msg.substring(c+1));
} else {
return c;
}
}
take advantage of the fact that Log.println() returns the number of bytes written to avoid hardcoding "4000". then, recursively call yourself on the part of the message that couldn't be logged until there's nothing left.
If your log is very long (eg. logging entire dump of your database for debugging reasons etc.) it may happen that logcat prevents excessive logging. To work around this you can add a timeout evry x milliseconds.
/**
* Used for very long messages, splits it into equal chunks and logs each individual to
* work around the logcat max message length. Will log with {#link Log#d(String, String)}.
*
* #param tag used in for logcat
* #param message long message to log
*/
public static void longLogDebug(final String tag, #NonNull String message) {
int i = 0;
final int maxLogLength = 1000;
while (message.length() > maxLogLength) {
Log.d(tag, message.substring(0, maxLogLength));
message = message.substring(maxLogLength);
i++;
if (i % 100 == 0) {
StrictMode.noteSlowCall("wait to flush logcat");
SystemClock.sleep(32);
}
}
Log.d(tag, message);
}
Beware, only use this for debugging purpose as it may halts blocks main thread.
As #mhsmith mentioned, the LOGGER_ENTRY_MAX_PAYLOAD is 4068 in the recent Android versions. However, if you use 4068 as the max message length in the code snippets offered in other answers, the messages will be truncated. This is because Android adds more characters to the beginning and end of your message, which also count. Other answers use the 4000 limit as a workaround. However, it is possible to really use the whole limit with this code (the code generates a tag from the stack trace to show the class name and line number which called the log, feel free to modify that):
private static final int MAX_MESSAGE_LENGTH = 4068;
private enum LogType {
debug,
info,
warning,
error
}
private static void logMessage(LogType logType, #Nullable String message, #Nullable String tag) {
logMessage(logType, message, tag, Thread.currentThread().getStackTrace()[4]);
}
private static void logMessage(LogType logType, #Nullable String message, #Nullable String customTag, StackTraceElement stackTraceElement) {
// don't use expensive String.format
String tag = "DASHBOARDS(" + stackTraceElement.getFileName() + "." + (!TextUtils.isEmpty(customTag) ? customTag : stackTraceElement.getMethodName()) + ":" + stackTraceElement.getLineNumber() + ")";
int maxMessageLength = MAX_MESSAGE_LENGTH - (tag.length()) - 4; // minus four because android adds a letter showing the log type before the tag, e. g. "D/" for debug, and a colon and space are added behind it, i. e. ": "
if (message == null || message.length() <= maxMessageLength) {
logMessageInternal(logType, message, tag);
} else {
maxMessageLength -= 8; // we will add counter to the beginning of the message, e. g. "(12/15) "
int totalChunks = (int) Math.ceil((float) message.length() / maxMessageLength);
for (int i = 1; i <= totalChunks; i++) {
int start = (i - 1) * maxMessageLength;
logMessageInternal(logType, "(" + i + "/" + totalChunks + ") " + message.substring(start, Math.min(start + maxMessageLength, message.length())), tag);
}
}
}
private static void logMessageInternal(LogType logType, String message, String tag) {
if (message == null) {
message = "message is null";
}
switch (logType) {
case debug:
Log.d(tag, message);
break;
case info:
Log.i(tag, message);
break;
case warning:
Log.w(tag, message);
break;
case error:
Log.e(tag, message);
}
}
public static void d(String debug, String tag) {
logMessage(LogType.debug, debug, tag);
}
Though the other provided solutions were helpful, I wasn't satisfied by them cause they did not cover cases when the log is longer than twice as long as the LOGGER_ENTRY_MAX_LEN mentioned by #b0ti. Furthermore even my following solution is not perfect as the LOGGER_ENTRY_MAX_LEN is not fetched dynamically. If someone knows a way to do this, I would love to hear about it in the comments! Anyway, this is the solution I use in my code right now:
final int loggerEntryMaxLength = 4000;
int logLength = loggerEntryMaxLength - 2 - TAG.length();
int i = 0;
while (output.length() / logLength > i) {
int startIndex = i++ * logLength;
int endIndex = i * logLength;
Log.d(TAG, output.substring(startIndex, endIndex));
}
int startIndex = i * logLength;
Log.d(
TAG,
output.substring(
startIndex,
startIndex + (output.length() % logLength)
)
);
I dont know any option to increase the length of logcat , but we can find the different logs like main log , event log etc..The main log usually contains everything its length goes upto 4Mb.. So you may able to get what you lost in log terminal. Path is: \data\logger.
Each log has a limit of maximum 4096 bytes (4KB), and some bytes (about 40 bytes) are used for general information of each log like tag, priority(assert, debug, ...) and etc.
So I tried to trim 4056 bytes of the string to be logged.
Advantages:
The trim function executes very fast because it doesn't have any loops (executes in 1 ms)
It doesn't truncate any characters of the log message
It logs entire message using a recursive function into multiple log entries.
Here is the solution:
private static final int MAX_LOG_BYTES = 4056;
public static void log(int priority, String tag, #NonNull String content) {
int size = content.getBytes(StandardCharsets.UTF_8).length;
if (size > MAX_LOG_BYTES) {
String text = trim(content, MAX_LOG_BYTES);
Log.println(priority, tag, text);
log(priority, tag, content.substring(text.length()));
} else {
Log.println(priority, tag, content);
}
}
public static String trim(String text, int length) {
byte[] inputBytes = text.getBytes(StandardCharsets.UTF_8);
byte[] outputBytes = new byte[length];
System.arraycopy(inputBytes, 0, outputBytes, 0, length);
String result = new String(outputBytes, StandardCharsets.UTF_8);
// check if last character is truncated
int lastIndex = result.length() - 1;
if (lastIndex > 0 && result.charAt(lastIndex) != text.charAt(lastIndex)) {
// last character is truncated so remove the last character
return result.substring(0, lastIndex);
}
return result;
}

String Array increment each string in TextToSpeech

Using the text to speech API I want to change the string array to increment from index 0 string and when it reaches the end it will go back to the beginning.
At the moment it uses a random generator and the method works as follows:
public static void sayHello() {
// Select a random hello.
int helloLength = HELLOS.length;
String hello = HELLOS[RANDOM.nextInt(helloLength)];
mTts.speak(hello,
TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
null);
}
HELLOS is the array and it holds the strings:
String [] HELLOS = {"One" "Two" "Three" "Four"};
Appreciate any help
Thanks.
When you want to increment an index but loop around to zero again modulo is your friend.
int currentHelloIndex = 0;
public static void sayHello() {
// Select a random hello.
int helloLength = HELLOS.length;
String hello = HELLOS[currentHelloIndex];
currentHelloIndex = (currentHelloIndex + 1) % helloLength;
mTts.speak(hello,
TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
null);
}

Categories

Resources