LiveData<String>To Float Parse Replace - java

I'm using the Google purchase library and I'm using the price via a LiveData. Price tag: It looks like $20.99. I have to parse this data and print only 20.99. For this, I think I need to convert the LiveData String data to float or integer. How can I do that?
static public class SkuDetails {
final public String sku;
final public LiveData<String> title;
final public LiveData<String> description;
final public LiveData<String> price;
final public int iconDrawableId;
SkuDetails(#NonNull String sku, TrivialDriveRepository tdr) {
this.sku = sku;
title = tdr.getSkuTitle(sku);
description = tdr.getSkuDescription(sku);
price = tdr.getSkuPrice(sku);
iconDrawableId = skuToResourceIdMap.get(sku);
}
}
BillingClient;
public final LiveData<String> getSkuPrice(String sku) {
LiveData<SkuDetails> skuDetailsLiveData = skuDetailsLiveDataMap.get(sku);
assert skuDetailsLiveData != null;
return Transformations.map(skuDetailsLiveData, SkuDetails::getPrice);
}
EDIT: Sorry, I forgot to add the line of code that prints the price information correctly. I have shared the code I need to parse below.
public LiveData<String> getSkuPrice(Subscription var1) {
return getSkuDetails(var1.getSku()).price;
}
Activity.xml;
android:text="#{viewModel.getSkuPrice(subscription)}"

You can do something like this once you've price LiveData assigned.
// get the string value from "price" LiveData
String strPrice = price.getValue();
//remove dollar sign from this price
String priceWithoutDollarSign = strPrice.replaceAll("[^\\d.]", "");
//convert/parse it as float just in-case needed otherwise priceWithoutDollarSign will be enough
float resultPrice = Float.parseFloat(priceWithoutDollarSign);

Related

All my firebase field get automatically an underscore on front

