Unreliable Google Awarness Weather API - android

I'm exploring the new Google Awareness API, more precisely the "get weather" one.
https://developers.google.com/awareness/android-api/snapshot-get-data#get_weather
Is several days that I'm testing, and I noticed two issues:
int[] getConditions() always return a single element condition, instead of "a 2-element int array" like the documentation report;
The condition is often very inaccurate.
Of course I tried with different locations around the world (mocking my location), comparing it with other weather services, and the results are the same.
Is that because they just release it? Or is it because I'm doing something wrong? This is my code:
Awareness.SnapshotApi.getWeather(client)
.setResultCallback(new ResultCallback<WeatherResult>() {
#Override
public void onResult(#NonNull WeatherResult weatherResult) {
// weatherResult.getWeather().getConditions() contains the weather condition
}
});

The public method summary says that getConditions() method of Weather (quoting verbatim) "Returns the current weather conditions as an array of values that best describe the current conditions."
In the link for getConditions(), the reference to 2-element array is just an example case for what would be returned if both conditions rainy and windy were applicable. In general it is an array that can contain one or more elements.
It is not clear from the question whether the issue reported is just for getConditions() or for other aspects of the weather such as temperature etc. If the other fields are accurate, it is less likely a problem with the update of the weather.

Related

Working with 'Associated' data in Firebase

I'm relatively new to Firebase Database, having used MySQL up until now. I know that there's no 'associated' data in Firebase as such, but I think I'm still trying to create it, because that's how my mind works! So, it may be that the problem I'm having is because my data is formatted badly - I'd appreciate any pointers.
In my app (using Android Studio), each user can have a number of Boxes. Each Box uses a single colour Palette (it can be the default one, or a user-defined one). A Palette consists of a number of Colours.
Currently, my data is like this:
Boxes
BoxKey1
name: Test Box
paletteKey: paletteKey1
belongsTo: userKey1
BoxKey2
... etc ...
Colours
ColourKey1
name: Red
hexCode: ff0000
ColourKey2
name: Blue
... etc ...
Palettes
PaletteKey1
name: default
colours
ColourKey1: true
ColourKey7: true
... etc ...
PaletteKey2
... etc ...
Users
UserKey1
name: Joe Bloggs
boxes
BoxKey1: true
BoxKey5: true
... etc ...
So, I can retrieve a list of the User's Boxes easily enough, and list all the names. If the User clicks on a name, then the Box with that name is retrieved and displayed. I also need to display the Palette used (the name and the Colours it contains).
In the Activity, I retrieve the Box as follows:
mBox.setKey(boxKey);
mBox.initialiseBox(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mBox = dataSnapshot.getValue(Box.class);
boxName.setText(mBox.getName()); // Show Box name
// AT THIS POINT I HAVE THE BOX DETAILS, BUT I NEED THE PALETTE DETAILS TOO
}
});
In the Box class, initialiseBox looks like this:
public void initialiseBox(ValueEventListener listener) {
if(this.key == null) return;
DatabaseReference mBoxReference = FirebaseDatabase.getInstance().getReference()
.child("boxes").child(this.key);
mBoxReference.addListenerForSingleValueEvent(listener);
}
That's working fine, but at this point I've only retrieved the Palette key from the database along with the other Box data. How do I then get the actual Palette, with all its Colours, so I can show those as well?
I've been trying to do a kind of 'nested listener' like this in the Main Activity:
mBox.initialiseBox(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Same as before
mBox = dataSnapshot.getValue(Box.class);
boxName.setText(mBox.getName()); // Show Box name
// Now add a new listener for the Palette
mPalette.setKey(mBox.getPaletteKey());
mPalette.initialisePalette(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mPalette = dataSnapshot.getValue(Palette.class);
paletteName.setText(mPalette.getName());
}
});
}
});
but it seems very unwieldy, and I can't quite get it to work (the Palette isn't getting populated, so at the paletteName.setText bit I'm getting an error).
Is this the correct approach to be taking? If not, what should I be doing? And if it's the right idea, can anyone see where I'm going wrong?
Related data in Firebase (and many other NoSQL databases) are almost as common as in SQL databases. The main differences are:
In Firebase the relation is not managed for you by the DBMS. This means that you need to write your own code (and possibly server-side security rules) to ensure ensure the relationship stay in-tact.
You often will duplicate some of the data in Firebase, which reduces the need for lookups. But this comes at the cost of needing to duplicate data during a write, and you'll need to consider strategies for keeping the duplicated data up to date.
What you're doing is called a client-side join and is indeed one valid way to get data from different top-level nodes into your app.
Whether it is the best approach to do this with a nested listener depends on the data and use-case. Things to consider here:
If the target list is short, you might simply want to preload the entire list and remove the need for nested joins.
What do you need from the joined item? If it's just a single property (e.g. the name of the palette), consider if it's worth it to duplicate that property under the source to remove the need for a nested join.
Nesting the code is going to rapidly become unreadable. Pull out the listener into a utility-class, and invoke it with a simpler interface.
i.e. you'll probably want to centralize the error handling, which you can perfectly do in the helper class. This leaves you with a single callback methods, which can be lambdafied in Java 8 - making it much easier to read.
I often recommend that you model the screens of your app in Firebase. So if your app has a list of user names, model a list of user names in your database. Right now you also nest the box IDs under that list, which means you'll end up loading the box IDs for all users, just to show their names.
I highly recommend reading NoSQL data modeling and watching Firebase for SQL developers.

