I have a bunch of EditTexts that are set up with int Strings to capture their length. I want to show the lengths in LogCat to confirm they have been set up correctly. I read about using LogCat, tags and how to filter but need some advice on how to add Log code to get output to LogCat.
Here is an example of the int String I am looking to calculate length for:
public class CardViewActivity extends AppCompatActivity {
private String tag = "CLOCKS";
private ListenerEditText eListenerEditText;
eListenerEditText.setKeyImeChangeListener(new KeyImeChange() {
#Override
public boolean onKeyIme(int keyCode, KeyEvent event) {
int stringNotes2 = eListenerEditText.getText().toString().trim().length();
Log.d("CLOCKS", String.valueOf(stringNotes2));
Log.d() must be called in somewhere like onCreate(..) {..} or some type of method.
for example,
// This is wrong
public class Hello {
Log.d("hello","hi");
...
}
Make sure you call methods in some type of methods.
// This is correct
public class Hello extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Hello","Hi");
...
}
...
}
Hope this helps
You shoud declare your log tag:
private static final String MYAPPTAG= YourActivity.class.getName();
Then you put the log code in a method:
Log.d(MYAPPTAG, String.valueOf(stringDueDate));
You will need to make sure you set your filter properly in logCat settings.
I suggest you to concatenate with a string to make sure something prints to the console just incase the value is null, for example:
Log.d(MYAPPTAG, "stringDueDate = " + stringDueDate);
Try this -
public class CardViewActivity extends AppCompatActivity {
private static final String TAG = "CLOCKS";
private ListenerEditText eListenerEditText;
eListenerEditText.setKeyImeChangeListener(new KeyImeChange() {
#Override
public boolean onKeyIme(int keyCode, KeyEvent event) {
int stringNotes2 = eListenerEditText.getText().toString().trim().length();
Log.d(TAG, "Length - " + stringNotes2));
}
}
If this doesn't work then there must be something wrong with your listener. I'll highly recommend to use TextWatcher on EditText over KeyListener.
Log.i: Use this to post useful information to the log. For example: that you have successfully connected to a server. Basically use it to report successes.
Log.i(String tag, String msg);
Related
In Android, how do I take an action whenever a variable changes?
So I want to implement a listener for an object I created. What I want it to do is execute a block of code when its value changes from false to true.
As I am following this thread, I can't understand where the person wants us to implement the last block of code containing the logic for the listener.
Could someone, hopefully, guide me in the right direction?
(This question is being asked here as I don't have enough rep. points)
That last bit of example code triggers the listener, so it basically needs to be run whenever the "event" occurs. In this case the "event" is whenever (wherever in the code) the value of the variable changes.
If you have a setter and that is the only place the value changes, that is where you'd put it. If you are changing the value in multiple places throughout your code, I would make a new private method (call it signalChanged), put your code there, and then call it immediately after the variable assignment in the cases you want the listener to fire.
Here's an example (some code borrowed from linked answer, haven't checked that it compiles).
public class MyObj
{
public MyObj(int value)
{
setValue(value);
}
private int myValue;
public int getValue() { return myValue; }
public void setValue( int value )
{
if (value != myValue)
{
myValue = value;
signalChanged();
}
}
public interface VariableChangeListener
{
public void onVariableChanged(Object... variableThatHasChanged);
}
private VariableChangeListener variableChangeListener;
public void setVariableChangeListener(VariableChangeListener variableChangeListener)
{
this.variableChangeListener = variableChangeListener;
}
private void signalChanged()
{
if (variableChangeListener != null)
variableChangeListener.onVariableChanged(myValue);
}
}
you have to create a callback interface
here is a good about custom listener tutorial
here is a sample
public class MyObj {
VariableChanger onVariableChanged ;
public void setOnVariableChanged(VariableChanger onVariableChanged) {
this.onVariableChanged = onVariableChanged;
}
void log(){
boolean changed = false;
onVariableChanged.onVariableChanged();
//this will call it
}
interface VariableChanger{
void onVariableChanged();
}
}
class logic {
MyObj mo = new MyObj();
void main(){
mo.setOnVariableChanged(new MyObj.VariableChanger() {
#Override
public void onVariableChanged() {
//do your action
}
});
}
}
In Android, like any language, most developper uses logic comparisons to check values (if, else, switch, =, !=, >, <, etc) or Event (signal)
What kind of listener do you want to implement?
I have a variable in my class , I want when that variable changed , I do an action in another class .
in fact I want a listener for changing variable in android (my variable may change every minute)
public class Connect {
public static boolean myBoolean;
//some actions do and myBoolean change
}
public class Selection extends Activity implements OnMenuItemClickListener{
//I want a thing like listener here ,when myboolean changed I do an action (myboolean may change every minute)
}
It's not possible directly. However, you can make your field private, add getters and setters, and create a method of adding listeners (this is called the Observer pattern):
interface ConnectionBooleanChangedListener {
public void OnMyBooleanChanged();
}
public class Connect {
private static boolean myBoolean;
private static List<ConnectionBooleanChangedListener> listeners = new ArrayList<ConnectionBooleanChangedListener>();
public static boolean getMyBoolean() { return myBoolean; }
public static void setMyBoolean(boolean value) {
myBoolean = value;
for (ConnectionBooleanChangedListener l : listeners) {
l.OnMyBooleanChanged();
}
}
public static void addMyBooleanListener(ConnectionBooleanChangedListener l) {
listeners.add(l);
}
}
Then, wherever you want to listen to changes of the boolean, you can register a listener:
Connect.addMyBooleanListener(new ConnectionBooleanChangedListener() {
#Override
public void OnMyBooleanChanged() {
// do something
}
});
Adding a method to remove listeners is left as an exercise. Obviously, for this to work, you need to make sure that myBoolean is only changed via setMyBoolean, even inside of Connect.
I am a beginner in this field.
How can i access a method from one package to another.
For example:
package add;
public class Addfunction {
int a,b,sum;
public int add(int x,int y)
{
a=x;
b=y;
sum=a+b;
return sum;
}
}
in my second package
package com.example.demoo;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int Result;
Addfunction addfunction=new Addfunction();
Result=addfunction.add(5, 10);
Toast.makeText(getApplicationContext(), Result , Toast.LENGTH_LONG).show();
}
}
while running it shows Unfortunately app is stop.
please help me to solve this.
There's nothing wrong in how you access the Addfunction class. But consider two things.
First, you must add an import for the Addfunction class before the MainActivity class definition:
import add.Addfunction;
although you probably already have that, because it wouldn't compile otherwise.
Second, you are probably using this makeText:
static Toast makeText(Context context, int resId, int duration)
Make a standard toast that just contains a text view with the text from a resource.
instead of this:
static Toast makeText(Context context, CharSequence text, int duration)
Make a standard toast that just contains a text view.
Note the second parameter is an int in the first case which refers to a resource. And you are just passing the result of your computation which is probably an invalid resource id.
You may want to try to build a message in a String object and pass it to makeText, like this:
String msg = "Result: " + Result;
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
public class Excuses extends ActionBarActivity {
// openings
private String[] openings = {
getString(R.string.opening_1),
getString(R.string.opening_2),
getString(R.string.opening_3),
getString(R.string.opening_4),
getString(R.string.opening_5),
getString(R.string.opening_6),
getString(R.string.opening_7),
getString(R.string.opening_8),
getString(R.string.opening_9),
getString(R.string.opening_10),
getString(R.string.opening_11),
getString(R.string.opening_12),
getString(R.string.opening_13),
getString(R.string.opening_14),
getString(R.string.opening_15),
getString(R.string.opening_16),
getString(R.string.opening_17)
};
When ran, this error pops up:
Caused by: java.lang.NullPointerException
at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:79)
at android.content.Context.getString(Context.java:352)
at com.aczylsapp.com.excusegenerator.Excuses.<init>(Excuses.java:12)
This line gives me the NullPointerException:
private String[] openings = {
and, I have no idea why :/
I have already looked at other posts, but they do not help me.
If someone could help me out, I would be greatful.
The problem is that the Activity was not fully constructed, based on Activity Lifecycle and you cannot access the Resources properly.
You must move this assignment to inside onCreate method. Like:
public class Excuses extends ActionBarActivity {
// openings, will be initialize in onCreate method
private String[] openings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeOpenings();
// Your initialization code
}
public void initializeOpenings() {
openings = new String[] {
getString(R.string.opening_1),
getString(R.string.opening_2),
getString(R.string.opening_3),
getString(R.string.opening_4),
getString(R.string.opening_5),
getString(R.string.opening_6),
getString(R.string.opening_7),
getString(R.string.opening_8),
getString(R.string.opening_9),
getString(R.string.opening_10),
getString(R.string.opening_11),
getString(R.string.opening_12),
getString(R.string.opening_13),
getString(R.string.opening_14),
getString(R.string.opening_15),
getString(R.string.opening_16),
getString(R.string.opening_17)
};
}
}
But there is a better way to do this!
Create an String Array in your resource, like:
<string-array name="openings">
<item>#string/opening_1</item>
<!-- Declare all your items here -->
<item>#string/opening_17</item>
</string-array>
And access then with getStringArray(int resId):
public class Excuses extends ActionBarActivity {
// openings, will be initialize in onCreate method
private String[] openings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeOpenings();
// Your initialization code
}
public void initializeOpenings() {
openings = getResources().getStringArray(R.array.openings);
}
}
Null Pointer exception means that the objects you are trying to put into your array are empty or dont exist.
In your case, this likely means that getString(R.string.opening_1) is returning null.
I suspect that the issue lies with the parameter you are putting in your getString() method. If I were you, I'd take a good look at your getString() and check that getString(R.string.opening_1) is returning the String you want it to.
Based on the Android Documentation for getString(), you need to make sure that the "Resource id for the string" can be found.
I have an app that uses custom Exceptions, such as this:
public class SomeException extends Exception{
private int iCode;
private String iMessage;
public SomeException(){
iCode = 201;
iMessage = **//Get the localized string R.string.error_201??**
}
#Override
public String getMessage() {
return iMessage;
}
#Override
public int getCode() {
return iCode;
}
}
Obviously, I want lo localize the error message. I have possible solutions but non of them satisfy me.
1) Pass "Context" to the constructor, and do ctx.getString(R.string.error_201)
--> Fail, as this Exceptions are sometimes thrown from MODEL classes, so they don't have a Context
2) Pass "Context" when retriveing the message in getMessage() function,
--> Fail, It's necesary to override the super method, to work as all other Exceptions.
Solution I have now: All activities in my app have this onCreate:
public void onCreate(...){
Utils.RESOURCES = getResources();
...
}
Very dirty code... I don't like the solution. My question is then,: is there a way to access the resources without the Context? And most important, How would an application such as mine solve this problem?
What about
public class MyException extends Exception {
private int iCode;
public MyException(int code) {
this.iCode = code;
}
#Override
public String getMessage() {
return "MyException code " + String.valueOf(iCode);
}
public String getLocalizedMessage(Context ctx) {
String message;
if (iCode == 201)
message = ctx.getString(R.string.error_201);
else if (iCode == 202)
message = ctx.getString(R.string.error_202);
// ...
}
}
Even if there was way to access context in different way, you should not do it. If you need to emit exceptions where you cannot pass Context, you should be able to access context before you display such error. I cannot see reason why you should create localized error messages from constructor. You can log to logcat not localized versions if you need. And where you want to display something in UI, you should have context at hand.
You can access only system wide resources without Context.
You need a Context, so I would suggest You to get it as soon as possible, and make it available through a static method or variable. You do the same thing in every Activity, but there is a cleaner method. You should make a custom Application, and override its onCreate() to make the resources public:
public class App extends Application {
private static Resources myResources;
#Override
public void onCreate() {
myResources = getBaseContext().getResources();
super.onCreate();
}
public static Resources getMyResources(){
return myResources;
}
}
The other thing you have to do is to set the Application in your manifest:
<application
android:name="{your_package}.App"
...
Now you can access the resources in all of your Activity without any preparation. Your custom Exception class could also use the externalized resources.