sample code for google places api in android - java

can anyone please tell me how to use google places api in android. I am developing this application in eclipse where i need to find the nearest petrol stations and garages near my area. I went through numerous websites. i didnt find a proper answer. I need a sample code since i am new to json concepts.
public class place {
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
private static final boolean PRINT_AS_STRING = false;
public void performSearch() throws Exception {
try {
System.out.println("Perform Search ....");
System.out.println("-------------------");
HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
request.url.put("key", "api key");
request.url.put("location", lat + "," + lng);
request.url.put("radius", 500);
request.url.put("sensor", "false");
if (PRINT_AS_STRING) {
System.out.println(request.execute().parseAsString());
} else {
PlacesList places = request.execute().parseAs(PlacesList.class);
System.out.println("STATUS = " + places.status);
for (Place place : places.results) {
System.out.println(place);
}
}
} catch (HttpResponseException e) {
System.err.println(e.response.parseAsString());
throw e;
}
}//StoresNearMe

You can use Google API Java Client for Google Places API in Android . See my answer for a short snippet https://stackoverflow.com/a/12824796/1147466

Related

Here Android SDK - Navigate through "No_THROUGH_TRAFFIC" and "DIR_NO_TRUCKS" streets

A short and simple question someone hopefully has an awnser to:
How can I navigate with the Here Android SDK Premium through road elemts that have the attributes DIR_NO_CARS, NO_THROUGH_TRAFFIC, DIR_NO_TRUCKS in the TRUCK transport mode? Like I am a special car and I can drive on these roads.
My code looks like the following:
public class Scratch extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AndroidXMapFragment mapFragment = (AndroidXMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapfragment);
boolean success = com.here.android.mpa.common.MapSettings.setIsolatedDiskCacheRootPath(
getApplicationContext().getExternalFilesDir(null) + File.separator + ".here-maps",
"MainActivity");
System.out.println(success);
mapFragment.init(new OnEngineInitListener() {
#Override
public void onEngineInitializationCompleted(
OnEngineInitListener.Error error) {
if (error == OnEngineInitListener.Error.NONE) {
// now the map is ready to be used
Map map = mapFragment.getMap();
for (String sheme : map.getMapSchemes()) {
Log.d("Custom", sheme);
}
map.setMapScheme("pedestrian.day");
map.setMapDisplayLanguage(Locale.GERMANY);
//Show current position marker
PositioningManager.getInstance().start(PositioningManager.LocationMethod.GPS_NETWORK);
mapFragment.getPositionIndicator().setVisible(true);
//Routing
GeoCoordinate start = new GeoCoordinate(50.992189, 10.999966);
GeoCoordinate target = new GeoCoordinate(51.001224, 10.990920);
//Start - End marker for routing
MapLabeledMarker markerStart = new MapLabeledMarker(start)
.setLabelText(map.getMapDisplayLanguage(), "Start")
.setIcon(IconCategory.ALL);
markerStart.setZIndex(12);
map.addMapObject(markerStart);
MapLabeledMarker markerTarget = new MapLabeledMarker(target)
.setLabelText(map.getMapDisplayLanguage(), "End")
.setIcon(IconCategory.ALL);
markerTarget.setZIndex(12);
map.addMapObject(markerTarget);
CoreRouter router = new CoreRouter();
router.setDynamicPenalty(NewPenaltyForStreetArea(
router.getDynamicPenalty(),
new GeoCoordinate(51.001137, 10.989901),
new GeoCoordinate(50.992582, 10.999338),
map.getMapDisplayLanguage(),
"Im Geströdig",
DrivingDirection.DIR_BOTH,
70
));
RouteOptions routeOptions = new RouteOptions();
routeOptions.setTransportMode(RouteOptions.TransportMode.TRUCK);
routeOptions.setRouteType(RouteOptions.Type.FASTEST);
routeOptions.setCarpoolAllowed(false);
routeOptions.setCarShuttleTrainsAllowed(false);
routeOptions.setDirtRoadsAllowed(true);
routeOptions.setTruckLength(6.590f);
routeOptions.setTruckWidth(2.150f);
routeOptions.setTruckHeight(2.150f);
routeOptions.setTruckTrailersCount(0);
routeOptions.setTruckDifficultTurnsAllowed(true);
routeOptions.setRouteCount(2);
RoutePlan routePlan = new RoutePlan();
routePlan.setRouteOptions(routeOptions);
routePlan.addWaypoint(new RouteWaypoint(start));
routePlan.addWaypoint(new RouteWaypoint(target));
class RouteListener implements CoreRouter.Listener {
// Method defined in Listener
public void onProgress(int percentage) {
// Display a message indicating calculation progress
Log.d("Custom", percentage + "");
}
// Method defined in Listener
#Override
public void onCalculateRouteFinished(List<RouteResult> routeResult, RoutingError error) {
// If the route was calculated successfully
if (error == RoutingError.NONE) {
// Render the route on the map
Log.d("Custom", routeResult.size() + " Routes calculated");
for (RouteResult result : routeResult) {
MapRoute mapRoute = new MapRoute(result.getRoute());
mapRoute.setColor(Color.argb(100, 201, 42, 42));
mapRoute.setZIndex(10);
if (routeResult.indexOf(result) == 0) {
//Best route
mapRoute.setColor(Color.argb(255, 201, 42, 42));
mapRoute.setZIndex(11);
}
map.addMapObject(mapRoute);
}
}
else {
// Display a message indicating route calculation failure
}
}
}
router.calculateRoute(routePlan, new RouteListener());
} else {
System.out.println("ERROR: Cannot initialize AndroidXMapFragment");
System.out.println(error);
}
}
});
}
private DynamicPenalty NewPenaltyForStreetArea(DynamicPenalty dynamicPenalty, GeoCoordinate cord1, GeoCoordinate cord2, String marcCode, String streetName, DrivingDirection drivingDirection, int speed){
List<GeoCoordinate> penaltyArea = new ArrayList<>();
penaltyArea.add(cord1);
penaltyArea.add(cord2);
List<RoadElement> roadElements = RoadElement.getRoadElements(GeoBoundingBox.getBoundingBoxContainingGeoCoordinates(penaltyArea), marcCode);
for (int i = 0; i < roadElements.size(); i++) {
//Log.d("Custom", roadElements.get(i).getRoadName());
if (!roadElements.get(i).getRoadName().equals(streetName)){
roadElements.remove(i);
i--;
}
else
Log.d("Custom", roadElements.get(i).getAttributes().toString());
}
Log.d("Custom", "Set penalty for " + roadElements.size() + " road elements - " + streetName);
for (RoadElement road : roadElements) {
dynamicPenalty.addRoadPenalty(road, drivingDirection, speed);
}
return dynamicPenalty;
}
}
And this is what I get
But this is what I need
So I want to say the navigation API that the road "Im Geströdig" is accessible for my car.
Road Element Attributes I need to change somehow:
[DIR_NO_CARS, DIRT_ROAD, NO_THROUGH_TRAFFIC, DIR_NO_TRUCKS]
The solution to the use case is not trivial. The functionality of updating Road Element attributes is available via the HERE Custom Route API, where you would need to upload an overlay with a shape, that matches the road you want to modify. The attributes which can be updated are also limited. ("VEHICLE_TYPES":"49" indicates road is open for Cars, Truck, Pedestrian)
GET http://cre.api.here.com/2/overlays/upload.json
?map_name=OVERLAYBLOCKROAD
&overlay_spec=[{"op":"override","shape":[[50.10765,8.68774],[50.10914,8.68771]],"layer":"LINK_ATTRIBUTE_FCN","data":{"VEHICLE_TYPES":"49"}}]
&storage=readonly
&app_id={YOUR_APP_ID}
&app_code={YOUR_APP_CODE}
Make sure to use the same AppId, Appcode as being used with HERE Premium Mobile SDK.
Now this overlay can be used in HERE Premium Mobile SDK with FTCRRouter (still Beta feature)
FTCRRouter ftcrRoute = new FTCRRouter();
FTCRRouter.RequestParameters parmaters =new
FTCRRouter.RequestParameters(routePlan,"OVERLAYBLOCKROAD",true);
ftcrRoute.calculateRoute(parmaters, new FTCRRouter.Listener() {
#Override
public void onCalculateRouteFinished(List<FTCRRoute> list,
FTCRRouter.ErrorResponse errorResponse) {
if (errorResponse.getErrorCode() == RoutingError.NONE) {
List<GeoCoordinate> shape = list.get(0).getGeometry();
MapPolyline polyline = new MapPolyline();
polyline.setGeoPolyline(new GeoPolygon(shape));
polyline.setLineWidth(10);
m_map.addMapObject(polyline);
}else{
// Error
}
}
});
As the FTCRRouter is still in Beta, there are some limitation like Dynamic Penanlity is not supported and also the FTCRRouter always prefers to take the roads available in HERE Map data and uses the Roads from the overlay if necessary.