My PoIs class:
public class PoIs {
private Integer location_id;
private String location_name;
private String location_address;
public PoIs() {}
public PoIs(Integer location_id, String location_name, String location_address) {
this();
this.location_id = location_id;
this.category_id = category_id;
this.location_name = location_name;
this.location_address = location_address;
}
public Integer get_location_id() {
return location_id;
}
public void set_location_id(Integer location_id) {
this.location_id = location_id;
}
public String get_location_name() {
return location_name;
}
public void set_location_name(String location_name) {
this.location_name = location_name;
}
public String get_location_address() {
return location_address;
}
public void set_location_address(String location_address) {
this.location_address = location_address;
}
I populate PoIs with informatision from a sqlite database:
final PoIs p = new PoIs(Integer.parseInt(row.get(0).toString()), row.get(1).toString(), row.get(2).toString());
and at a moment intend to save them on a firabase database:
FIREBASE_REFERENCE.child("PoI_"+ p.get_location_id()).setValue(p)
.addOnCompleteListener(t -> {
final boolean isSuccessful = t.isSuccessful();
final String msg = !isSuccessful
? getResources().getString(R.string.fb_error)
: getResources().getString(R.string.fb_success);
});
All work perfect except that my firebase fields start with an underscore. Instead location_id, location_name, location_address I have _location_id, _location_name, _location_address. I can't understand why this happening. Any ideea how to resolve this issue?
Firebase uses JavaBean naming conventions when mapping from properties in your code to properties in the database. In that convention a method like get_location_name is the getter for a property called _location_name.
If you want the property in the database to be location_name, that'd be a getter getLocation_name. Alternatively, you can use a #PropertyName("location_name")) annotation on all accessors (so the getter/setter function and/or the public field) to indicate the explicit property name you want in the database.

Hibernate One-To-Many Mapping, printing mapped lists

I have used One-to-Many Mapping in my project. I have stored a list of clicks for every user.
But when I retrieve the list by calling getClicks() methodm Hibernate returns list in different format.
Something like this.
"[com.zednx.tech.persistence.Click#29df9a77]"
So I tried Reading Every value from the list and assign to a new List.
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
clicks.add(temp);
}
But when i print the items of new List it stills prints the same way.
I need to build a JSON from the resulting String of this list.
So if the list is returned in format, it wont help me.
I couldn't find anything regarding this except How to pretty print Hibernate query results?
I tried Arrays.ToString(Object o). But it doesn't work.
GSON builder part-
Gson gson = new GsonBuilder()
.registerTypeAdapter(Click.class, new MyTypeAdapter<Click>())
.create();
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
temp.setCom_to_recieve(c.getCom_to_recieve());
temp.setStore_name(c.getStore_name());
temp.setT_date(c.getT_date());
temp.setT_status(c.getT_status());
temp.setT_ticket(c.getT_ticket());
temp.setUid(c.getUid());
System.out.println(c.toString());
clicks.add(temp);
}
String json = gson.toJson(clicks, Click.class);
Click.java
#Entity
#Table(name="click")
public class Click {
#Id
#Column(name="t_ticket")
private String t_ticket;
#Column(name="uid",nullable=false)
private long uid;
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
#ManyToOne
#JoinColumn(name="uid",
insertable=false, updatable=false,
nullable=false)
private Earning earning;
#Column(name="store_name")
private String store_name;
#Column(name="t_status")
private String t_status;
#Column(name="aff_source")
private String aff_source;
#Column(name="com_to_recieve")
private float com_to_recieve;
#Column(name="t_date")
private Date t_date;
#Column(name="cb_to_award")
private float cb_to_award;
#Column(name="cb_type")
private String cb_type;
public String getT_ticket() {
return t_ticket;
}
public void setT_ticket(String t_ticket) {
this.t_ticket = t_ticket;
}
public Earning getEarning() {
return earning;
}
public void setEarning(Earning earning) {
this.earning = earning;
}
public String getStore_name() {
return store_name;
}
public void setStore_name(String store_name) {
this.store_name = store_name;
}
public String getT_status() {
return t_status;
}
public void setT_status(String t_status) {
this.t_status = t_status;
}
public String getAff_source() {
return aff_source;
}
public void setAff_source(String aff_source) {
this.aff_source = aff_source;
}
public float getCom_to_recieve() {
return com_to_recieve;
}
public void setCom_to_recieve(float com_to_recieve) {
this.com_to_recieve = com_to_recieve;
}
public Date getT_date() {
return t_date;
}
public void setT_date(Date t_date) {
this.t_date = t_date;
}
public float getCb_to_award() {
return cb_to_award;
}
public void setCb_to_award(float cb_to_award) {
this.cb_to_award = cb_to_award;
}
public String getCb_type() {
return cb_type;
}
public void setCb_type(String cb_type) {
this.cb_type = cb_type;
}
Any Help is appreciated.
You need to implement a toString method, as your current Click class likely doesn't have one, so it just prints as the name of the class and instance identifier.
Okay, I could solve my problem finally.
I made another POJO without any annotations and Mapped the List items to that POJO class.
I think the problem was with Annotation of mapping on another class which I had in original POJO.
Also getString() method only helps in changing format of identifier. So basically it has nothing to do with JSON building unless you format getString() in form of JSON.
Hope it helps. If anyone wants new temp POJO I made I can post it if requested.
Thanks.

How to make a network call in Android without using an async call?

