Getting started with Android

1. Requirements

2. Download the Geosophic SDK for Android

Download the latest version of the Geosophic SDK for Android here.

3. Set up Geosophic SDK for your project

Geosophic SDK for Android is distributed as a jar library.
  1. Start Eclipse in the workspace of your game.
  2. Add the Geosophic library jar file into the libs directory of your project. Now the library is included in the project build path. You can check it by clicking in the project name –> Build path –> Configure build path –> Libraries. If it is not there, you can add it manually by clicking in Add External JARs.
  3. Add the Google gson (last checked version: 2.2.4) and the Google Play Services libraries to the libs directory in the same way as the Geosophic library.
  4. Copy the content of the Geosophic assets folder into the assets folder of your project. Geosophic assets contains the following items:
    1. geosophic.properties: This file will store the setting values that identifies you into the Geosophic platform.
    2. geosophic_www folder: This folder contains resources needed by the SDK.
  1. Start Android Studio with your game’s project.
  2. Add the Geosophic library jar file into the libs directory of your android module. Go to File -> Project Structure to check the settings of your project. Go to Modules section, select your android module and go to the Dependencies tab. Add the Geosophic SDK jar to the module dependencies clicking on the ‘+’ button –> Jars or directories. 
  3. Add the Google gson (last checked version: 2.2.4) and the Google Play Services libraries to the libs directory in the same way as the Geosophic library.
  4. Configure the Gradle builder to compile the jars. Open the gradle.build file located in your android module. Add the following lines inside the dependencies section depending of the location of your jars:
    1. If you have all the jars located in the same directory: 
      dependencies {
          compile fileTree(dir: 'libs', include: '*.jar')
      }
    2. If you have the jars located in different places:
      dependencies {
          compile files('jar1_path.jar', 'jar2_path.jar', ...)
      }
  5. Copy the content of the Geosophic assets folder into the assets folder of your android module. The assets folder of your module is located on src/main/assets by default (In case that the assets folder doesn’t exists you have to create it).  Geosophic assets contains the following items:
    1. geosophic.properties: This file will store the setting values that identifies you into the Geosophic platform.
    2. geosophic_www folder: This folder contains resources needed by the SDK.

NOTE

When you add new libraries or jars into your project you have to rebuild it to be able to use these libraries. You can do it going to Build -> Rebuild project
Some times Android Studio doesn’t rebuild the project properly. You can detect it when your app starts to throw ClassNotFound exceptions in the log. There is another useful way to rebuild your project via console command. Open a console or terminal, go to your project path and type the command gradlew clean.

4. Connect your game to your Geosophic account

You will need to set up the connection settings for Geosophic in your project.

  1. Go to the Geosophic developer dashboard and browse to your game. Select “Settings” and keep at hand the values of the “Connection Settings” section.
  2. Fill the geosophicsdk.properties file like shown in the example but using your own configuration values.
consumerKey=YourConsumerKey
consumerSecret=YourConsumerSecret
clientId=YourClientId

5. Android specific configuration

Android permissions

Geosophic SDK uses some device permissions to get fully working.

  • Internet: To connect to the online services of Geosophic.
  • Network State: To check if there is no connection and keep the user scores for later.
  • Location: To use the location based leaderboards.

Enable this permissions editing your AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Include Geosophic’s webview activity

Add this activity to your AndroidManifest.xml file:

<activity android:name="com.geosophic.view.Geosophic_View"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@android:style/Theme.NoTitleBar">
</activity>

Include Geosophic’s tracking service

Add these services to your AndroidManifest.xml file:

<service android:name="org.openudid.Geosophic_OpenUDID_service">
  <intent-filter>
    <action android:name="org.openudid.GETUDID" />
  </intent-filter>
</service>

Extra analytics tracking

Extend all your activities from the Geosophic_Activity class. This activity gets the control of the Geosophic SDK lifecycle in the background so you can forget about it and use the SDK in an easy way.

public class MainActivity extends Geosophic_Activity {
...
}

