Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Sunday, February 17, 2013

JSON in Android

In this post I will show you how to get JSON data from a HTTP server and parse it in android.
The JSON data that we will parse in this tutorial is the following:

{
  "status" : "ok",
  "score" : 101,
  "friends" : [{"id" : 321, "score" : 100}, {"id" : 320, "score" : 105}]
}

We will assume that you can access this data from the URL: http://server.com/json

The first step is to get the data in you android application. Since we will download it from a server, you will first need to specify the internet permission in you Android Manifest file:

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

Now that we set this permission, we can download the data. Since we can't use the main thread for networking, we will create a new thread to download our data and parse it. Add the following code in your onCreate method, in your Activity class.

new Thread() {
  public void run() {
    helloJson();
  }
}.start();

Next, we will create the helloJson method, containing the following code:

public void helloJson() {
    StringBuilder builder = new StringBuilder();
    
    try {
      HttpClient client = new DefaultHttpClient();
      HttpGet httpGet = new HttpGet("http://server.com/json");
  
      HttpResponse response = client.execute(httpGet);
      int statusCode = response.getStatusLine().getStatusCode();
      
      if (statusCode == 200) {
        HttpEntity entity = response.getEntity();
        InputStream content = entity.getContent();
        InputStreamReader reader = new InputStreamReader(content)
        BufferedReader reader = new BufferedReader(reader);
        String line;
        while ((line = reader.readLine()) != null) {
          builder.append(line);
        }
        JSONObject jobj = new JSONObject(builder.toString());
        builder = new StringBuilder(jobj.get("status").toString());
        JSONArray jar = jobj.optJSONArray("friends");
        builder.append(jar.length());
      }
    }
    catch(Exception e) {
      e.printStackTrace();
      builder.append(e);
    }
    
    final String str = builder.toString();
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
      }
    });
  }

This will display a message using Toast, containing the status string and the length of the friends array.

That's it! :)

Wednesday, February 6, 2013

Admob with Andengine

If you have a game developed with Andengine you probably don't use a XML layout file and your activity simply extends the BaseGameActivity class or the SimpleBaseGameActivity class.
I assume that you know hot to add the Admob jar to your project and to set the required permissions in the AndroidManifest file. If you don't, then check the tutorials on the Admob web site first.

The first thing you need to do is create a new XML layout file, let's call it game_layout.xml
The content of this file should be similar to the following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:orientation="vertical" >

    <org.andengine.opengl.view.RenderSurfaceView
        android:id="@+id/SurfaceViewId"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:gravity="center" />

    <com.google.ads.AdView
        android:id="@+id/adViewId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        ads:adSize="BANNER"
        ads:adUnitId="YOU_ID_HERE"
        ads:loadAdOnCreate="true" />
    
</RelativeLayout>

In this case, the Layout is RelativeLayout, because we want the ad to be drawn over the game surface. Based on your requirements, you could try to use a other layouts, but i find the relative one to be the best. Inside the layout there are 2 components, the surface view and the ad view, each with it's own id (adViewId and SurfaceViewId). Also, don't forget to define the namespace for the Admob components, in my case "ads:".


Now that we have our layout file, we must include it in the activity. In a normal android application you could do this by calling setContentView(R.layout.game_layout);  in the onCreate method of the activity. In Andengine, we need to use a different approach.
I will assume that you extend the SimpleBaseGameActivity class because the first step you need to do is adapt the class to extend the BaseGameActivity class.
The class hierarchy for the activity classes in Andengine is presented in the following figure:


In order to display ads we must extend the LayoutGameActivity class.
Let's assume that you have the following class that extends the SimpleBaseGameActivity:
public class MainActivity extends SimpleBaseGameActivity {

  public static final int CAMERA_HEIGHT = 720;
  public static final int CAMERA_WIDTH = 480;

  private Camera camera;
  private BitmapTexture blocksTexture;

  @Override
  public EngineOptions onCreateEngineOptions() {
    this.camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
    EngineOptions engineOptions = new EngineOptions(true,
        ScreenOrientation.PORTRAIT_FIXED,
        new FillResolutionPolicy(), camera);
    return engineOptions;
  }

