Unable to find the error in logcat - android

I am unable to find the error in my android application. I have read guides on how to read logcat errors but the problem with my error is that it is not from my classes. Could someone give me some idea on how I could debug this?
I have a two spinners in my layout. One of which has an string array fixed for its list of items inside. The other spinner's items are generated dynamically with some code. The program actually runs fine on the emulator. But when I run on my device, a toggle button which doesnt uses the spinner crashes the application. If there is any more detail or information that I need to share to debug, do let me know.
Sorry I did post the logcat but the image disappeared. The complete logcat is below now.
And here is the toggle button which crashed the application when pressed.
public void onToggleClicked(View view) {
Context context = getApplicationContext();
if (checkConnectivity()) {
// Is the toggle on?
boolean on = tglbtn.isChecked();
if (on) {
startRepeatingTask();
} else {
stopRepeatingTask();
}
}
else {
Toast.makeText(context, "Please check your internet connection.", Toast.LENGTH_LONG).show();
}
}
These are the two methods....
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
//updateStatus(); //this function can change value of mInterval.
new updateBuses().execute();
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
The updateBuses class is an Asynctask which has nothing to do with my spinners. This is the method which populates my spinner.
private void plotBuses(ArrayList<MyMarker> markers) {
Log.d("Checking Array", mMyMarkersArray.toString());
if(markers.size() > 0)
{
for (MyMarker myMarker : markers)
{
// Create bus marker with custom icon and other options
Log.d("plotting", myMarker.getmLabel());
MarkerOptions markerOption = new MarkerOptions().position(new LatLng(myMarker.getmLatitude(), myMarker.getmLongitude()));
markerOption.title(myMarker.getmLabel());
markerOption.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_bus));
Marker currentMarker = map.addMarker(markerOption);
mMarkersHashMap.put(currentMarker, myMarker);
}
Log.d("check hashmap:", mMarkersHashMap.toString());
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
(this, android.R.layout.simple_spinner_item,spinnerList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(dataAdapter);
}
}
The spinnerList is not null because my spinner populates with the items inside my spinner.

According to documentation the purpose of the method makeAndAddView() that throws NullPointerException:
Obtain a view, either by pulling an existing view from the recycler or by getting a new one from the adapter.
This method tries to get the View by accessing adapter that is bound to this Spinner.
P.S.
What API version do you use during building? What are the AVD and actual phone Android versions you are testing on?

Related

Use arraylist for multiple if statements (with buttons)

I'm currently working on a school project in Android Studio and so far I've written a code which generates random equations.
Now I display two equations on the screen and the user then has to decide wether the second equation is bigger or smaller than the first one. If the second is bigger, the user presses the button 'bigger', if the second one is smaller, the user presses the button with 'smaller'.
Now I'm trying to write the code that if the user pressed correct, it generates a new equation, if he was wrong, the process stops.
I was thinking of if statements like so:
final ArrayList<String> arrayListCheck = new ArrayList<String>();
if(doubleAnswer1 > doubleAnswer2){
arrayListCheck.add("smaller");
} else {
arrayListCheck.add("bigger");
}
final Button buttonBigger = (Button)findViewById(R.id.button_bigger);
final Button buttonSmaller = (Button)findViewById(R.id.button_smaller);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.equals(buttonBigger)){
arrayListCheck.add("bigger");
} else {
arrayListCheck.add("smaller");
}
}
};
buttonBigger.setOnClickListener(listener);
buttonSmaller.setOnClickListener(listener);
In the arraylist arrayListCheck it will store either 'bigger' or 'smaller'. Now I want to check if the elements in the arraylist are both the same (either both 'bigger' or 'smaller'), if so a new equation will be generated. If the elements in the arraylist are different (not both the same), the process will be stopped.
I don't know if that really works, so it would be nice if someone could help me with this.
If there is anything unclear in my question, feel free to ask and I will try to clarify the problem :)
Thank you already in advance for your help!
I wouldn't use an ArrayList for that.
I would do the following:
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.equals(buttonBigger) && doubleAnswer1 < doubleAnswer2) {
Log.v("TAG", "you are right");
} else if(v.equals(buttonSmaller) && doubleAnswer1 > doubleAnswer2) {
Log.v("TAG", "you are right");
} else {
Log.v("TAG", "you are wrong");
}
}
};
Arrays are not really neccessary for this kind of simple comparison.

FirebaseUI RecyclerView random items added to listitems