Google API returning the server location, not user location

Hello so I though I was getting user location through this code but im actually getting the server's location, any idea how can I change it so I get the user location?
public void geolocate() {
try {
GeolocationPayloadBuilder payloadBuilder = new GeolocationPayload.GeolocationPayloadBuilder();
GeolocationPayload payload = payloadBuilder.createGeolocationPayload();
//GeoApiContext context = new GeoApiContext.Builder().apiKey("my api key").build();
// I guess the payload needs to be build in a different way but no clue how it should be :/
GeolocationApiRequest req = (GeolocationApiRequest) GeolocationApi.geolocate(context, payload);
GeolocationResult res = req.await();
String location = res.location.toString();
String[] latLngArray = location.split(",");
com.google.maps.model.LatLng latLng = new com.google.maps.model.LatLng(Double.parseDouble(latLngArray[0]),
Double.parseDouble(latLngArray[1]));
GeocodingApiRequest geoReq = GeocodingApi.reverseGeocode(context, latLng);
GeocodingResult[] geoRes = geoReq.await();
// Setting the user location for view
System.out.println(geoRes[0].formattedAddress);
origen.setValue(geoRes[0].formattedAddress);
} catch (Exception e) {
System.out.println("Exception in NetClientGet:- " + e);
}
}
this is the dependency where im getting the objects from:
<dependency>
<groupId>com.google.maps</groupId>
<artifactId>google-maps-services</artifactId>
<version>0.9.3</version>
</dependency>
hope somebody can help me with this, thanks in advance
EDIT:
I have been searching and found out how to build the payload with help of https://developers.google.com/maps/documentation/geolocation/intro#cell_tower_object
But I have a couple of question which is how will I get my users mac address to create the wifiAccessPoint and also where do I find info of cell towers in my city (Cali, Colombia)? Just an update will keep searching any help is appreciated..
#POST
#Path("/geolocate")
public String geolocate() {
try {
CellTower newCellTower = new CellTower.CellTowerBuilder().CellId(42).LocationAreaCode(415)
.MobileCountryCode(310).MobileNetworkCode(410).Age(0).createCellTower();
WifiAccessPoint newWifiAccessPoint = new WifiAccessPoint.WifiAccessPointBuilder()
.MacAddress("00:25:9c:cf:1c:ac").createWifiAccessPoint();
WifiAccessPoint newWifiAccessPoint2 = new WifiAccessPoint.WifiAccessPointBuilder()
.MacAddress("00:25:9c:cf:1c:ad").createWifiAccessPoint();
GeolocationPayloadBuilder payloadBuilder = new GeolocationPayload.GeolocationPayloadBuilder()
.HomeMobileCountryCode(310).HomeMobileNetworkCode(410).RadioType("gsm").Carrier("Vodafone")
.ConsiderIp(false).AddCellTower(newCellTower).AddWifiAccessPoint(newWifiAccessPoint)
.AddWifiAccessPoint(newWifiAccessPoint2);
GeolocationPayload payload = payloadBuilder.createGeolocationPayload();
GeoApiContext context = new GeoApiContext.Builder().apiKey("my api key")
.build();
GeolocationApiRequest req = (GeolocationApiRequest) GeolocationApi.geolocate(context, payload);
GeolocationResult res = req.await();
String location = res.location.toString();
String[] latLngArray = location.split(",");
com.google.maps.model.LatLng latLng = new com.google.maps.model.LatLng(Double.parseDouble(latLngArray[0]),
Double.parseDouble(latLngArray[1]));
GeocodingApiRequest geoReq = GeocodingApi.reverseGeocode(context, latLng);
GeocodingResult[] geoRes = geoReq.await();
// Setting the user location for view
return geoRes[0].formattedAddress;
} catch (Exception e) {
System.out.println("Exception in NetClientGet:- " + e);
}
return "XD";
}
The Geolocation API of Google Maps Platform is not intended for getting user location, what I can suggest is that you use the HTML5 Geolocation instead, there's also a sample of that in the Google Maps Platform documentation. But please note that this is not supported by Google as this is using HTML5 Geolocation and not Google APIs, if you wish to get the address of the user location as well, you may Geocode the coordinates that will be returned by the HTML5 Geolocation. You may see the sample below (without the Geocoding function). Here's a working sample - https://jsfiddle.net/w2sad5pn/
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}