There is some gaps in android that I do not understand. There is a file I would like to make a network call in. I keep getting an error when I don't make a network call in either a activity or fragment.
public class Attraction {
public String name;
public String description;
public String longDescription;
public Uri imageUrl;
public Uri secondaryImageUrl;
public LatLng location;
public String city;
public Bitmap image;
public Bitmap secondaryImage;
public String distance;
public Attraction() {}
public Attraction(String name, String description, String longDescription, Uri imageUrl,
Uri secondaryImageUrl, LatLng location, String city) {
//I am looking to replace these variables with information from a website
this.name = "Hey";//name;
this.description = description;
this.longDescription = longDescription;
this.imageUrl = imageUrl;
this.secondaryImageUrl = secondaryImageUrl;
this.location = location;
this.city = city;
}
}
EVEN Better if I can make the network call here:
public class TouristAttractions extends Main2Activity{
public static final String CITY_SYDNEY = "Sydney";
public static final String TEST_CITY = CITY_SYDNEY;
private static final float TRIGGER_RADIUS = 2000; // 2KM
private static final int TRIGGER_TRANSITION = Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT;
private static final long EXPIRATION_DURATION = Geofence.NEVER_EXPIRE;
public static final Map<String, LatLng> CITY_LOCATIONS = new HashMap<String, LatLng>() {{
put(CITY_SYDNEY, new LatLng(-33.873651, 151.2068896));
}};
/**
* All photos used with permission under the Creative Commons Attribution-ShareAlike License.
*/
public static final HashMap<String, List<Attraction>> ATTRACTIONS =
new HashMap<String, List<Attraction>>() {{
//It would be perfect if I can make the network call here
put(CITY_SYDNEY, new ArrayList<Attraction>() {{
add(new Attraction(
"France",
"Lovely place",
"You should go",
Uri.parse("http://....png"),
Uri.parse("http://.....png"),
new LatLng(-33.858667, 151.214028),
CITY_SYDNEY
));
}});
}};
/**
* Creates a list of geofences based on the city locations
*/
public static List<Geofence> getGeofenceList() {
List<Geofence> geofenceList = new ArrayList<Geofence>();
for (String city : CITY_LOCATIONS.keySet()) {
LatLng cityLatLng = CITY_LOCATIONS.get(city);
geofenceList.add(new Geofence.Builder()
.setCircularRegion(cityLatLng.latitude, cityLatLng.longitude, TRIGGER_RADIUS)
.setRequestId(city)
.setTransitionTypes(TRIGGER_TRANSITION)
.setExpirationDuration(EXPIRATION_DURATION)
.build());
}
return geofenceList;
}
public static String getClosestCity(LatLng curLatLng) {
if (curLatLng == null) {
// If location is unknown return test city so some data is shown
return TEST_CITY;
}
double minDistance = 0;
String closestCity = null;
for (Map.Entry<String, LatLng> entry: CITY_LOCATIONS.entrySet()) {
double distance = SphericalUtil.computeDistanceBetween(curLatLng, entry.getValue());
if (minDistance == 0 || distance < minDistance) {
minDistance = distance;
closestCity = entry.getKey();
}
}
return closestCity;
}
}
Simply, you cannot make network operations on UI thread. Why would you like to do it anyway? Network call will block UI message loop - possibly for serveral seconds - this will quickly cause ANR error. There are various APIs that make network operations very easy, ie. OkHTTP.
//It would be perfect if I can make the network call here
then you will have to split this part in async operation, this will require restructuring your code - there is no way around.

How to remove a value from a hashmap?

