I was looking for an example and alive code to transfer just a list of objects into Json string and vice versa.
It is not a secret, that Androids are often used as a communication devices between (in my case) PC with .NET and the Android device itself.
The very common operation is to send SMS messages to a group of subscribers, that's usually exists as a List of objects.. say..
class Man {
public string Number {get;set;}
public string Message {get;set;}
}
So, the List<Man> Men = new List<Man>();
is quite intuitive as the basic structure.
I can convert both ways in C#.NET
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public static void Main() {
List<Man> Men = new List<Man>();
// numbers are just random
Man m1 = new Man();
m1.Number = "+6149168158";
m1.Message = "Hello Bob from 1";
m1.UniqueCode = "0123";
m1.State = 0;
Man m2 = new Man();
m2.Number = "+6146146182";
m2.Message = "Hello Bob from 2";
m2.UniqueCode = "0125";
m2.State = 0;
Men.AddRange(new Man[] { m1, m2 });
string result = JsonConvert.SerializeObject(Men);
Console.WriteLine(result);
List<Man> men = JsonConvert.DeserializeObject<List<Man»(result);
foreach(Man m in men) Console.WriteLine(m.Message);
}
}
public class Man
{
public string Number{get;set;}
public string Message {get;set;}
public string UniqueCode {get;set;}
public int State {get;set;}
}
It works.. but the Android side.. just like a dark matter.. I am sure it exists, but I can't touch it..
So, please, whoever knows it, please, publish the Android part here, so the others would get nice and clear example for such a standard requirement.
(No Gson, Mason or some others.. only Android and only JSON..
Thank you..
It looks like you might not want to use the tools available( Gson, Mason or some others..)
You must manually implement your mapper class for every object:
Native tools for android are JSONArray,JSONObject;
In the following code I have provided an example of decoding
Ok, this is the Deserializator
public List<Man> DecodeFactor(String json) throws JSONException {
List<Man> list = null;
try
{
JSONArray headarrays=new JSONArray(json);
if(headarrays.length()>0)
{
list=new ArrayList<Man>();
for (int i = 0; i <headarrays.length() ; i++)
{
Man man=new Man();
JSONObject o = headarrays.getJSONObject(i);
man.Message = o.getString("Message");
man.Number = o.getString("Number");
man.UniqueCode = o.getString("UniqueCode");
man.State = o.getInt("State");
list.add(man);
}
}
}catch (Exception ee) { ee.printStackTrace(); }
return list;
}
Related
I was making an app and all of sudden I got error that code is too long :(
I didn't know about this restriction in Java and I have already added a lot of arrays.
So I can't go back and create a database.
If anyone knows how to convert this:
list = new ArrayList<DataObject>();
list.add(new DataObject("Aback", "پُٺ","Toward the back or rear; backward"));
list.add(new DataObject("Abacus", "انگ","A board, tray, or table, divided into perforated compartments, for holding cups, bottles, or the like; a kind of cupboard, buffet, or sideboard."));
into a String and call that string in that ArrayList?
You can convert array list to Json and store it in string.
And when you need back the data just reverse it...
Array to json below code
String mStringArray[] = { "String1", "String2" };
JSONArray mJSONArray = new.
JSONArray(Arrays.asList(mStringArray));
Or you can use the GSON library for the same.
http://code.google.com/p/google-gson/
just to give a vary basic idea , iterate through your list, get the string from your Object save it to xml.
for(DataObject dobject: objectList){
String someString = dobject.getYourString();
save(someString);
}
If you have a constructor class you can do something like this.
You want to create a model class
public class model {
String s1, s2, s3;
public model(String s1, String s2, String s3) {
this.s1 = s1;
this.s2 = s2;
this.s3 = s3;
}
public String getS1() {
return s1;
}
public String getS2() {
return s2;
}
public String getS3() {
return s3;
}
}
From there you can do something like the following.
List<model> modelList = new ArrayList<>();
modelList.add("1", "2", "3");
// ADD MORE
Then you can create a for loop.
for (int i = 0; i < modelList.size(); i++) {
System.out.println(modelList.get(i).getS1());
System.out.println(modelList.get(i).getS2());
System.out.println(modelList.get(i).getS3());
}
//THIS WILL PRINT OUT THE STRINGS IN THE MODEL
have fun
Trying to convert a Arraylist of strings into one big comma separated string.
However when I use the
String joined = TextUtils.join(", ", participants);
Debugger shows me size of 4 for participants however the joined value as "" therefore empty
private ArrayList<String> participants;
Not sure what is going wrong?
UPDATE:
List<String> list = new ArrayList<>();
list.add("Philip");
list.add("Paul Smith");
list.add("Raja");
list.add("Ez");
String s = TextUtils.join(", ", list);
This works when I have a list that I manually populate however below is how the code is working right now.
In the onCreate()
callApi(type);
String s = TextUtils.join(", ", participants);
getSupportActionBar().setTitle(s);
In callAPI():
JSONArray participantsR = sub.getJSONArray("referralParticipants");
Log.e("Participants length ", String.valueOf(participantsR.length()));
for (int i = 0; i < participantsR.length(); i++)
{
JSONObject object = participantsR.getJSONObject(i);
String firstname = (String) object.get("fullName");
participants.add(firstname);
Log.e("Times", String.valueOf(i));
}
I'm trying to reproduce your error and am unable to. Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp);
List<String> list = new ArrayList<>();
list.add("Philip Johnson");
list.add("Paul Smith");
list.add("Raja P");
list.add("Ezhu Malai");
String s = TextUtils.join(", ", list);
Log.d(LOGTAG, s);
}
My output is Philip Johnson, Paul Smith, Raja P, Ezhu Malai as expected.
Are you importing the correct TextUtils class?
android.text.TextUtils;
Given the new information, here is my approach:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp);
callApi(type, new OnResponseListener<List<String>>() {
#Override public void onResponse(List<String> list) {
getSupportActionBar().setTitle(TextUtils.join(", ", list));
}
});
}
I don't know what networking library you're using, but you may have to define OnResponseListener as an interface. It's very easy:
public interface OnResponseListener<T> {
public void onResponse(T response);
}
You will then need to modify your callApi function to take an instance of OnResponseListener> and call it's onResponse method after completing the call.
I would recommend looking into the Volley library, and reading the Android documentation about simple network calls.
I use StringUtils.join from Apache Common Utilities.
The code is super-simple just the way you wanted,
StringUtils.join(participants,", ");
Works flawlessly for me.
EDIT
As requested, here is the StringUtils.java file for those who just want to use this single utility class and not the entire library.
I don't know what TextUtils does. This will do it.
StringBuffer sb = new StringBuffer();
for (String x : participants) {
sb.append(x);
sb.append(", ");
}
return sb.toString();
Easy enough, just use that.
Try with kotlin
val commaSeperatedString = listOfStringColumn.joinToString { it ->
"\'${it.nameOfStringVariable}\'" }
// output: 'One', 'Two', 'Three', 'Four', 'Five'
I have created an Android app wherein the users can give reviews and comments the products. Is there a way to control users from writing bad words in the reviews and comments or is there any sdk available for doing that.
You have to create a class for the censor module, this is somewhat greedy in implementation.
public class WordFilter {
static String[] words = {"bad", "words"};
public static String censor(String input) {
StringBuilder s = new StringBuilder(input);
for (int i = 0; i < input.length(); i++) {
for (String word : words) {
try {
if (input.substring(i, word.length()+i).equalsIgnoreCase(word)) {
for (int j = i; j < i + word.length(); j++) {
s.setCharAt(j, '*');
}
}
} catch (Exception e) {
}
}
}
return s.toString();
}
public static void main(String[] args) {
System.out.println(censor("String with bad words"));
}
}
Do it server side if you're using php and If you're just trying to do a simple word filter, create a single long regexp with all of the banned phrases that you want to censor, and merely do a regex find/replace with it. A regex like:
$filterRegex = "(boogers|snot|poop|shucks|argh|fudgecicles)"
and run it on your input string using preg_match() to wholesale test for a hit,
or preg_replace() to blank them out.
Currently working on an app that takes results from a search, parses the JSON object returned, and then adds the resulting pieces into a few ArrayLists within a class created called VenueList.
Here is the method that receives the results from the service and parses the JSON:
private static List<String> getResultsFromJson(String json) {
ArrayList<String> resultList = new ArrayList<String>();
try {
JSONObject resultsWrapper = (JSONObject) new JSONTokener(json).nextValue();
JSONArray results = resultsWrapper.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
resultList.add(result.getString("text"));
}
}
catch (JSONException e) {
Log.e(TAG, "Failed to parse JSON.", e);
}
return resultList;
}
What results of this becomes a List variable call mResults (to clarify: mResults = getResultsFromJson(restResult);. That is then used, among other places, in the following loop that puts the results into an ArrayAdapter that is used for displaying them in a ListFragment:
for (String result : mResults) {
VenueList.addVenue(result, "HELLO WORLD");
adapter.add(result);
}
I also add the result to a class called VenueList that manages the results and makes them accessible for multiple views. It essentially just holds multiple ArrayLists that hold different types of details for each venue returned in the search. The method I use to add a venue to VenueList is below (and you can see it used in the for loop above):
public static void addVenue(String name, String geo) {
venueNames.add(name);
venueGeos.add(geo);
}
I want the addVenue method to be able to take multiple arguments and update the VenueList class. Yet, when I call the addVenue method in the for loop, I can only pass it String result (from the parameters of the loop) and can't figure out how to pass it a second argument (which should also come from the JSON parsed by getResultsFromJson) so I've used "HELLO WORLD" as a placeholder for now.
I realize getResultsFromJson only has one list returned. I need to be able to take multiple elements from the JSON object that I parse, and then add them to VenueList in the right order.
So my questions are:
1) Given the getResultsFromJson method and the for loop, how can I use the addVenue() method as designed? How do I parse multiple elements from the JSON, and then add them to the VenueList at the same time? I plan on adding more arguments to it later on, but I assume if I can make it work with two, I can make it work with four or five.
2) If that's not possible, how should the getResultsFromJson, the for loop, and the addVenue method be redesigned to work properly together?
Please let me know if you need more detail or code - happy to provide. Thank you!
EDIT - Full VenueList class:
public class VenueList {
private static ArrayList<String> venueNames;
private static ArrayList<String> venueGeos;
public VenueList() {
venueNames = new ArrayList<String>();
venueGeos = new ArrayList<String>();
}
public static void addVenue(String name, String geo) {
venueNames.add(name);
venueGeos.add(geo);
}
public static String getVenueName(int position) {
return venueNames.get(position);
}
public static String getVenueGeo(int position) {
return venueGeos.get(position);
}
public static void clearList() {
venueNames.clear();
venueGeos.clear();
}
}
Clarification: I will have additional ArrayLists for each element of data that I want to store about a venue (phone number, address, etc etc)
1) I don't think methods getResultsFromJson(String json) and addVenue(String name, String geo) fit your needs.
2) I would consider rewriting method getResultsFromJson(String json) to something like this:
private static SortedMap<Integer, List<String>> getResultsFromJson(String json) {
Map<Integer, String> resultMap = new TreeMap<Integer, String>();
//...
return resultMap;
}
where the number of keys of your map should be equal to the number of objects you're extracting info, and each one of them will properly have their own list of items just in the right order you extract them.
With this approach you can certainly change your logic to something like this:
// grab your retuned map and get an entrySet, the just iterate trough it
SortedMap<Integer, String> result = returnedMap.entrySet();
for (Entry<Integer, String> result : entrySet) {
Integer key = result.getKey(); // use it if you need it
List<String> yourDesiredItems = result.getValue(); // explicitly shown to know how to get it
VenueList.addVenue(yourDesiredItems);
}
public static void addVenue(List<String> yourDesiredItems) {
// refactor here to iterate the items trough the list and save properly
//....
}
EDIT -- as you wish to avoid the go-between map i'm assuming you need nothing to return from the method
First i'm providing you with a solution to your requirements, then i'll provide you with some tips cause i see some things that could smplify your design.
To save VenueList things directly from getResultsFromJSON do something like this:
private static void getResultsFromJson(String json) {
try {
JSONObject resultsWrapper = (JSONObject) new JSONTokener(json).nextValue();
JSONArray results = resultsWrapper.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
//FOR EXAMPLE HERE IS WHERE YOU NEED TO EXTRACT INFO
String name = result.getString("name");
String geo = result.getString("geo");
// and then...
VenueList.addVenue(name, geo, ..., etc);
}
} catch (JSONException e) {
Log.e(TAG, "Failed to parse JSON.", e);
}
}
This implies that your addVenue method should know receive all params needed; as you can see this is just a way (that you can consider a workaround to your needs), however as i don't know all requirements that lead you to code this model, i will point to a few things you might consider:
1. If there's a reason for VenueList class to use everything static, consider doing this:
static{
venueNames = new ArrayList<String>();
venueGeos = new ArrayList<String>();
//....
}
private VenueList(){
}
This way you won't need to get an instance every time and also will avoid null pointer exceptions when doing VenueList.addVenue(...) without previous instantiation.
2. Instead of having an ArrayList for every characteristic in VenueList class consider defining a model object for a Venue like this:
public class Venue{
String name;
String geo;
//... etc
public Venue(){
}
// ... getters & setters
}
then if you need that VenueList class you will just have a list o Venue objects (List<Venue>), this means that instead of calling the method addVenue, you will first create a brand new instance of Venue class and will call the setter method of each characteristic, as an example of the refactored for loop from the workaround i provided you you'd be using something like this:
List<Venue> myListOfVenues = new ArrayList<Venue>();
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
// THIS WOULD REMAIN THE SAME TO EXTRACT INFO
String name = result.getString("name");
String geo = result.getString("geo");
// and then instead of calling VenueList.addVenue(name, geo, ..., etc)...
Venue v = new Venue();
v.setName(name);
v.setGeo(geo);
// ...etc
myListOfVenues.add(v);
}
// Once you're done, set that List to VenueList class
VenueList.setVenueList(myListOfVenues);
So VenueList class would now have a single property List<Venue> venueList; and would suffer minor tweeks on methods getVenueName, etc... and everything would be more readable... i hope this helps you to get another approach to solve your problem, if i still don't make my point let me know and i'll try to help you out...
I am a new developer on android application. I would like to get the ISO Country code when I pass the mobile number with country code. If I pass the mobile number as 1-319-491-6338, can I get country ISO code as US / USA in android?
I have written the code as follows:
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String countryCode = tm.getSimCountryIso();
String mobileno="1-319-491-6338";
Here, where can I pass the mobile number?
Can anybody please help me ?
Thanks in advance
You may not be able to query the country code programmatically via the standard API but you could include a table in your app. Such a table is easily found via Google (e.g. http://countrycode.org/).
Danger Will Robinson!: However, one should ask yourself what question you are trying to answer. Implicit in your question is that assumption that there is a one-to-one mapping between international dialling codes and ISO country codes. This is not true. For example, both the USA and Canada have the international dialling code '1'.
Perhaps think about re-structuring your app's interface. Allow the user to select a country to associate with the phone number but use the table from http://countrycode.org/ to order the most likely candidates at the top?
Had the same problem. Eventually I put all the data in excel and read the excel sheet.
Here is the implementation:
copy-past the country code table from http://countrycode.org/ to Microsoft Excel file.
Save the Excel file as 97-2003 compatible (.xls) in \res\raw\countrycode_org.xls
Download JExcelApi from here
Use the following class to read the file:
public class CountryCodes {
private HashMap mCountryByName = new HashMap();
private HashMap mCountryByCode = new HashMap();;
private ArrayList mCountries = new ArrayList();
public void addCountry(String countryName,String ISO_code,String countryCode){
countryCode = PhoneNumberUtil.normalizeDigitsOnly(countryCode);
Country country = new Country();
country.Name = countryName;
country.Code = countryCode;
country.ISO_code = ISO_code;
mCountryByName.put(countryName, country);
mCountryByCode.put(countryCode, country);
mCountries.add(country);
return;
}
public Country getCountryByCode(String countryCode){
countryCode = PhoneNumberUtil.normalizeDigitsOnly(countryCode);
return mCountryByCode.get(countryCode);
}
public Country getCountryByName(String countryName){
return mCountryByName.get(countryName);
}
public Country getCountryByIsoCode(String ISO_code){
ISO_code = ISO_code.toUpperCase();
for (Country country:mCountries){
String [] strArr = country.ISO_code.split("/| ");
for (String s:strArr){
if (ISO_code.equals(s))
return country;
}
}
return null;
}
public String[] getCountryNamesList(){
String[] res = new String [mCountries.size()];
int i=0;
for (Country c:mCountries){
res[i] = c.Name;
i++;
}
return res;
}
public void readCountryCodesFromExcelWorkbook()
{
Context context = GlobalData.getInstance().getApp();
Workbook mWorkbook;
InputStream myRawResource = context.getResources().openRawResource(R.raw.countrycode_org);
if (myRawResource == null)
Toast.makeText(context,"XML file not found",Toast.LENGTH_LONG).show();
else
try {
WorkbookSettings ws = new WorkbookSettings();
ws.setEncoding("Cp1252");
mWorkbook = Workbook.getWorkbook(myRawResource);
//ArrayList<String[]> currentSheet = new ArrayList<String[]>();
Sheet sheet = mWorkbook.getSheet(0);
int rowsNum = sheet.getRows();
for (int rowNum = 1; rowNum < rowsNum; rowNum++) {
//Log.d("RowNum", ""+rowNum);
int colsNum = sheet.getColumns();
String[] strArr = new String[colsNum];
boolean rowIsFull = true;
for (int colNum = 0; colNum < colsNum; colNum++) {
strArr[colNum] = sheet.getCell(colNum, rowNum).getContents();
if (strArr[colNum].length() == 0)
rowIsFull = false;
}
if (rowIsFull)
addCountry(strArr[0],strArr[1],strArr[2]);
}
} catch (BiffException e) {
Toast.makeText(context,"Error Reading xml file: BiffException",Toast.LENGTH_LONG).show();
e.printStackTrace();
return ;
} catch (IOException e) {
Toast.makeText(context,"Error Reading xml file: IOException",Toast.LENGTH_LONG).show();
e.printStackTrace();
return ;
}
}
public Country[] getCountries(){
return mCountries.toArray(new Country[0]);
}
public class Country {
public String Name;
public String Code;
public String ISO_code;
}
}
Step-1
You can get country calling code as well as its ISO name in the following URL
http://en.wikipedia.org/wiki/List_of_country_calling_codes
or
http://www.unc.edu/~rowlett/units/codes/country.htm
Step-2 You can get page source of that file using java program. You will get file in HTMl format
Step-3 you can convert those HTML files into XML format using any of available parsers. see Open Source HTML Parsers in Java
Step-4 Form the phone number you can get the calling code. Example if the number is "1-319-491-6338" then calling code is 1
Step-5 Match this calling code against the calling code and country name list that you have got from XML parser. In this way you can get iso country