How to send a request using Telegram API

I'm learning to use the Telegram client api (not the bot api). I'm currently trying out simple things to try to understand how things work. I'm currently trying to retrieve information about a channel but not managing to.
From what I searched, there's very little documentation, examples and no tutorials. If you possibly know of tutorials, I would be very thankful if you shared them with me.
Method I'm using to retrieve info:
public static void printChatInfo(int chatId) {
try {
TLRequestChannelsGetChannels request = new TLRequestChannelsGetChannels();
TLIntVector ints = new TLIntVector();
ints.add(chatId);
request.setId(ints);
TLVector<TLAbsChat> chats = bot.getKernelComm().doRpcCallSync(request).getChats();
for (TLAbsChat chat : chats) {
System.out.println("*****************************" +
"\n*****************************" +
"\n*****************************" +
"\n*****************************" +
"\n*****************************");
System.out.println(chat.getId());
if (chat instanceof TLChat) {
TLChat chatCast = (TLChat) chat;
System.out.println(chatCast.getTitle());
} else {
System.out.println("NOT INSTANCE");
}
System.out.println("*****************************" +
"\n*****************************" +
"\n*****************************" +
"\n*****************************" +
"\n*****************************");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Where it's being called:
public void onTLMessage(TLMessage message) {
final TLAbsPeer absPeer = message.getToId();
System.out.println(message.getMessage());
Deepthought.printChatInfo(message.getChatId());
if (absPeer instanceof TLPeerUser) {
onTLMessageForUser(message);
} else {
BotLogger.severe(LOGTAG, "Unsupported Peer: " + absPeer.toString());
}
}
System.out.println(message.getMessage()); is working correctly.
The exceptions at TLVector<TLAbsChat> chats = bot.getKernelComm().doRpcCallSync(request).getChats();:
java.util.concurrent.ExecutionException: org.telegram.api.engine.RpcException: INPUT_CONSTRUCTOR_INVALID_04A42D7B
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.telegram.bot.kernel.KernelComm.doRpcCallSync(KernelComm.java:185)
at org.telegram.Deepthought.printChatInfo(Deepthought.java:97)
at org.telegram.plugins.echo.handlers.TLMessageHandler.onTLMessage(TLMessageHandler.java:30)
at org.telegram.plugins.echo.CustomUpdatesHandler.onTLMessage(CustomUpdatesHandler.java:98)
at org.telegram.plugins.echo.CustomUpdatesHandler.onTLAbsMessageCustom(CustomUpdatesHandler.java:74)
at org.telegram.plugins.echo.CustomUpdatesHandler.onTLUpdateNewMessageCustom(CustomUpdatesHandler.java:67)
at org.telegram.bot.handlers.UpdatesHandlerBase.onTLUpdateNewMessage(UpdatesHandlerBase.java:327)
at org.telegram.bot.handlers.UpdatesHandlerBase.processUpdate(UpdatesHandlerBase.java:122)
at org.telegram.bot.kernel.MainHandler$UpdateHandlerThread.run(MainHandler.java:305)
Caused by: org.telegram.api.engine.RpcException: INPUT_CONSTRUCTOR_INVALID_04A42D7B
at org.telegram.api.engine.TelegramApi$2.onError(TelegramApi.java:345)
at org.telegram.api.engine.TelegramApi$ProtoCallback.onRpcError(TelegramApi.java:851)
at org.telegram.mtproto.MTProto.onMTProtoMessage(MTProto.java:375)
at org.telegram.mtproto.MTProto.onMTMessage(MTProto.java:255)
at org.telegram.mtproto.MTProto.access$1300(MTProto.java:44)
at org.telegram.mtproto.MTProto$ResponseProcessor.run(MTProto.java:754)
java.lang.NullPointerException
at org.telegram.Deepthought.printChatInfo(Deepthought.java:97)
at org.telegram.plugins.echo.handlers.TLMessageHandler.onTLMessage(TLMessageHandler.java:30)
at org.telegram.plugins.echo.CustomUpdatesHandler.onTLMessage(CustomUpdatesHandler.java:98)
at org.telegram.plugins.echo.CustomUpdatesHandler.onTLAbsMessageCustom(CustomUpdatesHandler.java:74)
at org.telegram.plugins.echo.CustomUpdatesHandler.onTLUpdateNewMessageCustom(CustomUpdatesHandler.java:67)
at org.telegram.bot.handlers.UpdatesHandlerBase.onTLUpdateNewMessage(UpdatesHandlerBase.java:327)
at org.telegram.bot.handlers.UpdatesHandlerBase.processUpdate(UpdatesHandlerBase.java:122)
at org.telegram.bot.kernel.MainHandler$UpdateHandlerThread.run(MainHandler.java:305)
I appreciate any ideas that might solve or help solve this problem.
Thanks.

location is wrong on the map in iOS

I try to realize a small app in codename one for iOS. I show a Google map in a dialoge. I want to show my actual and real location on the embedded map. I m shown on the map near 0N 0E - somewhere in the ocean. Here s the code I m using:
private void putMeOnMap(MapComponent map) {
Location loc;
try {
loc = LocationManager.getLocationManager().getCurrentLocation();
lastLocation = new Coord(loc.getLatitude(), loc.getLongitude());
Image i = Image.createImage(10, 10, 0xff00ff00); //("/red_pin.png");
PointsLayer pl = new PointsLayer();
pl.setPointIcon(i);
PointLayer p = new PointLayer(lastLocation, "aktueller Standort", i);
p.setDisplayName(true);
pl.addPoint(p);
pl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
PointLayer p = (PointLayer) evt.getSource();
System.out.println("pressed " + p);
Dialog.show("Details", "Du bist hier" + "\n" + p.getLatitude() + "|" + p.getLongitude(), "Ok", null);
}
});
map.addLayer(pl);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thanks for help
You need to explicitly ask and accept Location tracking when utilizing it in an iOS app.
It will look something like this:
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
...
var shouldIAllow = false
switch status {
case CLAuthorizationStatus.Restricted:
locationStatus = "Restricted Access to location"
case CLAuthorizationStatus.Denied:
locationStatus = "User denied access to location"
case CLAuthorizationStatus.NotDetermined:
locationStatus = "Status not determined"
default:
locationStatus = "Allowed to location Access"
shouldIAllow = true
}
if (shouldIAllow == true) {
NSLog("Location to Allowed")
// Start location services
locationManager.startUpdatingLocation()
} else {
NSLog("Denied access: \(locationStatus)")
}
I suggest using native mapping which looks much better on the device and also highlights your location as an option.
You should also use getCurrentLocationSync() rather than getCurrentLocation(). Notice that you must define the build hint ios.locationUsageDescription as explained here.

Convenient way to extract data from the MtGox/PubNub JSON API?

I'm using the PubNub API with Java for pulling data from MtGox.
When retrieving data, the API delivers it in form of a JSONObject, which represents a tree structure of JSON data. Trying to extract bits of information directly from a JSONObject produces ugly code with lots of calls to getJSONObject(String), for which again exceptions might need to be handled.
Therefor, I'm looking for a convenient way to extract information from the JSONObject responses. So far, I've come across the possibility to convert the JSONObject into a POJO and then access the POJO. For conversion, I found the ObjectMapper from the Jackson library, which does a nice job here:
public void successCallback(String channel, Object message) {
JSONObject messageJson = (JSONObject) message;
ObjectMapper mapper = new ObjectMapper();
Message myMessage = mapper.readValue(messageJson.toString(), Message.class);
// do stuff with myMessage here
}
This approach has the disadvantage that I have to write my own POJO classes, e.g. the Message class in the above example, because I could not find these classes ready to use anywhere.
How to conveniently access the information stored in the JSONObject?
PubNub Java Class for MtGox JSON API
It's easy to create a ready made Java Class for ingesting the live feed provided by Mt.Gox This is a work-in-progress post to show you how to access the PubNub Data Feed from Mt.Gox as shown in the Dev Console live feed!
Official Bitcoin Wiki JSON Streaming API
We will be working from the Bitcoin wiki feed instructions provided by Bitcoin official Wiki: https://en.bitcoin.it/wiki/MtGox/API/Pubnub - continue reading below the screenshot to continue.
To see the live real-time data feed we will be using, please checkout the following two links:
Live Feed Trade Events (Buy/Sell Feed): https://www.pubnub.com/console?sub=sub-c-50d56e1e-2fd9-11e3-a041-02ee2ddab7fe&pub=demo&channel=dbf1dee9-4f2e-4a08-8cb7-748919a71b21&origin=pubsub.pubnub.com&ssl=true
Live Feed Ticker Updates (Price Changes): https://www.pubnub.com/console?sub=sub-c-50d56e1e-2fd9-11e3-a041-02ee2ddab7fe&pub=demo&channel=d5f06780-30a8-4a48-a2f8-7ed181b4a13f&origin=pubsub.pubnub.com&ssl=true
Trade Lag Example: https://www.mtgox.com/lag.html
PubNub Java SDK Docs
We will be using the PubNub Java SDK Docs
http://www.pubnub.com/docs/java/javase/overview/data-push.html
Specifically we'll be using the mtgox.subcribe(...) instance method to focus our efforts which looks like the following:
Download JAR or Source: https://github.com/pubnub/mtgox
import org.json.JSONObject;
import com.pubnub.mtgox.MtGox;
import com.pubnub.mtgox.MtGoxCallback;
public class PubnubMtGoxSample {
public static void main(String[] args) {
MtGox mtgx = new MtGox();
mtgx.subscribe("ticker.BTCUSD", new MtGoxCallback(){
#Override
public void callback(JSONObject data) {
try {
String channel_name = data.getString("channel_name");
String avg_value = data.getJSONObject("ticker").getJSONObject("avg").getString("value");
System.out.println(channel_name + " : " + avg_value);
} catch (Exception e) {}
}});
}
}
See Full MtGox Example with Java Source Code - https://github.com/pubnub/mtgox/blob/master/java/examples/PubnubMtGoxSample.java
To compile the example got to https://github.com/pubnub/mtgox/tree/master/java and run
javac -cp Pubnub-MtGox.jar:libs/json-20090211.jar examples/PubnubMtGoxSample.java
And then to RUN:
java -cp .:examples/:Pubnub-MtGox.jar:Pubnub-StandardEdition-3.5.6.jar:libs/json-20090211.jar:libs/bcprov-jdk15on-1.47.jar:libs/slf4j-api-1.7.5.jar:libs/slf4j-nop-1.7.5.jar PubnubMtGoxSample
The Concept
For me, the best solution was to convert the JSONObjects from the PubNub API to bean classes which I found in the MtGox module of the XChange library.
Admitted, this approach adds quite a bit of glue code as you can see at the end of this answer, but I think it's worth the trouble, because after the conversion, the code gets much simpler. E.g. for getting the rate and currency from the ticker at which BTC was last traded, you can simply write
ticker.getLast().getValue()
and
ticker.getLast().getCurrency()
How To Do It
The mtgox module of the XChange library is available as a maven artifact, which is very convenient. You only need to add this module as a dependency to your project and the project setup is done.
In the xchange-mtgox module, you will find the package com.xeiam.xchange.mtgox.v2.dto.marketdata with the two calsses MtGoxTrade and MtGoxTicker.
Converting from JSONObject to one of these classes is easy with the Jackson ObjectMapper. As an advantage, the Jackson library is automatically imported as a transitive dependency of the xchange-mtgox maven artifact. That means that if you're using maven, you don't even have to write a single line of code to add it to your project.
Below is a complete runnable Example. Most is standard code for using PubNub. The important bits are between the marks // BEGIN OF IMPORTANT PART and // END OF IMPORTANT PART.
public class PubNubMtGoxBeanExample {
private static final String MTGOXPUBNUB_SUBSCRIBE_KEY = "sub-c-50d56e1e-2fd9-11e3-a041-02ee2ddab7fe";
private static final String MTGOXPUBNUB_BTCEUR_CHANNEL = "0bb6da8b-f6c6-4ecf-8f0d-a544ad948c15";
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
static {
OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public static void main(String[] args) throws PubnubException {
Pubnub pubnub = new Pubnub("demo", MTGOXPUBNUB_SUBSCRIBE_KEY);
pubnub.subscribe(MTGOXPUBNUB_BTCEUR_CHANNEL, new Callback() {
#Override
public void successCallback(String channel, Object message) {
// BEGIN OF IMPORTANT PART
JSONObject messageJson = (JSONObject) message;
JSONObject tickerJson;
try {
tickerJson = messageJson.getJSONObject("ticker");
} catch (JSONException e) {
throw new RuntimeException(e);
}
MtGoxTicker ticker;
try {
// the following line is the most important, because it maps from the JSONObject to the MtGoxTicker class
ticker = OBJECT_MAPPER.readValue(tickerJson.toString(), MtGoxTicker.class);
} catch (JsonParseException e) {
throw new RuntimeException(e);
} catch (JsonMappingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
String currency = ticker.getLast().getCurrency();
BigDecimal value = ticker.getLast().getValue();
System.out.println(currency + " " + value);
// END OF IMPORTANT PART
}
#Override
public void connectCallback(String channel, Object message) {
System.out.println("connectCallback on channel:" + channel + " : " + message.getClass() + " : " + message.toString());
}
#Override
public void disconnectCallback(String channel, Object message) {
System.out.println("disconnectCallback on channel:" + channel + " : " + message.getClass() + " : " + message.toString());
}
#Override
public void reconnectCallback(String channel, Object message) {
System.out.println("reconnectCallback on channel:" + channel + " : " + message.getClass() + " : " + message.toString());
}
#Override
public void errorCallback(String channel, PubnubError error) {
System.out.println("errorCallback on channel " + channel + " : " + error.toString());
}
});
}
}
For clarity, I've removed the imports, which you can add back in with the appropriate hotkeys in most IDEs (it's Ctrl+Shift+O in Eclipse).
Morevoer, note that there is a performance penalty in this code, which can be avoided by following the answer to the question
How to efficiently map a org.json.JSONObject to a POJO?

Categories