i have a simple doubt in android programming. I am not familiar with java coding.so it might be a simple problem.
In the first two lines I am retrieving an array, which i passed from another activity to this activity...Then i am creating an array list . I am creating an object in the 4th line. Now comes the problem ...
I have to run a for loop to get the url value, which i have to pass it in the BaseFeedParser class. but i cant use the 4th line, i.e creating the object inside the loop because it will create a new object each time... which should not happen ... how can i fix this probelm?
Intent myintent = getIntent();
String[] ActiveURL = myintent.getStringArrayExtra("URL");
List<String> titles = new ArrayList<String>();
BaseFeedParser parser = new BaseFeedParser(url);
// fetching all active URLs
for (int i = 0; i < ActiveURL.length + 1; i++) {
url = ActiveURL[i];
messages.addAll(parser.parse());
}
// now getting the titles out of the messages for display
for (Message msg : messages) {
titles.add(msg.getTitle());
}
Thanks in advance ...
There are some problems in your java code :
Intent myintent = getIntent();
//variables are named in camel case, starting with a lower case letter
String[] activeURL = myintent.getStringArrayExtra("URL");
List<String> titles = new ArrayList<String>();
//we will use parser later, see below
//BaseFeedParser parser = new BaseFeedParser(url);
// fetching all active URLs
//it's very easy to loop through a table in java / C / C++
//learn the pattern, it's the simplest, you got confused with the final index
for (int i = 0; i < activeURL.length ; i++) {
//here you don't change the former object url was referencing,
//you are saying that you give the name url to another object in the array
//it doesn't create any new item, change giving them a name to use them
url = activeURL[i];
//create a new parser for each url, except if they can be recycled
//i.e they have a property setUrl
messages.addAll( new BaseFeedParser(url).parse());
}
// now getting the titles out of the messages for display
for (Message msg : messages) {
titles.add(msg.getTitle());
}
Indeed, you could even shorten the whole thing by
Intent myintent = getIntent();
String[] activeURL = myintent.getStringArrayExtra("URL");
List<String> titles = new ArrayList<String>();
// fetching all active URLs
//use a for each loop
for ( String url : activeURL ) {
//loop through messages parsed from feed to add titles
for (Message msg : new BaseFeedParser(url).parse() ) {
titles.add(msg.getTitle());
}
}
if you don't need the List of Message you called messages.
Related
When exporting my array list item, Im getting this error. In the first place it works but when updating my code adding data on my array it crashed my app and this error appear, do you have any idea why this happening?
java.lang.ClassCastException: android.text.SpannableStringBuilder
cannot be cast to java.lang.String
I'm getting error in this line 312 after if statement -
mEdit1.putString("Status_" + i,list_items.get(i));
I've already tried put empty string on my list like this
""+list_items.get(i));
but it's not working :(
ArrayList<String> list_items = new ArrayList<String>(); //declared global
ArrayAdapter arrayAdapter; //declared global
public boolean export_data()
{
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor mEdit1 = sp.edit();
mEdit1.putString("Status_","");
mEdit1.apply();
mEdit1.putInt("Status_size", list_items.size());
for(int i=0;i<list_items.size();i++)
{
mEdit1.remove("Status_" + i);
if (list_items.get(i) !=null){
mEdit1.putString("Status_" + i,list_items.get(i));
String[] separated = list_items.get(i).split(":");
mEdit1.putString("Status_" + i, separated[0]);
}
else{
Toast.makeText(getApplicationContext(), "List is Empty", Toast.LENGTH_SHORT).show();
}
}
return mEdit1.commit();
}
Adding item on ArrayAdapter
public void refreshInbox(){
arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list_items);
ContentResolver cResolver = getContentResolver();
Cursor smsInboxCursor = cResolver.query(Uri.parse("content://sms/inbox"),null,null,null,"date desc");
int indexBody = smsInboxCursor.getColumnIndex("body");
if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
do{
String strbody = smsInboxCursor.getString( smsInboxCursor.getColumnIndex("body") );
if(strbody.contains("Notifier,") && strbody.contains(":")){
System.out.println ( strbody );
String str = strbody;
String[] separated = str.split(",");
String separate = separated[1];
String[] sep = separate.split(" : ");
String sep1 = sep[1];
String finals = separate.replace(sep1, "<u>"+"<b>" + sep1 +"<b>"+ "</u>");
arrayAdapter.add(Html.fromHtml(finals));
}
else if(strbody.contains("Notifier,") && !strbody.contains(":")){
System.out.println ( strbody );
String str = strbody;
String[] separated = str.split(",");
String separate = separated[1];
arrayAdapter.add(separate);
}
}while (smsInboxCursor.moveToNext());
}
Assuming you want to keep displaying HTML in your list view, the problem is that the objects that ArrayAdapter is adding list_items are not Strings. That means, you have to change how you define the list_items variable from String to a more generic character sequence type:
ArrayList<CharSequence> list_items = new ArrayList<>();
The CharSequence interface does not have a "split" method though. To be able to use "split", you'll need to call toString to get a regular string:
String[] separated = list_items.get(i).toString().split(":");
It would also help if you used the type parameter with your ArrayAdapter. Using the type parameter would have made it harder (if not impossible) to make this mistake.
ArrayAdapter<CharSequence> arrayAdapter;
... inside the method ...
arrayAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, list_items);
list_items.get(i));
Looks like you might be attempting to put an unusual type of string into the list...
see: java.lang.ClassCastException: android.text.SpannableString cannot be cast to java.lang.String
I'm not an android dev but I suspect there are some "useful" shortcuts it provides in an attempt to make your life easier, that would probably trip you up.
Groovy's default string was a GString rather than a String. That tripped me up a number of times before I got used to it.
The error is with this line in refreshInbox()
arrayAdapter.add(Html.fromHtml(finals));
Html.fromHtml does't return String but instead it retuns Spanned
But you need to pass String to add() on adapter
To fix this convert it to String
adapter.add(Html.fromHtml(finals).toString()); // this will return plain text without html tags
or
adapter.add(finals); // this will be having HTML tags from this you can set text on views later
i have data in sqlit database so i use it to store categoreis and items
and i get it in arraylist like this:
public ArrayList showDataItems(String id_cate){
ArrayList<Items> arrayListItems = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cr = db.rawQuery("select * from items where id_cate = "+id_cate,null);
cr.moveToFirst();
while (cr.isAfterLast() == false){
String item_id = cr.getString(0);
String ItemName = cr.getString(1);
String Item_quantity = cr.getString(2);
String icon = cr.getString(3);
int isDone = Integer.parseInt(cr.getString(5));
arrayListItems.add(new Items(item_id,ItemName,Item_quantity,R.drawable.shopicon,icon,isDone));
cr.moveToNext();
}
return arrayListItems;
}
so i need to get this data and convert it to string and share it to other application like whatsapp in custom format for example :
1- first one *
2- second one *
3-....
so i use this code for send data
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT,"hello world");
intent.setType("text/plain");
startActivity(Intent.createChooser(intent,"send items i need all
data here"));
so we can use string builder or some thing to get data in one string
please help me!
As you said, there is a StringBuilder class who can help formatting strings.
Here are the java docs
From StringBuilder, see the append(..) method. For your example:
int size = list.size();
for(int i = 0; i< size-1;i++){
stringBuilder.append(i+1).append("- ").append(list.get(i)).append('\n');
}
stringBuilder.append(size).append("- ").append(list.get(size-1));
The last call to append is different from the firstone by not appending the end line
I am trying to parse a REST API that has 3 possible variations. The first one is the one I already have working where there is an array for the "row" output as shown in the photo below.
There is also row as an object, as pictured below.
And finally, one where there is no data, as shown below.
Any one of these is a possible output when parsing the API, I need something like an if statement to see which one is the output and parse the information from there, but I do not know how to create an if statement for this particular need. Here is my current code:
JSONObject parentObject = new JSONObject(finalJson);
JSONObject responseJSON = JSONUtils.jsonObjectFromJSONForKey(parentObject, "response");
if (responseJSON != null) {
JSONObject resultJSON = JSONUtils.jsonObjectFromJSONForKey(responseJSON, "result");
JSONObject contactsJSON = JSONUtils.jsonObjectFromJSONForKey(resultJSON, "Potentials");
JSONArray parentArray = contactsJSON.getJSONArray("row");
List<Photoshoots> photoshootsList = new ArrayList<>();
for (int i = 0; i < parentArray.length(); i++) {
JSONObject mainObject = parentArray.getJSONObject(i);
JSONArray mainArray = mainObject.getJSONArray("FL");
Photoshoots photoshoot = new Photoshoots();
...
I have solved the problem I was having. It may not be the ideal way to solve the problem, but it does work. Inside of the doInBackground in AsyncTask, I had initially converted the JSON result data into a StringBuffer, then converted the StringBuffer to a String. I then used one if and 2 else if statements to parse the data. The first if statement checks if the JSON string contains the phrase "nodata" representing that no data matches my original criteria, shown below:
if (finalJson.contains("nodata"))
I then had it pass on null data to be checked in onPostExecute for later. Next else if statement checked to see if row is an array. The way I did that was check to see if the string had a [ after row, indicating that it was an array, shown below:
else if (finalJson.contains("{\"response\":{\"result\":{\"Potentials\":{\"row\":["))
I then parsed the information as follows:
JSONArray parentArray = contactsJSON.getJSONArray("row");
for (int i = 0; i < parentArray.length(); i++) {
JSONObject mainObject = parentArray.getJSONObject(i);
JSONArray mainArray = mainObject.getJSONArray("FL");
the final else if, which could probably just be an else statement, is almost the same, except looking for a { after row instead of [, indicating it was just an object, as shown below:
else if (finalJson.contains("{\"response\":{\"result\":{\"Potentials\":{\"row\":{"))
I then parsed the information as follows:
JSONObject mainObject = contactsJSON.getJSONObject("row");
JSONArray mainArray = mainObject.getJSONArray("FL");
Inside of the onPostExecute, I have a code that will run a class that extends ArrayAdapter for the results contained in both of the else if statements, but I don't want it to run if there is no data, so I did the following:
protected void onPostExecute(List<Photoshoots> result) {
super.onPostExecute(result);
if (result != null) {
PhotoshootAdapter adapter = new PhotoshootAdapter(getApplicationContext(), R.layout.row, result);
lvPhotoshoots.setAdapter(adapter);}
else{
new CountDownTimer(60000, 1000) {
public void onTick(long millisUntilFinished) {
btnRefresh.setText("No Data to Show. Try again in " + millisUntilFinished / 1000 + " Seconds");
}
public void onFinish() {
btnRefresh.setText("Refresh");
btnRefresh.setEnabled(true);
}
}.start();
The result will pass the null data if there is nodata, but a list if there is data within the result. Like I said, there may be a better way to solve this problem, but the app works now and it doesn't crash regardless of the data that is returned.
I'm trying to take data from a backend(I'm using parse.com), put it into an array and use it to populate a ListView via an adapter. I parse multiple objects into a list and then put "names" and "ids" into two separate string arrays.
Now, my problem is that data disappears as soon as I add the next position to the array. I've spent quite a while figuring this out with debug logs, and it appears as if names[0] is displayed in the log properly when requested right after I write it. If I try to access names[0] after writing names[1] I get a null pointer exception - println needs a message, and the app crashes. When not trying to access the data via debug log, the listview is populated by a proper number of entries, yet the data that should've come from names[] and ids[] is empty. Here's the code where everything goes horribly wrong:
names = new String[2];
ids = new String[2];
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestItem");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
int size = objects.size();
int i = 0;
ParseObject obj;
while (i < size) {
obj = objects.get(i);
names[i] = obj.getString("name");
ids[i] = obj.getString("objectId");
i++;
}
/*The following code is fairly irrelevant(I think?) since the error appears
to be somewhere in the previous lines.*/
Bundle bundel = new Bundle();
bundel.putStringArray("names", names);
bundel.putStringArray("ids", ids);
ft = getSupportFragmentManager().beginTransaction();
screen = new Feed().newInstance(bundel);
ft.add(R.id.holder_frame, screen);
ft.commit();
} else {
}
}
});
I feel like it's something basic about managing arrays, but I can't seem to understand it. Please help :(
The following line seems to be fishy:
new Feed().newInstance(bundel);
newInstance method should be static method.
Make sure that you are adding the appropriate instance of fragment with the bundle information. If you don't figure it out, provide code in the Fragment.
Consider code below:
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestItem");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
int size = objects.size();
String[] names = new String[size];
String[] ids = new String[size];
for (int i = 0; i < size; i++) {
ParseObject elem = objects.get(i);
names[i] = elem.getString("name");
ids[i] = elem.getObjectId();
}
/*The following code is fairly irrelevant(I think?) since the error appears
to be somewhere in the previous lines.*/
Bundle params = new Bundle();
params.putStringArray("names", names);
params.putStringArray("ids", ids);
ft = getSupportFragmentManager().beginTransaction();
screen = new Feed();
screen.setArguments(params);
ft.add(R.id.holder_frame, screen);
ft.commit();
} else {
Toast.make(<Current>Activity.this, "Error", ...).show();
}
}
});
I think this might be the problem:
int size = objects.size();
int i = 0;
ParseObject obj;
while (i < size) {
obj = objects.get(i);
names[i] = obj.getString("name");
ids[i] = obj.getString("objectId");
i++;
}
names and ids are initialised as
names = new String[2];
ids = new String[2];
You are looping over all of the elements in objects so if it has any more than two elements you will be writing outside the bounds of the names and ids arrays.
I am working on a JSF based Web Application where I read contents from a file(dumpfile) and then parse it using a logic and keep adding it to a list using an object and also set a string using the object. But I keep getting this error. I am confused where I am wrong. I am a beginner so can anyone be kind enough to help me?
List<DumpController> FinalDumpNotes;
public List<DumpController> initializeDumpNotes()
throws SocketException, IOException {
PostProcessedDump postProcessedDump = (PostProcessedDump) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("postProcessedDump");
List<DumpController> FinalNotes = new ArrayList<>();
if (postProcessedDump.getDumpNotes() == null) {
dumpNotes = new DumpNotes();
}
DumpListController dlcon = (DumpListController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("dumpListController");
DumpInfo dumpinfo = dlcon.getSelectedDumpInfo();
String fileName = dumpinfo.getDate() + dumpinfo.getTime() + dumpinfo.getSeqNo() + dumpinfo.getType() + dumpinfo.getTape() + dumpinfo.getDescription() + ".txt";
if (checkFileExistsInWin(fileName)) {
postProcessedDump.setDumpnotescontent(getFileContentsFromWin(fileName));
String consolidateDumpnotes = getFileContentsFromWin(fileName);
String lines[];
String content = "";
lines = consolidateDumpnotes.split("\\r?\\n");
List<String> finallines = new ArrayList<>();
int k = 0;
for (int i = 0; i < lines.length; i++) {
if (!lines[i].equalsIgnoreCase("")) {
finallines.add(lines[i]);
k++;
}
}
for (int j = 0; j < finallines.size(); j++) {
if (finallines.get(j).startsWith("---------------------SAVED BY")) {
PostProcessedDump dump = new PostProcessedDump();
dump.setDumpMessage(content);
content = "";
FinalDumpNotes.add(dump);
} else {
content = content + finallines.get(j);
}
}
}
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("postProcessedDump", postProcessedDump);
return FinalDumpNotes;
}
I get the following error:
If you want to add instances of type PostProcessedDump to your List you should change it's type. Also, don't forget to initialize it. Something like,
List<PostProcessedDump> FinalDumpNotes = new ArrayList<>();
Also, Java naming convention is to start variable names with a lower case letter. FinalDumpNotes looks like a class, I would suggest something like
List<PostProcessedDump> processedList = new ArrayList<>();
Problems with your code:
List<DumpController> FinalDumpNotes;
You declare FinalDumpNotes to be a List of DumpController objects, but you never initialize it. In addition, your IDE is barfing on the following line of code:
FinalDumpNotes.add(dump);
because you are attempting to add a PostProcessedDump object to the List instead of a DumpController object.
For starters, you need to initialize your list like this:
List<DumpController> finalDumpNotes = new ArrayList<DumpController>();
Notice that I have made the variable name beginning with lower case, which is the convention (upper case is normally reserved for classes and interfaces).
I will leave it to you as a homework assignment to sort out the correct usage of this List.