SpeechRecognizer offline ERROR_NO_MATCH

SpeechRecognizer return ERROR_NO_MATCH in onResults when the device is offline while it's returning the partial results in onPartialResults() call back. The last time I played around with SpeechRecognizer it was working fine offline, I wonder if anyone has found a solution to it.
As a work around I use the partialResults returned in onPartialResults().
In the returned bundle "SpeechRecognizer.RESULTS_RECOGNITION" has all the terms minus the last term and "android.speech.extra.UNSTABLE_TEXT" has the last missing recognized term.
#Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> data = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
ArrayList<String> unstableData = partialResults.getStringArrayList("android.speech.extra.UNSTABLE_TEXT");
mResult = data.get(0) + unstableData.get(0);
}
To make the answer a little bit more clear, you need to enable partial results first, and to call UNSTABLE_TEXT in a specific fashion:
// When creating the intent, set the partial flag to true
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS,true);
// When requesting results in onPartialResults(), the UNSTABLE_TEXT parameter to getSTtringArrayList() must be in quotes
ArrayList<String> unstableMatches = partialResults.getStringArrayList("android.speech.extra.UNSTABLE_TEXT");
onPartialResults() gets called multiple times now and onError() still gets called with ERROR_NO_MATCH. I ended up using a solution similar to the one listed here: https://github.com/nenick/QuAcc/blob/master/app/src/main/java/de/nenick/quacc/speechrecognition/speech/RecognizerListenerWithOfflineWorkaround.java
In a nutshell:
Keep track of partial results and whether an error was shown
Reset both in onBeginningOfSpeech()
Store partial results in the variable when onPartialResults() gets called
When onError() gets called check if result is ERROR_NO_MATCH and combine SpeechRecognizer.RESULTS_RECOGNITION with "android.speech.extra.UNSTABLE_TEXT" into your partial results variable
Call onResults()

How to refer to a ParseObject before it has been issues an ObjectId (saved)?

A ParseObject only get's it's ObjectId once it's been saved. If I were offline at the time of creation and couldn't save the object, how can I refer to it whilst still being offline?
For instance how do I set a comment's postId when I don't yet know the
post's Id?
I was considering making a separate attribute called TempId in my extended ParseObject, which I can put an exclusively locally known Id that it can refer to until it has a proper Object Id, but is this the best choice I have?
The following concern me with this:
Double Handling
Maintaining all the callbacks necessary to make sure I update the correct object in the correct order.
Thanks!
Here's my rule of thumb: think objects, not objectIDs.
var post = // ... this is a real object, not an id. it can be new
var comment = // ... this is a real object, not an id. it can be new
// posts might have many comments by keeping an array of pointers called "comments"
post.add("comments", comment);
// or posts might have many comments by keeping a relation called "comments"
post.relation("comments").add(comment);
After doing this, the parent side of the relationship can be saved, and the unsaved children will be saved, too:
post.save().then(function(savedPost) {
// savedPost now has savedPost.id, but who cares?
// if comments is an array of pointers:
// savedPost.get("comments") now has comments with ids, but again, we don't need them.
// if comments is a relation:
return savedPost.get("comments").query.find();
}).then(function(comments) {
// comments is an array of objects with ids, but again, if I find
// myself needing those ids, its a clue that my design is weak
});