The thing is, I have an ExpandableListView with 2 groups, inside of each group I have some users and when I click on these users I get their ids and add to a HashMap of strings, now I'm trying to remove these ids when I click on them for the second time, but the ids of the second group are not being deleted. here is what I'm trying to do:
aMap = new HashMap < String, GPSEscolas > ();
TextView idAluno = (TextView) v.findViewById(R.id.idcrianca);
TextView idEscola = (TextView) v.findViewById(R.id.idescola);
IdEscola = String.valueOf(idEscola.getText());
IdAluno = String.valueOf(idAluno.getText());
mGpsEscolas = aMap.get(IdEscola);
if (mGpsEscolas == null) {
mGpsEscolas = new GPSEscolas();
aMap.put(IdEscola, mGpsEscolas);
mGpsEscolas.getIds_alunos().add(String.valueOf(IdAluno));
mGpsEscolas.setAlunos(IdAluno);
} else {
Set < String > ia = mGpsEscolas.getIds_alunos();
if (!ia.contains(IdAluno)) {
ia.add(String.valueOf(IdAluno));
} else {
alunos = aMap.get(IdEscola).getAlunos();
ia.remove(IdAluno);
aMap.remove(alunos);
}
stringArray = new String[ia.size()];
out = "";
if (ia.size() > 0) {
for (String str: ia.toArray(stringArray)) {
out += ";" + str;
}
aMap.get(IdEscola).setAlunos(out.substring(1));
}
}
MOdel:
public class GPSEscolas implements Serializable{
private static final long serialVersionUID = 1L;
private Integer id_escola;
private Set<String> ids_alunos = new TreeSet<String>();
private String Alunos;
private double distancia;
private Float latitude;
private Float longitude;
public String getAlunos() {
return Alunos;
}
public void setAlunos(String alunos) {
Alunos = alunos;
}
public Integer getId_escola() {
return id_escola;
}
public void setId_escola(Integer id_escola) {
this.id_escola = id_escola;
}
public Set<String> getIds_alunos() {
return ids_alunos;
}
public void setIds_alunos(Set<String> ids_alunos) {
this.ids_alunos = ids_alunos;
}
public double getDistancia() {
return distancia;
}
public void setDistancia(double distancia) {
this.distancia = distancia;
}
public Float getLatitude() {
return latitude;
}
public void setLatitude(Float latitude) {
this.latitude = latitude;
}
public Float getLongitude() {
return longitude;
}
public void setLongitude(Float longitude) {
this.longitude = longitude;
}
}
I assume you are referring to this line:
aMap.remove(alunos);
... which is the only place where you are trying to remove from a HashMap.
If that's the case, the problem is that you are not passing the right parameter value to aMap.remove(). That method expects you to pass a key value, such as whatever IdEscola is, which is the key value you used to do a put in the HashMap.
But instead, you are passing in alunos, which I can't quite be sure what that is, but it looks like a list of students.
So I think that what you wanted to do was to simply do aMap.remove(IdEscola).
EDIT: I now realize that your hashmap is keyed by school, so I changed my answer.
EDIT 2: And if the above is not what you want, then you probably don't want to remove anything from that HashMap.
If your key objects are different while putting(aMap.put(IdEscola, mGpsEscolas)) and getting (aMap.get(IdEscola).getAlunos()) are two different objects then hashmap will return null even when they are logically same values.
Read about object class in java and it's equals() and hashcode() functions , hashmap class uses it.
Student A= new Student ("ram");
Student B= new Student ("ram");
map.put(A,"10");
map.get(B) will return null.
If you use object A as a key to put some element in map then you cant use object B to retrieve it , even when they are logically same .

Questions about enum

