When using the google maps API, for the admin area it gives you the long name and short name eg.
{
"long_name": "Victoria",
"short_name": "VIC",
"types": [
"administrative_area_level_1",
"political"
]
}
however when using android's native geocoder, I am only getting the long name (in this case "Victoria"). Is there a way to get the short name of an admin area in android, short of integrating the google maps geocoding API?
I'm gonna keep this short and simple, I have done my location implementation a little different. Since it took me a couple of hours to do this.
First I made a Map List to find the state name then convert it to the 2 letter code like so:
Map<String, String> states = new HashMap<>();
states.put("Alabama","AL");
states.put("Alaska","AK");
states.put("Alberta","AB");
states.put("American Samoa","AS");
states.put("Arizona","AZ");
states.put("Arkansas","AR");
states.put("Armed Forces (AE)","AE");
states.put("Armed Forces Americas","AA");
states.put("Armed Forces Pacific","AP");
states.put("British Columbia","BC");
states.put("California","CA");
states.put("Colorado","CO");
states.put("Connecticut","CT");
states.put("Delaware","DE");
states.put("District Of Columbia","DC");
states.put("Florida","FL");
states.put("Georgia","GA");
states.put("Guam","GU");
states.put("Hawaii","HI");
states.put("Idaho","ID");
states.put("Illinois","IL");
states.put("Indiana","IN");
states.put("Iowa","IA");
states.put("Kansas","KS");
states.put("Kentucky","KY");
states.put("Louisiana","LA");
states.put("Maine","ME");
states.put("Manitoba","MB");
states.put("Maryland","MD");
states.put("Massachusetts","MA");
states.put("Michigan","MI");
states.put("Minnesota","MN");
states.put("Mississippi","MS");
states.put("Missouri","MO");
states.put("Montana","MT");
states.put("Nebraska","NE");
states.put("Nevada","NV");
states.put("New Brunswick","NB");
states.put("New Hampshire","NH");
states.put("New Jersey","NJ");
states.put("New Mexico","NM");
states.put("New York","NY");
states.put("Newfoundland","NF");
states.put("North Carolina","NC");
states.put("North Dakota","ND");
states.put("Northwest Territories","NT");
states.put("Nova Scotia","NS");
states.put("Nunavut","NU");
states.put("Ohio","OH");
states.put("Oklahoma","OK");
states.put("Ontario","ON");
states.put("Oregon","OR");
states.put("Pennsylvania","PA");
states.put("Prince Edward Island","PE");
states.put("Puerto Rico","PR");
states.put("Quebec","PQ");
states.put("Rhode Island","RI");
states.put("Saskatchewan","SK");
states.put("South Carolina","SC");
states.put("South Dakota","SD");
states.put("Tennessee","TN");
states.put("Texas","TX");
states.put("Utah","UT");
states.put("Vermont","VT");
states.put("Virgin Islands","VI");
states.put("Virginia","VA");
states.put("Washington","WA");
states.put("West Virginia","WV");
states.put("Wisconsin","WI");
states.put("Wyoming","WY");
states.put("Yukon Territory","YT");
Then I appended it into the Location String result after doing all the hocus pocus to get the address like
Address address = addressList.get(0);
String state = states.get(address.getAdminArea());
result = address.getLocality() + ", " + state;
I hope you got this before I did, but I just decided to put this up for anyone else that needs it. I happened to be on this page when I fixed it.
NOTE: The Map(not really a Location Map) List has Canada "states" and some other places that use abbreviations.
After some searching , I found one solution for that
String url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + latitude + "," + longitude + "&sensor=true";
RequestQueue mVolleyQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
Log.i("response ", response);
JSONObject jsonObject = new JSONObject(response);
JSONArray arrayResult = jsonObject.getJSONArray("results");
JSONArray arrComponent = arrayResult.getJSONObject(0).getJSONArray("address_components");
for (int i = 0; i < arrComponent.length(); i++) {
JSONArray arrType = arrComponent.getJSONObject(i).getJSONArray("types");
for (int j = 0; j < arrType.length(); j++) {
if (arrType.getString(j).equals("administrative_area_level_1")) {
longname = arrComponent.getJSONObject(i).getString("long_name");
shortname = arrComponent.getJSONObject(i).getString("short_name");
Log.i("longname", longname);
Log.i("shortname", shortname);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
stringRequest.setShouldCache(false);
stringRequest.setTag("Volley");
mVolleyQueue.add(stringRequest);
Happy Codding :)
Related
I'm trying to stay connected with a url but I don't know how.
I'm working on a quiz app so I need to refresh the question every time that user lose or win.
but it takes long time to connect to the url every time.
so I just want to connected once and then just get new questions from that url.
I'm using volley library to connect to a url.
And This is my code.
public static void getQuestionsData(Activity activity,
OnDoneLintenter onDoneListener) {
String url = "https://opentdb.com/api.php?amount=15&type=multiple";
RequestQueue queue = VolleySingleton.getInstance().getRequestQueue();
JsonObjectRequest jsonObjectRequest =
new JsonObjectRequest(ColumnStructure.GET, url, null,
jsonObject -> {
try {
JSONArray array
= jsonObject.getJSONArray(ColumnStructure.COL_RESULTS);
for (int i = 0; i < array.length(); i++) {
setColumnStructureFields(array, i);
}
onDoneListener.onDone();
} catch (JSONException e) {
Log.e("Log", "there is not result : " + e.getMessage());
}
},
volleyError -> {
Log.e("Log", "volley error : " + volleyError.getMessage());
});
queue.add(jsonObjectRequest);
}
I use this code at the beginning and every time user lose or win.So is there any way to stay connected with the url or at least get the json faster.
I have been attempting to retrieve information from an online JSON Source using a URL. I initially got the information parsed to a TextView in Android, however I got ALL Information from the JSON. Below is a screenshot of what I am referring to.
Text View Showing All Data In Json
Essentially, What I want is to just show the Location, so in the above example, Oslo, in Norway in one Textview, then in another show the Current Moon Phase for that location, so - using the above example again, Waxing Crescent.
This is the JSON I am using.
{
"version": 2,
"locations": [{
"id": "187",
"geo": {
"name": "Oslo",
"country": {
"id": "no",
"name": "Norway"
},
"latitude": 59.913,
"longitude": 10.740
},
"astronomy": {
"objects": [{
"name": "moon",
"days": [{
"date": "2018-09-13",
"events": [],
"moonphase": "waxingcrescent"
}]
}]
}
}]
}
To parse the JSON to the Textview showing all the data I used the following.
JSONObject jo = new JSONObject(data);
JSONArray locations = jo.getJSONArray("locations");
for (int i = 0; i < locations.length(); ++i) {
JSONObject loc = locations.getJSONObject(0);
JSONObject geo = loc.getJSONObject("geo");
JSONObject country = geo.getJSONObject("country");
JSONObject astronomy = loc.getJSONObject("astronomy");
JSONObject objects = astronomy.getJSONArray("objects").getJSONObject(0);
JSONObject day = objects.getJSONArray("days").getJSONObject(0);
StringBuilder result = new StringBuilder();
String singleParsed = "Moon: "+ astronomy.getString("moonphase");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
MainActivity.fetcheddata.setText(this.data);
}
NOTE: A String is created in the For Loop, Called "Single Parsed", This is what I want to put on the screen, however - once I call that variable, nothing shows on the screen. It only shows when using:
MainActivity.fetcheddata.setText(this.data);
But Not with the following, I do actually receive an error saying "Cannot Resolve Symbol, singleParsed as well.
MainActivity.fetcheddata.setText(this.singleParsed);
After some research and previous questions on Stack, I believe GSON is the way to go to do what I wish, however I have no idea where to start, or how to do the task using GSON.
All help is appreciated.
JSON Information from URL through GSON
Simple answer - Look at using Retrofit, and find a tutorial on it, as well as Gson
However
You don't need Gson to fix your problem, and I suggest fixing the problem at hand rather than going down an unnecessary path.
First, singleParsed is a local variable within a loop. Therefore, this.singleParsed doesn't exist. Or if it does, you never set it.
Secondly, let's assume you only have one location, so you don't need a loop. Similar to how you accessed the other JSON arrays, just get the first array item.
Finally, you'll need to understand how AsyncTask works, but my general recommended solution is at How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
But, for this purpose, here is a simple example with AsyncTask<String, Void, String>
// protected String doInBackground(String... url) { // I assume you have this ??
// String data = parseJsonFrom(url[0]);
String singleParsed = "(none)";
try {
JSONObject jo = new JSONObject(data);
JSONObject firstLocationAstronomy = jo
.getJSONArray("locations").getJSONObject(0)
.getJSONObject("astronomy");
JSONObject firstDay = firstLocationAstronomy
.getJSONArray("objects").getJSONObject(0)
.getJSONArray("days").getJSONObject(0);
singleParsed = firstDay.getString("moonphase");
} catch (Exception e) { // TODO: catch a JSONParseException
}
return singleParsed; // This is returned to onPostExecute, don't store a variable elsewhere
}
Then in the MainActivity, wherever you make this task, and set the text
new MoonPhaseTask() {
#Override
protected void onPostExecute(String moonPhase) {
MainActivity.this.textView.setText("Phase: " + moonPhase);
}
}.execute("some url");
What I want is to just show the Location, so in the above example, Oslo, in Norway in one Textview, then in another show the Current Moon Phase for that location
You can change the AsyncTask to return you the entire JSONObject to the onPostExecute, and parse the JSON there if you really wanted. Just the networking pieces need to be off the UI thread... parsing is not computationally expensive.
I'm creating an android app and i have a relatively large amount of data (mostly in text form and as key->string pairs) that i want to display in my app.
The problem is i don't want to enter the data in my app's code,meaning feel each TextView manually with the associated data.i don't feel that to be right!
I want my app to read this data from a file(maybe a JSON?) and then associate each key-> string pair with the related TexView.
To be more clear, i need to read from a prepared text file and use that text inside my app, AND i want to do this offline,i dont want to use any webservic
How should i accomplish this? should i use a database or room?Then how should i feel the database manually without using insert codes inside the app?
Use Volley for JSON Parsing
private static final String url ="your url";
Create a method
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Please wait, while we load the data");
progressDialog.show();
*make a String or JSON request*
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
newurl, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("response", response.toString());
Log.i("updated Url",newurl);
progressDialog.dismiss();
*then move into the json and create JSON object or JSON Array to get their String values*
try {
JSONObject data = response.getJSONObject("data");
JSONArray onwardflights = data.getJSONArray("data_key");
for (int i = 0; i < onwardflights.length(); i++) {
JSONObject onwardFlightsChild = onwardflights.getJSONObject(i);
String arrival,deparutre,duration,flightno,grossamount,image,direct;
JSONObject object = onwardFlightsChild.getJSONObject("data_key");
Onwardflights onwardflights1 = new Onwardflights(
arrival = onwardFlightsChild.getString("data_key"),
deparutre = onwardFlightsChild.getString("data_key"),
duration = onwardFlightsChild.getString("data_key"),
flightno = onwardFlightsChild.getString("data_key"),
direct = onwardFlightsChild.getString("data_key"),
origin = onwardFlightsChild.getString("data_key"));
Log.i("Origin",origin);
Fare fare = new Fare(
grossamount = object.getString("data_key")
);
onwardflights1.setFare(fare);
suggestionmodel.add(onwardflights1);
}
*Create an instance of adapter and pass the parameters*
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(suggestionmodel,getApplicationContext());
recyclerView.setAdapter(recyclerAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("THIS", "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(jsonObjReq);
}
You could simply use a JSON file. Now, the question is: How do you ship a JSON file with your app so that it's available at Runtime? You can use any of these methods:
Put it in the directory res/raw/ and read it using the Resources class (it has a openRawResource() method)
Put it in the assets/ directory and read it in using the AssetManager class (it has a open() method that returns an InputStream)
I hope this helps... Merry coding!
I am using the Google Maps API and the Google Maps Directions API for tracking the journey of a pilgrimage. My travel mode is walking and I have 8 waypoints placed along the way (Google doesn't allow you to add more for free).
The problem is that Google Maps is taking an odd unsought detour from the original path. I set up LatLng coordinates as waypoints accordingly to fix the problem, but the API remains stubborn on its resolve to take me 200 km away from the path and back again...
I have attached a screenshot of the app with this question. As you can see, in the bottom right corner, Google Maps takes a detour. How do I fix the problem? Thank You.
Here's some code:
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=18.6769503," +
"73.8945701&destination=17.6774444,75.3329239&mode=walking&waypoints=" +
"via:Saswad,MH|via:Jejuri,MH|via:Natepute,MH|" +
"via:Velapur,MH|via:Bhandishegaon,MH|via:Wakhari,MH|" +
"via:17.685236,75.287492|via:17.682496,75.304931&" +
"key=MY_API_KEY";
RequestQueue requestQueue = Volley.newRequestQueue(this);
StringRequest jsonObjectRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("Json Data", "Successfully Retrieved - Starting Parse Process");
mapJsonData = response;
try {
parseJsonData(mapJsonData);
} catch (JSONException e) {
e.printStackTrace();
}
PolylineOptions polyOptions = new PolylineOptions().geodesic(true).
color(Color.RED).
width(10);
polyOptions.add(dnyaneshwarOrigin);
for (int i = 0; i < polyPoints.size(); i++) {
polyOptions.add(polyPoints.get(i));
}
polyOptions.add(vitthalMandir);
gMap.addPolyline(polyOptions);
final LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(dnyaneshwarOrigin);
builder.include(vitthalMandir);
mapLayout.getViewTreeObserver().addOnGlobalLayoutListener
(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
LatLngBounds bounds = builder.build();
gMap.animateCamera(CameraUpdateFactory.newLatLngBounds
(bounds, 20));
}
});
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Response Error", "Could Not Retrieve Json Data");
Toast.makeText(MapActivity.this, "Error Retrieving Json Data",
Toast.LENGTH_SHORT).show();
}
});
Log.i("Request Queue", "Sending Json Request");
requestQueue.add(jsonObjectRequest);
Fixed the Problem. There was an alternative place with the same name as one of my way-points. I changed the way-point in my URL from a name to specific Lat-Long Coordinates and that solved the problem for me.
I have a JSONString that came back successfully and I want to convert it into a JSONArray where I can parse the bits. The string came back successfully but when I try to log the "title" within each movie's object inside the "results" array, it's not coming up.
public List<MovieItem> fetchItems() {
List<MovieItem> items = new ArrayList<>();
try {
String url = Uri.parse("https://api.themoviedb.org/3/movie/popular")
.buildUpon()
.appendQueryParameter("api_key", API_KEY)
.build().toString();
String jsonString = getUrlString(url);
Log.i(TAG, "Received JSON: " + jsonString);
JSONObject jsonBody = new JSONObject(jsonString);
JSONArray photoJsonArray = jsonBody.getJSONArray("results");
for(int i = 0; i < photoJsonArray.length(); i++){
JSONObject jsonPart = photoJsonArray.getJSONObject(i);
Log.i("title", jsonPart.getString("title"));
}
} catch (IOException ioe) {
Log.e(TAG, "Failed to fetch items", ioe);
} catch (JSONException je) {
Log.e(TAG, "Failed to parse", je);
}
return items;
}
-
02-03 13:34:43.236 4728-4746/? I/MovieFetchr: Received JSON: {
"page":1,
"results":[
{
"poster_path":"\/oXUWEc5i3wYyFnL1Ycu8ppxxPvs.jpg",
"adult":false,
"overview":"In the 1820s, a frontiersman, Hugh Glass, sets out on a path of vengeance against those who left him for dead after a bear mauling.",
"release_date":"2015-12-25",
"genre_ids":[37,18,12,53],
"id":281957,
"original_title":"The Revenant",
"original_language":"en",
"title":"The Revenant",
"backdrop_path":"\/uETWtwsE1QjfoFqRQqFLnSjppPA.jpg",
"popularity":42.096309,
"vote_count":1079,
"video":false,
"vote_average":7.36
},
{
"poster_path":"\/kqjL17yufvn9OVLyXYpvtyrFfak.jpg",
"adult":false,
"overview":"An apocalyptic story set in the furthest reaches of our planet, in a stark desert landscape where humanity is broken, and most everyone is crazed fighting for the necessities of life. Within this world exist two rebels on the run who just might be able to restore order. There's Max, a man of action and a man of few words, who seeks peace of mind following the loss of his wife and child in the aftermath of the chaos. And Furiosa, a woman of action and a woman who believes her path to survival may be achieved if she can make it across the desert back to her childhood homeland.",
"release_date":"2015-05-13",
"genre_ids":[878,53,28,12],
"id":76341,
"original_title":"Mad Max: Fury Road",
"original_language":"en",
"title":"Mad Max: Fury Road",
"backdrop_path":"\/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg",
"popularity":32.157869,
"vote_count":3566,
"video":false,
"vote_average":7.5
},
try changing
Log.i("title", jsonPart.getString("title"));
to
Log.i(TAG, "Title: " + jsonPart.getString("title"));
and comment out the above log statement so it can be read easily