Turn Base Match , how to update all devicesafter every turn

I was so excited to hear about the turn-based match in the new google game services but at the same time a bit disappointed to not see the "flow" of turn based game especially cards games will have hard time to fit the design into the "expected flow" by google turn base. One of the issues I found and I really hope that I missunderstood it in the documentation is updating the game state
According to the documentation, if a user takes a turn (lets say throw a an Ace of Heart) then this will information will be rendered only on the device of the next player. Is there no way to update this information on all the participants devices at the same time? Otherwise the 6th player will have to wait for 5 turns before seeing a movement on his screen!
Any idea?
From the Saving Game State guide:
Call takeTurn() and pass in your game state data as the matchData parameter.
If the call is successful, Play Games services notifies other participants in the match about the update and makes the match data available on all participant devices.
Your game can then call getData() to retrieve the updated game state.
So it appears all participants get the updated state.
I know this thread is old but anyway I'll put my two cents.
If you want be notified whenever any participant in the match takes a turn, attach a OnTurnBasedMatchUpdateReceivedListener to your activity. Whenever the match is updated following a player's turn, your listener is notified via the onTurnBasedMatchedReceived() callback.
You can attach a OnTurnBasedMatchUpdateReceivedListener like this.
public class TurnBasedActivity extends BaseGameActivity implements OnTurnBasedMatchUpdateReceivedListener{
#Override
public void onSignInSucceeded() {
Games.TurnBasedMultiplayer.registerMatchUpdateListener(getApiClient(), this);
}
#Override
public void onTurnBasedMatchReceived(TurnBasedMatch match) {
Toast.makeText(this, "A match was updated.", TOAST_DELAY).show();
}
#Override
public void onTurnBasedMatchRemoved(String matchId) {
Toast.makeText(this, "A match was removed.", TOAST_DELAY).show();
}
}
}
I took the information from here https://developers.google.com/games/services/android/turnbasedMultiplayer#taking_the_first_turn
Hope it helps somebody else.

How to use Box2D sensor contact to increment an integer variable?

Firstly, thanks for your time.
How do I use Box2D Sensors on the EdgeShape(s) to determine a collision condition with the Ball, then use said condition to increment a score variable?
I am creating a Pong clone using Box2D via libGDX! I have found great examples and tutorials from iforce2d and Ray Wenderlich, however, they are written in languages and libraries that I am not familiar with at the moment. Trying to comprehend and convert the code is not working for me. If code or a link to a Java/libGDX rendition of Sensor use could be provided, I would be much obliged.
I am receiving contacts in my code, but I do not yet understand the recipe for the algorithm that would ignore contact with the paddle rectangles and arena boundary, but increment a score variable upon collision with the left or right EdgdeShape sensors.
I have scavenged the web for two weeks in an effort to find bits and pieces of useful information to hack together a solution before posting to SO, however, I am officially stumped on this one. I could use some guidance.
i don't know how far you came with your efforts and never worked with libgdx, but the way to go is something like this:
fixture.setUserData() (could be body) to recognize the single bodies you have (outLeft, outRight, paddleLeft, paddleRight, ball) - this could be any useful information from Integers to the whole game object instance, what ever you need
set your left/right boundaries as sensor fixture.setSensor(true) - afaik this has to be set to not let the boundaries induct a collision
implement your contact listeners endContact(Contact contact) (or begin contact, like you want it) call and request the fixtures A and B from the contact object with contact.getFixtureA/B() and determine if the given collision is relevant for your needs e.g.:
-
public void endContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Object userDataA = fixtureA.getBody().getUserData();
Object userDataB = fixtureB.getBody().getUserData();
// check if one is ball
if (userDataA instanceof Ball) {
checkBallCollision(userDataB);
} else if (userDataB instanceof Ball) {
checkBallCollision(userDataA);
}
}
private void checkBallCollision(Object userData) {
if (userData instanceof outLeft) {
//add points to right player
} else if (userData instanceof outRight) {
//add points to left player
}
}
-4. add your ContactListener to your World.setContactListener()
as said, i'm not 100% sure that this will work, never used it in libgdx, just some smaller experiments with andengines box2d extension, but in fact it should be the same for both engines. here is another link handling sensors in andengine: http://www.matim-dev.com/creating-sensors.html

Categories

Resources