NOTE

There are some third party libraries that also require your Activities to extend from a base activity. Java doesn’t allow multiple inheritance (one class extending several classes). To make both work you have to create a class inheritance tree that manages all the extensions. Here you have the link to the Geosophic_Activity class source code so you can create your classes tree.

6. Using Geosophic features in your game

Now you are ready to play. Follow this guide to perform most common tasks provided by the SDK. Geosophic_ServiceController is the main object you’ll need to use Geosophic features.

Before using Geosophic

It is a good practice to check if the Geosophic service is active before trying to use it:

if(Geosophic_ServiceController.isServiceActive()) {
   // myGeosophicSDK code
}

USE CASE: Post player scores or votes and view leaderboards

Check how our location based leaderboards work before you use them.

Submit a player score

To post a score you should call the method:

(Geosophic_ScoreResponse) postScore(int leaderboardSchema, int score)
leaderboardSchema: Identifier of the leaderboard you want to submit the score to. You can get this id in the “Settings” view of your game.
score: Value of the score.

This method returns a Geosophic_ScoreResponse object, containing the following information:

highScore: True if the score submitted is a new personal highscore.
leaderboardId: Id of the leaderboard where the score has been submitted.

It is a good practice to make this call asynchronously:

...
new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive())
        Geosophic_ServiceController.postScore(11, 100);
    } catch (Geosophic_BadRequestException e) {
      e.printStackTrace();
    } catch (Geosophic_ResponseFormatingErrorException e) {
      e.printStackTrace();
    } catch (Geosophic_HostNotReachableException e) {
      e.printStackTrace();
    }
    return null;
}.execute();
...

Display a leaderboard

There are two ways to get the contents of a leaderboard in a predefined HTML view.

(void) showLeaderboard(int leaderboardId, int leaderboardSchema)
(void) showLeaderboard(int leaderboardSchema)
leaderboardId: Identifier of the leaderboard you want to display. You get this id in the Geosophic_ScoreResponse object after calling “postScore”. The device’s nearest location is showed when you use the call without the leaderboardId parameter .
leaderboardSchema: Identifier of the leaderboardSchema you are using. You get this id in the “Settings” page of your game.

A sample call like

Geosophic_ServiceController.showLeaderboard(13)

will display the nearest leaderboard.

Submit a player vote

To post a vote you should call the method:

(Geosophic_VoteResponse) postVote(int leaderboardSchema, String vote)
leaderboardSchemaId: Identifier of the leaderboard you want to submit the vote to. You can get this id in the “Settings” view of your game.
vote: Value of the vote.

This method returns a Geosophic_VoteResponse object, containing the following information:

choice: The vote posted in the leaderboard.

firstCast: True if the player post his first vote, false in other case.

leaderboardSchema: Id of the leaderboard where the score has been submitted.

It is a good practice to make this call asynchronously:

...
new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive())
        Geosophic_ServiceController.postVote(11, "Candidate 2");
    } catch (Geosophic_BadRequestException e) {
      e.printStackTrace();
    } catch (Geosophic_ResponseFormatingErrorException e) {
      e.printStackTrace();
    } catch (Geosophic_HostNotReachableException e) {
      e.printStackTrace();
    }
    return null;
}.execute();
...

Get a player vote info

To get the info of a player vote you should call the method:

(Geosophic_VoteResponse) getUserVote(int leaderboardSchema)
leaderboardSchemaId: Identifier of the leaderboard which you want to obtain the info. You can get this id in the “Settings” view of your game.

This method returns a Geosophic_VoteResponse object, containing the following information:

choice: The last vote posted in the leaderboard by the player.

firstCast:
True if this vote was the first vote of the player, false in other case.

leaderboardSchema:
Id of the leaderboard where the score has been submitted.

It is a good practice to make this call asynchronously:

...
new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive())
        Geosophic_ServiceController.getUserVote(11);
    } catch (Geosophic_BadRequestException e) {
      e.printStackTrace();
    } catch (Geosophic_ResponseFormatingErrorException e) {
      e.printStackTrace();
    } catch (Geosophic_HostNotReachableException e) {
      e.printStackTrace();
    }
    return null;
}.execute();
...

Display a voting leaderboard

There are two ways to get the contents of a voting leaderboard in a predefined HTML view.

(void) showVotingLeaderboard(int leaderboardId, int leaderboardSchemaId)
(void) showVotingLeaderboard(int leaderboardSchemaId)
leaderboardId: Identifier of the voting leaderboard you want to display. The device’s nearest location is showed when you use the call without the leaderboardId parameter .
leaderboardSchemaId: Identifier of the leaderboardSchema you are using. You get this id in the “Settings” page of your game.

A sample call like

Geosophic_ServiceController.showVotingLeaderboard(13)

will display the nearest voting leaderboard.

USE CASE: Set player’s nickname

Each player has an unique nickname in Geosophic. Geosophic’s service sets a nickname, using the “PLAYER_NUMBER” format, to each player by default. To change or update the player’s nickname you should call the method:

(Geosophic_NicknameResponse) updateUserNickname(String nickname)
nickname: The new nickname of the player.

This method returns a Geosophic_NicknameResponse object, containing the following information:

isNicknameAvailable: Returns if the user nickname is available. If it returns true, the nickname is available and updated for the current player in Geosophic. If it returns false, the requested nickname is in use by another player so you have to choose another one.

getSuggestedNickname: If the nickname is in use by another player you can get a suggestion of an available nickname invoking this method. It is not mandatory to use this one in a new update nickname call.

A sample call:

new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive()) {
        Geosophic_NicknameResponse nicknameResponse = Geosophic_ServiceController.updateUserNickname(nickname);
while (!nicknameResponse.isNicknameAvailable()) {
nicknameResponse = Geosophic_ServiceController.updateUserNickname(nicknameResponse.getSuggestedNickname());
}
} } catch (Geosophic_BadRequestException e) { e.printStackTrace(); } catch (Geosophic_ResponseFormatingErrorException e) { e.printStackTrace(); } catch (Geosophic_HostNotReachableException e) { e.printStackTrace(); } return null; }.execute();

USE CASE: Get player’s nickname

To get the player’s current nickname you should call the method:

String getPlayerNickname()

A sample call:

Geosophic_ServiceController.getPlayerNickname();

USE CASE: Get player’s highscores

To get the player’s global highscores in your game you should call the method:

JSONArray getPlayerGlobalHighscore()

This call returns an array of JSONObjects which represents the highscores of the player in each leaderboard schema defined in your game. Schemas which don’t have a score associated to the player are not included in the array. So if the player doesn’t have any score in any leaderboard the array is empty.
The fields of the JSONObject are:

  • leaderboardSchemaId: Value of the leaderboard schema associated to this highscore.
  • rank: Worldwide ranking of the player.
  • value: Value of the highscore.

An example of array returned by this call:

[{"leaderboardSchemaId" : 567, "rank" : 2, "value" : "600.0"},{"leaderboardSchemaId" : 625, "rank" : 3, "value" : "740.0"},{"leaderboardSchemaId" : 340, "rank" : 4, "value" : "720.0"}]

The use of the call is as simple as

Geosophic_ServiceController.getPlayerGlobalHighscore();

USE CASE: Get player’s ranking for the nearest leaderboard

To get the player’s ranking for the nearest leaderboard to the current location you should call the method:

JSONArray getPlayerRank(int leaderboardSchemaId, int neighbours) 
leaderboardSchema: Identifier of the leaderboard schema.
neighbours: This value allow you to include data of the players that precede and follow the current player in the ranking. Zero to not include data of other players.

