everything works fine when creating a room and automatch too, but the problem is when i call p.getDisplayName(), in this code it dosn't return the opponent name it returns some junk letters ..
void updatePeerScoresDisplay() {
((TextView) findViewById(R.id.score0)).setText(formatScore(mScore) + " - Me");
int[] arr = {
R.id.score1, R.id.score2, R.id.score3
};
int i = 0;
if (mRoomId != null) {
for (Participant p : mParticipants) {
String pid = p.getParticipantId();
if (pid.equals(mMyId))
continue;
if (p.getStatus() != Participant.STATUS_JOINED)
continue;
int score = mParticipantScore.containsKey(pid) ? mParticipantScore.get(pid) : 0;
((TextView) findViewById(arr[i])).setText(formatScore(score) + " - "+
p.getDisplayName());
++i;
}
}
It returns something like Player234, it won't return the player's name, even if he/she is in your circles (as I have experienced). That's the point of a random opponent match.
google play game realtime multiplayer how to get quickmatch player's name?
Related
I'm getting errors when trying to get a player's scores across all leaderboards, in order to store locally.
My Android game is designed to be played offline, so I store high score and lifetime scores locally for each game mode.
Now I am working on adding leaderboards to my game. During the game play, I periodically post these scores to the leaderboards. So far so good.
Naturally, I need to cover the scenario where a user either uninstalls my game or moves to a new device, etc. In that scenario, when they sign in again to Google, I need to update the scores that are on leaderboards back into my local version.
Here's where I seem to get 26504 - NETWORK_ERROR_NO_DATA when I make the 4th call.
I have tried to wait until the 3rd call is complete and then fire the 4th one but I still get the same error. So I haven't even been able to add code for the 5-6 additional scores I will still need to retrieve.
getScoresFromLeaderboards(GAME_MODE_FIXED_QUESTIONS, SCORE_HIGH);
getScoresFromLeaderboards(GAME_MODE_FIXED_QUESTIONS, SCORE_LIFETIME);
getScoresFromLeaderboards(GAME_MODE_RAPID_FIRE, SCORE_HIGH);
getScoresFromLeaderboards(GAME_MODE_RAPID_FIRE, SCORE_LIFETIME);
Then...
public long getScoresFromLeaderboards(final String gameMode, final String scoreType) {
final int scoreHigh = 0, scoreLifetime = 0;
String leaderboardID = getLeaderboardForGameMode(gameMode, scoreType);
mLeaderboardsClient.loadCurrentPlayerLeaderboardScore(leaderboardID, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC )
.addOnCompleteListener(new OnCompleteListener<AnnotatedData<LeaderboardScore>>() {
#Override
public void onComplete(#NonNull Task<AnnotatedData<LeaderboardScore>> task) {
if (task.isSuccessful()) {
AnnotatedData<LeaderboardScore> lbs = task.getResult();
long i = lbs.get().getRawScore();
// Do something to store the score locally
}
else{
Log.Error("Error", "Retrieval failed");
}
}
I would suggest another approach to using "loadCurrentPlayerLeaderboardScore" which has the 3 query limit
Use loadPlayerCenteredScores instead . Limit the scores to 1. The resultant buffer will return only the player score. You are now in the user quota of 500 requests instead of 3.
long limitResultsTo = 1;
String PlayerID = "-1"; // set this from playersClient.getCurrentPlayer() ->task-> getPlayerId()
String leaderboardID = getString(R.string.leaderboard_name); // or string of ID
Games.getLeaderboardsClient(this, GoogleSignIn.getLastSignedInAccount(this))
.loadPlayerCenteredScores(leaderboardName, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, limitResultsTo)
.addOnSuccessListener(new OnSuccessListener<AnnotatedData<LeaderboardsClient.LeaderboardScores>>() {
#Override
public void onSuccess(AnnotatedData<LeaderboardsClient.LeaderboardScores> leaderboardScoreAnnotatedData) { // big ups Danoli3.com for the fix for loadCurrentPlayerLeaderboardScore
LeaderboardsClient.LeaderboardScores scoresResult = leaderboardScoreAnnotatedData.get();
LeaderboardScore scoreResult = (scoresResult != null ? scoresResult.getScores().get(0) : null);
long score = 0;
if(scoreResult != null && scoreResult.getScoreHolder() != null &&
PlayerID.equals(scoreResult.getScoreHolder().getPlayerId())) // else if the player has 0 score it will retrieve top player
score = scoreResult.getRawScore();
// use the score in your own code here
// Log.i(TAG, "loadPlayerCenteredScores:" + leaderboardID + " score:" + score);
leaderboardScoreAnnotatedData = null;
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Failure:loadPlayerCenteredScores GPG:Leader:" + leaderboardID + " Ex:" + e.getMessage());
}
if (mRoomId != null) {
for (Participant p : mParticipants) {
String pid = p.getParticipantId();
String name = p.getDisplayName();
if (pid.equals(mMyId))
continue;
if (p.getStatus() != Participant.STATUS_JOINED)
continue;
int score = mParticipantScore.containsKey(name) ? mParticipantScore.get(name) : 0;
((TextView) findViewById(arr[i])).setText(formatScore(score) + " - " +
p.getDisplayName());
++i;
}
}
Here is the screenshot...
What I want is user's Name instead of the generated id.
full code on the link below.
https://github.com/playgameservices/android-basic-samples/blob/master/BasicSamples/ButtonClicker/src/main/java/com/google/example/games/bc/MainActivity.java
My requirement is to get top 5 scores from leaderboard and display it in my app.
There is a method loadTopScores but it shows the scores in its own UI i guess.
mGamesClint.loadTopScores(new OnLeaderboardScoresLoadedListener() {
public void onLeaderboardScoresLoaded(int arg0, LeaderboardBuffer arg1,
LeaderboardScoreBuffer arg2) {
// TODO Auto-generated method stub
}
}, LEADERBOARD_ID,LeaderboardVariant.TIME_SPAN_ALL_TIME , LeaderboardVariant.COLLECTION_PUBLIC, 5, true);
So is there any way I can get individual data like Name and score..?
Name 1 : Name of the top scorer 1
score 1 : score of the top scorer 1
Name 2 : Name of the top scorer 2
score 2 : score of the top scorer 2
......and so on
I just want name string and score integer so that I can use it in my game.
Please suggest me some ideas
You are on the right track in your example, you just need to extract the information once it is loaded. It is fairly confusing to get it working but I will point you to this answer of mine, which shows how to do it for achievements - doing it for leaderboards works the same way, except that you will use the leaderboard interfaces instead of those used for achievements.
Basically, you will access arg2 to get the data, and it should look something like this:
mGamesClint.loadTopScores(new OnLeaderboardScoresLoadedListener() {
public void onLeaderboardScoresLoaded(int arg0, LeaderboardBuffer arg1, LeaderboardScoreBuffer arg2) {
// iterate through the list of returned scores for the leaderboard
int size = arg2.getCount();
for ( int i = 0; i < size; i++ ) {
LeaderboardScore lbs = arg2.get( i );
// access the leaderboard data
int rank = i + 1; // Rank/Position (#1..#2...#n)
String name = lbs.getScoreHolderDisplayName();
String scoreStr = lbs.getDisplayScore();
long score = lbs.getRawScore();
// now display or cache these values, or do whatever with them :)
}
arg2.close();
arg1.close();
}
}, LEADERBOARD_ID,LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, 5, true);
I did not actually test this implementation, but it should work (or at least show you enough so you can fix any mistakes I might have made).
Just remember that this will be done asynchronously, so the contents of the method will not execute immediately, but rather once the scores have been loaded.
Here is how I have achieved it.
PendingResult<Leaderboards.LoadScoresResult> topScores =
Games.Leaderboards.loadTopScores(getApiClient(),LEADERBOARD_ID,LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, 1, true);
topScores.setResultCallback(new ResultCallback<Leaderboards.LoadScoresResult>() {
#Override
public void onResult(LoadScoresResult scoreResults) {
if(scoreResults != null) {
if (scoreResults.getStatus().getStatusCode() == GamesStatusCodes.STATUS_OK) {
scoreStringBuilder = new StringBuilder();
LeaderboardScoreBuffer scoreBuffer = scoreResults.getScores();
Iterator<LeaderboardScore> it = scoreBuffer.iterator();
while(it.hasNext()){
LeaderboardScore temp = it.next();
Log.d("PlayGames", "player"+temp.getScoreHolderDisplayName()+" id:"+temp.getRawScore() + " Rank: "+temp.getRank());
scoreStringBuilder.append("|"+temp.getScoreHolderDisplayName()+"*"+temp.getRawScore());
}
UnityPlayer.UnitySendMessage(handlerName, "onGetScoreSucceededEventListener", "");
Log.d("PlayGames", "Call Sent for getHighScorewithPlayerNameSuccess ::: "+handlerName);
}
}
}});
You can use it as you want I created a String and returned it to Unity and then parsed it.
But this code is working with Latest Google Play Services.
Thanks
My Solution which worked is as follows which is for the latest game play services.
Games.Leaderboards.loadTopScores(mGamesClint,LEADERBOARD_ID, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, 5).setResultCallback(new ResultCallback<Leaderboards.LoadScoresResult>() {
public void onResult(LoadScoresResult arg0) {
// TODO Auto-generated method stub
int size = arg0.getScores().getCount();
for ( int i = 0; i < 3; i++ ) {
LeaderboardScore lbs = arg0.getScores().get(i);
String name = lbs.getScoreHolderDisplayName();
String score = lbs.getDisplayScore();
Uri urlimage = lbs.getScoreHolderHiResImageUri();
}
}
you can get all the data from leaderboard users here including high resolution image ie. profile picture.
Hope you get the idea here.
This code gets you the top 5 scores on your leaderboard.
private LeaderboardsClient mLeaderboardsClient;
mLeaderboardsClient.loadTopScores("HgkF9bOSF_UPAAILKE", LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC,5,true).addOnSuccessListener(new OnSuccessListener<AnnotatedData<LeaderboardsClient.LeaderboardScores>>() {
#Override
public void onSuccess(AnnotatedData<LeaderboardsClient.LeaderboardScores> leaderboardScoresAnnotatedData) {
LeaderboardScoreBuffer scoreBuffer = leaderboardScoresAnnotatedData.get().getScores();
Iterator<LeaderboardScore> it = scoreBuffer.iterator();
while(it.hasNext()){
LeaderboardScore temp = it.next();
Log.d("PlayGames", "player"+temp.getScoreHolderDisplayName()+" id:"+temp.getRawScore() + " Rank: "+temp.getRank());
}
}
});
My problem is I have around 1000+ records in an Android App
string field1;
string field2;
string field3;
string field4;
//...
I want to search in this set of records and get the best results on two fields (field1 and field2).
Currently I read each record and compare() (string compare) with the text i want to search so that takes a long time.
What is the best method to perform search?
Store each records in SQLite DB and do "select query where like"
Hash-Mapped
? any other suggestions?
Or may be create an Index of the records and do search.
If you want to search for not exact matches, I would try to make an ArrayList of MyAppRecord where
public class MyAppRecord {
private String record;
private int deviance;
}
and get for each record the deviance of the String you want to find with:
public static int getLevenshteinDistance (String s, String t) {
if (s == null || t == null) {
throw new IllegalArgumentException("Strings must not be null");
}
int n = s.length(); // length of s
int m = t.length(); // length of t
if (n == 0) {
return m;
} else if (m == 0) {
return n;
}
int p[] = new int[n+1]; //'previous' cost array, horizontally
int d[] = new int[n+1]; // cost array, horizontally
int _d[]; //placeholder to assist in swapping p and d
// indexes into strings s and t
int i; // iterates through s
int j; // iterates through t
char t_j; // jth character of t
int cost; // cost
for (i = 0; i<=n; i++) {
p[i] = i;
}
for (j = 1; j<=m; j++) {
t_j = t.charAt(j-1);
d[0] = j;
for (i=1; i<=n; i++) {
cost = s.charAt(i-1)==t_j ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left and up +cost
d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1), p[i-1]+cost);
}
// copy current distance counts to 'previous row' distance counts
_d = p;
p = d;
d = _d;
}
// our last action in the above loop was to switch d and p, so p now
// actually has the most recent cost counts
return p[n];
}
}
save it to your MyAppRecord-object and finally sort your ArrayList by the deviance of its MyAppRecord-objects.
Note that this could take some time, depending on your set of records. And NOTE that there is no way of telling wether dogA or dogB is on a certain position in your list by searching for dog.
Read up on the Levensthein distance to get a feeling on how it works. You may get the idea of sorting out strings that are possibly to long/short to get a distance that is okay for a threshold you may have.
It is also possible to copy "good enough" results to a different ArrayList.
I am working on simple audio media player. I am using media store to get information of all songs stored on the sdcard. So far So good. Everything is working fine.
But I am stuck now. How can I get last added (recently added) songs using media store?
Regards,
Niral
This is from the source of the Default Music Player in Android 2.3
private void playRecentlyAdded() {
// do a query for all songs added in the last X weeks
int X = MusicUtils.getIntPref(this, "numweeks", 2) * (3600 * 24 * 7);
final String[] ccols = new String[] { MediaStore.Audio.Media._ID};
String where = MediaStore.MediaColumns.DATE_ADDED + ">" + (System.currentTimeMillis() / 1000 - X);
Cursor cursor = MusicUtils.query(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
ccols, where, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
if (cursor == null) {
// Todo: show a message
return;
}
try {
int len = cursor.getCount();
long [] list = new long[len];
for (int i = 0; i < len; i++) {
cursor.moveToNext();
list[i] = cursor.getLong(0);
}
MusicUtils.playAll(this, list, 0);
} catch (SQLiteException ex) {
} finally {
cursor.close();
}
}
I'm not sure if this is what you are looking for, but when I looked up at the default android music player source, i found out that there is a "recently added" playlist in media store. Its id in MediaStore.Audio.Playlists is -1.
EDIT:
After further research, I found out that -1 is just a value to indicate that it does not exist on the Playlist table.
You may use the following solution instead:
Upon querying MediaStore.Audio.Media, add this to your where clause condition:
MediaStore.Audio.Media.DATE_ADDED + ">" + (System.currentTimeMillis() / 1000 - NUM_OF_DAYS);
NUM_OF_DAYS refers to how old your audio file is stored in your SD card.
Take Note: query from MediaStore.Audio.Media, not MediaStore.Audio.Playlist.
In your custom list that you maintain add one more integer field 'dateAdded' and to access that use
int dateAddedIndex = internalContentCursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED);
if (dateAddedIndex != -1) {
songs.setDateAdded(externalContentCursor.getInt(externalContentCursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED)));
}
After getting this sort the list according to the time they were added
public static List<Songs> getTopRecentAdded(List<Songs> list) {
Collections.sort(list, new Comparator<Songs>() {
#Override
public int compare(Songs left, Songs right) {
return left.getDateAdded() - right.getDateAdded();
}
});
Collections.reverse(list);
return list;
}
This will return the list which contain song at first which was added last.