  @Override
  protected void onCreateResources() {
    try {
      this.blocksTexture = new BitmapTexture(this.getTextureManager(),
            new IInputStreamOpener() {
        @Override
        public InputStream open() throws IOException {
          return getAssets().open("gfx/block.png");
        }
      });
      blocksTexture.load();
      
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  protected Scene onCreateScene() {
    GameScene scene = new GameScene(blocksTexture, this);
    this.mEngine.registerUpdateHandler(scene);
    return scene;
  }

}

This is a minimalist class, with all the logic defined in the GameScene class, for the sake of simplicity.
After extending the LayoutGame class, the file will look like this:
public class MainActivity extends LayoutGameActivity {

  public static final int CAMERA_HEIGHT = 720;
  public static final int CAMERA_WIDTH = 480;

  private Camera camera;
  private BitmapTexture blocksTexture;

  @Override
  public EngineOptions onCreateEngineOptions() {
    this.camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
    EngineOptions engineOptions = new EngineOptions(true,
        ScreenOrientation.PORTRAIT_FIXED,
        new FillResolutionPolicy(), camera);
    return engineOptions;
  }

  @Override
  public void onCreateResources(
      OnCreateResourcesCallback pOnCreateResourcesCallback)
          throws Exception {
    try {
      this.blocksTexture = new BitmapTexture(this.getTextureManager(),
            new IInputStreamOpener() {
        @Override
        public InputStream open() throws IOException {
          return getAssets().open("gfx/block.png");
        }
      });
      blocksTexture.load();

    } catch (IOException e) {
      e.printStackTrace();
    }
    pOnCreateResourcesCallback.onCreateResourcesFinished();
  }

  @Override
  public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
      throws Exception {
    GameScene scene = new GameScene(blocksTexture, this);
    this.mEngine.registerUpdateHandler(scene);
    pOnCreateSceneCallback.onCreateSceneFinished(scene);
  }

  @Override
  public void onPopulateScene(Scene pScene,
      OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
    pOnPopulateSceneCallback.onPopulateSceneFinished();
  }

  @Override
  protected int getLayoutID() {
    return R.layout.game_layout;
  }

  @Override
  protected int getRenderSurfaceViewID() {
    return R.id.SurfaceViewId;
  }

}

There are 2 methods related to the layout file. The first method is getLayoutID, that must return the id of the file containing the layout. The other method is getRenderSurfaceViewID, that must return the id of the surface view.
The other methods simply do what the SimpleBaseGameActivity class does for the BasicGameActivity.

This is all you need to do in order to display ads in an Andengine game.

Sunday, January 27, 2013

Global variables in android

Global variables are variables that can be accessed from more than one activity.
If you only need primitive values than you can pass them in the Intent, but if you have more complex data types this is not an option.
The first thing you might try is to declare the members as static.
This is a VERY BAD idea.
Android can set static instances to null without you knowing and you will spend hours debugging the application.

The correct way to do this is by extending the Application class.
As stated in the Android documentation:
Base class for those who need to maintain global application state.

Bellow is an example of how to use the application class:
package gulyan.gametoolkit.app;

import android.app.Application;

public class GameApplication extends Application {

 private static GameApplication instance = null;

 @Override
 public void onCreate() {
  super.onCreate();
  instance = this;
 }

 public static GameApplication getInstance() {
  return instance;
 }

}
Next, you must edit the AndroidManifest file in order to use the custom application class, by setting the name attribute.
<application
     android:name="gulyan.gametoolkit.app.GameApplication"
     android:icon="@drawable/ic_launcher"
     android:label="@string/app_name"
     android:allowBackup="true"
     android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
You can now declare all the variables as members of this class (non-static members).
If you need to access them you can use the getInstance method in order to obtain the application instance. This instance is the same in all the activities.
GameApplication inst = GameApplication.getInstance();
MyVar x = inst.getMyVar();
inst.setMyVar(x);
Hope you find this useful.