This call returns an array of JSONObject which represents the info of the leaderboards associated to the current location. If the location is disabled the array just contains info of the worldwide leaderboard. 
The fields of the JSONObject are:

  • latitude: Latitude of the leaderboard.
  • longitude: Longitude of the leaderboard.
  • placeName: Name of the location linked to the leaderboard.
  • playerInfo: JSONObject with the info of the player. If the player doesn’t have any score uploaded into the leaderboard, this field is not included.
    • scoreDate: Date where the highscore was uploaded.
    • scoreValue: Value of the highscore.
    • userNickname: Nickname of the player.
    • userRank: Player ranking in this leaderboard
  • ranking: JSONArray of JSONObjects that contains the ranking of the player and the neighbours. The array is ordered by ranking. If the player doesn’t have any score uploaded into the leaderboard, this field is not included. Each JSONObject contains the same fields as the playerInfo object shown previously.
[
  {
   "latitude" : 0,
   "longitude" : 0,
   "placeName" : "World",
   "playerInfo" :         
{ "scoreDate" : 1360732096087, "scoreValue" : 600, "userNickname" : "Player2", "userRank" : 2 }, "ranking" : [ { "scoreDate" : 1360732096086, "scoreValue" : 1540, "userNickname" : "Player0", "userRank" : 0 }, { "scoreDate" : 1360732096087, "scoreValue" : 1415, "userNickname" : "Player1", "userRank" : 1 }, { "scoreDate" : 1360732096087, "scoreValue" : 600, "userNickname" : "Player2", "userRank" : 2 }, { "scoreDate" : 1360732096088, "scoreValue" : 400, "userNickname" : "Player3", "userRank" : 3 }, { "scoreDate" : 1360732096088, "scoreValue" : 120, "userNickname" : "Player4", "userRank" : 4 }] }, { "latitude" : "52.1082", "longitude" : "5.32986", "placeName" : "Netherlands" }, { "latitude" : "52.582619", "longitude" : "4.93554", "placeName" : "North Holland" }, { "latitude" : "52.373119", "longitude" : "4.89319", "placeName" : "Amsterdam" }
]
A call example
new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive())
        Geosophic_ServiceController.getPlayerRank(351, 2);
    } catch (Geosophic_BadRequestException e) {
      e.printStackTrace();
    } catch (Geosophic_ResponseFormatingErrorException e) {
      e.printStackTrace();
    } catch (Geosophic_HostNotReachableException e) {
      e.printStackTrace();
    }
    return null;
}.execute();

USE CASE: Track custom events

You can track custom in-game events like finishing a level, using a power-up or purchasing an item with this feature.

(boolean) postUserEvent(String eventName, HashMap<String,Object> data)
eventName: Name that identifies the event.
data: Map of parameters to associate with the event. The objects in this map have to be serializable.

Sample usage:

new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive()) {
         HashMap eventContext = new HashMap();
         eventContext.put("level","5");
         eventContext.put("time","324);
         Geosophic_ServiceController.postUserEvent("LEVEL_COMPLETED", eventContext);
    } catch (Geosophic_BadRequestException e) {
       e.printStackTrace();
    } catch (Geosophic_ResponseFormatingErrorException e) {
       e.printStackTrace();
    }  catch (Geosophic_HostNotReachableException e) {
       e.printStackTrace();
    }
  return null;
}.execute();

USE CASE: Use custom user account

Now players can access their scores and data from different devices. In order to do that, you need to connect the running instance with your custom User Id.

(boolean) setCustomUserId(String customUserId)
customUserId: Custom User Id. A user id unique to the users space of the developer.

Sample usage:

new AsyncTask<Void, Void, Void>() {
  @Override
  protected Void doInBackground(Void... params) {
    try {
      if(Geosophic_ServiceController.isServiceActive()) {
         String myCustomUserId = String.valueOf(MyUserAccount.getId());
         Geosophic_ServiceController.setCustomUserId(myCustomUserId);
    } catch (Geosophic_BadRequestException e) {
       e.printStackTrace();
    } catch (Geosophic_ResponseFormatingErrorException e) {
       e.printStackTrace();
    }  catch (Geosophic_HostNotReachableException e) {
       e.printStackTrace();
    }
  return null;
}.execute();