If I have a Object
public class Genre {
private int id;
private int name;
}
And the id and name were been determined in advance, for example
if (id == 1)
name = "action";
else if (id == 2)
name = "horror";
My problem is how to create these two methods well
Genre.getName(1); // return "action";
Genre.getId("action"); // return 1;
I thought maybe I can use enum, like
public enum Genre {
ACTION(1), HORROR(2);
private final int id;
private final String name;
private Genre(int id) {
this.id = id;
this.name = getName(id);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public static String getName(int i) {
switch(i) {
case 1 : return "action";
case 2: return "horror";
default :
return null;
}
}
}
But in this way, I have no idea how to
Genre.getId("action"); // return 1;
And im afraid i use enum not correctly.
Could you give me some advice? Thanks!
---
At first, What I want to do this is in my case i want to use id or name to find the name or id like
int id = 1;
Genre.getName(id); // return "action"
or
String name = "action";
Genre.getId(name); // return 1
And now thanks for all the advices, I realize why I want to do is
int id = 1;
Genre.getGenre(id); // return Genre that id = 1 and the name = "action"
or
String name = "action";
Genre.getGenre(name); // return Genre that id = 1 and the name = "action"
If you insist on using an enum for this, you can just use the existing enum facilities. The solution below assumes the enum name and ordinal may be used in place of your name and id fields:
public enum Genre {
// ordinal 0, name = "ACTION"
ACTION,
// ordinal 1, name = "HORROR"
HORROR;
}
public static void main(String[] args) {
int horrorOrdinal = 1;
Genre horrorGenre = Genre.values()[horrorOrdinal];
String horrorName = horrorGenre.name();
String actionName = "ACTION";
Genre actionGenre = Genre.valueOf(actionName);
int actionOrdinal = actionGenre.ordinal();
System.out.println(String.format("%s=%s %s=%s", horrorName, horrorOrdinal, actionName, actionOrdinal));
}
Output:
HORROR=1 ACTION=0
Another suitable way would be to use a map for the lookup, like Michał Šrajer suggested:
private static Map<Integer, String> genres = new HashMap<Integer, String>();
public static void main(String[] args) {
initGenres();
int horrorOrdinal = 2;
String horrorName = genres.get(horrorOrdinal);
String actionName = "action";
int actionOrdinal = getGenreIdByName(actionName);
System.out.println(String.format("%s=%s %s=%s", horrorName, horrorOrdinal, actionName, actionOrdinal));
}
private static void initGenres() {
genres.put(1, "action");
genres.put(2, "horror");
}
private static int getGenreIdByName(String genreName) {
for (Entry<Integer, String> entry : genres.entrySet()) {
if (entry.getValue().equals(genreName)) {
return entry.getKey();
}
}
throw new IllegalArgumentException("Genre not found: " + genreName);
}
Output:
horror=2 action=1
Design considerations:
In this example I chose to use the (fast) map lookup for id->name and wrote a seperate method (getGenreIdByName) to do the reverse lookup name->id. You could reverse that, or use a second map to make both lookups fast (at the cost of needing to maintain an extra map).
I chose to store the id and name in the map. You could also use the Genre class itself as the map value. This would allow you to easily add extra fields (like 'description') later on.
If you need to represent you genres in different languages, you can use ResourceBundles to localize the output. Create a language file in your classpath root.
In file genres_nl.properties:
horror=heel eng
action=actie
Where the _nl suffix in the filename indicates the language.
Then in your code, in initGenres:
ResourceBundle genreNames = ResourceBundle.getBundle("genres", new Locale("nl");
And when getting the genre name:
String horrorName = genreNames.getString(genres.get(horrorOrdinal));
Note that getString can throw the runtime exception MissingResourceException if the bundle is not found. To avoid this, make sure you create a 'default' bundle with no suffix (so in this case a file named 'genres.properties') which is automatically used in case no bundle for the used Locale can be found.
Try the valueOf(...) method:
void String getId(String name) {
//names are upper case, so account for that
//handling non-existent names is an excersize for you
valueOf(name.toUpperCase()).getId();
}
Note that there are better methods (like Thilo suggested), but if you have a string only, you might use that.
Edit: another note:
In your getName(int i) method, you might want to return ACTION.name() etc. in order to be more refactoring safe and use the correct case.
You can get its ID by calling Genre.ACTION.getId();
This should do it:
Genre.ACTION.getId()
And if you need to do it at run-time:
Genre.valueOf("ACTION").getId()
ACTION(1, "action"), HORROR(2, "horror");
is a easy way to do it.
But if you are require to do it more often i would suggest you to create your own class and use MAP<-"-,-"-> as micheal said.
Edit:----
As you said the rarely gonna change use this way-->
public enum Genre {
ACTION(0, "action"), HORROR(1, "horror"), ROMANCE(2, "romance"), COMEDY(5, "comedy");
public final int id;
public final String name;
private Genre(int id, String name) {
this.id = id;
this.name = name;
};
public final static int length = Genre.values().length;
public static String[] getGenre() {
String[] genreList = new String[length];
int i = 0;
for (Genre attribute : Genre.values()) {
genreList[i++] = attribute.toString();
}
return genreList;
}
#Override
public String toString() {
return this.name;
}
}
Please remember use this as Genre.HORROR.id
also note that using this way is best as per your requirement.
Why don't you use the Enum Constructor with id and String:
public enum Genre {
ACTION(1, "action"), HORROR(2, "horror");
}
public enum Genre {
ACTION(1, "action"), HORROR(2, "horror");
private final int id;
private final String name;
private Genre(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
If you need to access particular element by it's name, you need to do it this way:
Genre.valueOf("ACTION").getId()
However, if you need to do it often, and in more dynamic way, I suggest to create regular class, and to keep all data in some Map<String, Movie> container.

Categories

Resources