When a button is pressed, a dialog appears asking user for message, with the option of attaching an image (from url). The problem I'm having is once the recyclerview is filled with enough items to scroll, when the user scrolls quickly for some reason random images start popping up in seemingly random list items.
I know the problem has to come from when the image is actually placed into the imageview, since I can tell the link is added to the firebase db just fine.
When the image link is submitted, it's sent to /posts/$uid/$post-id in a HashMap. Kind of like this:
final Map<String, String> postMap = new HashMap<String, String>();
imagebutton.setOnClickListener((view) -> {
AlertDialog.Builder = new...
LayoutInflater in = ...
View dialogLayout = ...inflate(r.layout...., null);
build.setView(dialogLayout);
EditText imgText = ...
Button submit = ...
AlertDialog a = build.create();
submit.setOnClickListener((View) -> {
...
postMap.put("imgLink", imgText.getText().toString());
a.dismiss();
...
urlDialog.show();
Then a few more items are added to the map and pushed to firebase.
Firebase postRef = ref.child("posts").child(auth.getUid());
postMap.put("author", ...);
postMap.put("content", ...);
postRef.push().setValue(postMap);
But like I said, I'm almost 100% sure the problem is not in posting the information, just populating the recview
Here's my code for the list itself:
RecyclerView feed = (RecyclerView)findViewById(R.id.recycler);
if (ref.getAuth() != null) {
FirebaseRecyclerAdapter<TextPost, PostViewHolder> adapter = new FirebaseRecyclerAdapter<TextPost, PostViewHolder>(TextPost.class, R.layout.list_item, PostViewHolder.class, ref.child("posts").child(uid)) {
#Override
protected void populateViewHolder(final PostViewHolder postViewHolder, final TextPost textPost, int i) {
postViewHolder.content.setText(textPost.getContent());
postViewHolder.author.setText(textPost.getAuthor());
postViewHolder.score.setText(textPost.getScore());
postViewHolder.time.setText(textPost.getTime());
if (textPost.getImgLink() != null && !textPost.getImgLink().equals("")) {
Log.i(TAG, "Setting image");
new Thread(new Runnable() {
#Override
public void run() {
try {
final Bitmap pic = bitmapFromUrl(textPost.getImgLink());
postViewHolder.img.post(new Runnable() {
#Override
public void run() {
postViewHolder.img.setImageBitmap(pic);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
...
feed.setAdapter(adapter);
I just started learning how to work with worker threads for network activities off the main UI thread so I assume I messed that up? I've gone through the logic over and over in my head and i can't seem to figure out what's going wrong here.
EDIT: I tried using AsyncTask instead of Threads and the problem persists. sos
All I had to do was set the ImageView drawable to null before populating the ImageView.
Like this:
#Override
protected void populateViewHolder(final ViewHolder v, final Object o, int i) {
//populate views
v.content.setText("...");
//Set imageview to null
v.imageview.setImageDrawable(null);*
if (o.getImageLink() != null && !o.getImageLink.equals("")) {
// Start AsyncTask to get image from link and populate imageview
new DownloadImageTask().execute(o.getImgLink(), v.imageview);
}
}

AutocompleteTextView is not updated dynamically

I am getting data (List) from an API and I am trying to update my AutcompleteTextView with this data.
This is how I currently do :
I have a TextWatcher which calls a the method to get the data in afterTextChanged, so every time the user stops typing the method is called, and the adapter is notified with ``notifyDataSetChanged :
//in onCreate
addressAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,suggestions_address);
at_address.setAdapter(addressAdapter);
...
#Override
public void afterTextChanged(Editable s) {
autoComplete(s);
addressAdapter.notifyDataSetChanged();
//suggestions_address is the updated list, and when I print it I can see the
//results so it is not empty
Log.i("addresses",suggestions_address.toString());
}
...
class SuggestionQueryListener implements ResultListener<List<String>> {
#Override
public void onCompleted(List<String> data, ErrorCode error) {
if (error != ErrorCode.NONE) {
Toast.makeText(MainActivity2.this,error.toString(),Toast.LENGTH_LONG).show();
} else {
suggestions_address.clear();
for(int i = 0;i<data.size();i++){
suggestions_address.add(data.get(i));
}
}
}
}
public void autoComplete(CharSequence s) {
try {
String term = s.toString();
TextSuggestionRequest request = null;
request = new TextSuggestionRequest(term).setSearchCenter(new GeoCoordinate(48.844900, 2.395658));
request.execute(new SuggestionQueryListener());
if (request.execute(new SuggestionQueryListener()) != ErrorCode.NONE) {
//Handle request error
//...
}
} catch (IllegalArgumentException ex) {
//
}
}
But it seems that the adapter is not really updated because it doesn't show the suggestions when I type something.
Also, before doing this with an AutoCompleteTextView I did it with a listView, with the same process, and everything worked well.
Any ideas or solutions would be really appreciated
EDIT : I noticed something really strange : the data is not binded to the adapter, because adapter#getCount always returns 0, even if the list is not empty. But when I remove at_address.setAdapter(addressAdapter), the data adapter is updated and adapter#getCount returns the right number of elements.
I am really confused right now, please help !
Instead of this:
for(int i = 0;i<data.size();i++){
suggestions_address.add(data.get(i));
}
you can use just this:
suggestions_address.addAll(data);
you are calling notifyDataSetChanged after you start the request, you should call it after you get the result and update the suggestions_address, so call notifyDataSetChanged inside onCompleted

Android: How to get search suggestions asynchronously from the web?

I have created a searchable activity. Now, i want to add search suggestions that are taken from web service. I want to get those suggestions asynchronously. According to Adding Custom Suggestions I need to override the query method, do my suggestion search, build my own MatrixCursor and return it. but this is the problem, my request for getting the suggestion is an asynchronically one. so when result is back from net it out side of query method's scope.
Here is an example of SearchView with suggestions coming from a network service (I used Retrofit):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_search_activity, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.search));
final CursorAdapter suggestionAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
null,
new String[]{SearchManager.SUGGEST_COLUMN_TEXT_1},
new int[]{android.R.id.text1},
0);
final List<String> suggestions = new ArrayList<>();
searchView.setSuggestionsAdapter(suggestionAdapter);
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
#Override
public boolean onSuggestionSelect(int position) {
return false;
}
#Override
public boolean onSuggestionClick(int position) {
searchView.setQuery(suggestions.get(position), false);
searchView.clearFocus();
doSearch(suggestions.get(position));
return true;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
MyApp.autocompleteService.search(newText, new Callback<Autocomplete>() {
#Override
public void success(Autocomplete autocomplete, Response response) {
suggestions.clear();
suggestions.addAll(autocomplete.suggestions);
String[] columns = {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_INTENT_DATA
};
MatrixCursor cursor = new MatrixCursor(columns);
for (int i = 0; i < autocomplete.suggestions.size(); i++) {
String[] tmp = {Integer.toString(i), autocomplete.suggestions.get(i), autocomplete.suggestions.get(i)};
cursor.addRow(tmp);
}
suggestionAdapter.swapCursor(cursor);
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(SearchFoodActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
Log.w("autocompleteService", error.getMessage());
}
});
return false;
}
});
return true;
}
It seems that the request to the suggestion content provider is not run on the UI thread, anyway, according to this answer: https://stackoverflow.com/a/12895381/621690 .
If you can change your http request you could simply call it blocking inside the query method. Might help to listen for interruptions or other signals (custom ones maybe) to stop unnecessary requests.
Another option - if you do not want to change any request classes that are already asynchronous (like if you are using Robospice) - should be to just return the MatrixCursor reference and populate it later on. The AbstractCursor class already implements the Observer pattern and sends out notifications in case of changes. If the search system is listening it should handle any changes in the data. I have yet to implement that myself so I cannot confirm that it will work out as nicely as I picture it. (Have a look at CursorLoader's source for more inspiration.)
And, anyway, isn't that the whole point of a cursor? Otherwise we could simply return a list with data.
UPDATE:
For me, using a MatrixCursor didn't work out. Instead, I have implemented two other solutions:
Using the AutoCompleteTextField in combination with a custom subclass of ArrayAdapter which itself uses a custom subclass of Filter. The method Filter#performFiltering() (which I override with the synchronous call to the remote service) is called asynchronously and the UI thread is not blocked.
Using the SearchWidget with a SearchableActivity and a custom ArrayAdapter (without custom Filter). When the search intent comes in, the remote request is started (Robospice) and when it comes back via callback, I call the following custom method on my ArrayAdapter<Tag> subclass:
public void addTags(List<Tag> items) {
if (items != null && items.size() > 0) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
super.setNotifyOnChange(false);
for (Tag tag : items) {
super.add(tag);
}
super.notifyDataSetChanged();
} else {
super.addAll(items);
}
}
}
This method takes care of triggering the notifications on the adapter and thus the search result list.
The closest thing I have found to solve this, is by using a ContentProvider and do the network request on the Query method of your provider (even when this goes against the best practices), with the result you can create a MatrixCursor as it's show here and here.
I'm still searching for other options like using a SyncAdapter, which seems overwhelming for the purpose of just showing suggestions that aren't used anywhere else.
Another option, that I took to do this asynchronously is to use an AutoCompleteTextView, that way you can create a custom adapter, where you can implement the getFilter function as it is shown in this answer.

Can any body explain this code from Hello Android book

I cannot understand this code in page number 68-69 in Hello Android book. Some methods used in the code are new to me. Can anybody elaborate and explain the code.
private static final String TAG = "Sudoku" ;
private void openNewGameDialog() {
new AlertDialog.Builder(this)
.setTitle(R.string.new_game_title)
.setItems(R.array.difficulty, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface,int i) {
startGame(i);
}
})
.show();
}
private void startGame(int i) {
Log.d(TAG, "clicked on " + i);
// Start game here...
}
All it does is when you call openNewGameDialog() it will create an alertdialog with an assigned title and list of options from a resource file ("R.array.difficulty" is an integer value ultimately pointing to a string-array declared in the file /res/values/arrays.xml). An AlertDialog is a simple to create way of getting input from the user. It can also be used for output, but many prefer Toast for that task. The
.show() at the end of it brings the dialog to the foreground.
When the items are added in that call they are assigned an onClick listener which when an item is clicked it sends the index of that item to startGame. In that function it only sends a message including the index to the logcat debug system.

Categories

Resources