Archive for the ‘Desarrollo Android’ Category

Configurar ADB para usar Nexus S en linux

Posted on mayo 25th, 2012 in Desarrollo Android | 142 Comments »

Si, una vez conectado el teléfono por USB, este no es detectado, deberemos configurar udev tal que así:

1. Crear el fichero /etc/udev/rules.d/51-android.rules.

2. Añadir el siguiente contenido (como dice el título, esto es válido para el Nexus S):

 #      NEXUS S
 SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e21",
 SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e22", SYMLINK+="android_adb"
 SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e20", SYMLINK+="android_fastboot"

3. Ahora, en la línea de comandos, lanzamos lo siguiente:

 sudo chmod a+r /etc/udev/rules.d/51-android.rules

4. Reiniciamos y ya deberiamos ver nuestro dispositivo lanzando “adb devices” en la línea de comandos.

5. Una vez lanzado deberiamos ver algo tal que así

 List of devices attached
 3130F74D00E600EC	device

6. Si obtuviéramos una respuesta del siguiente tipo:

 List of devices attached
 ???????????? no permissions

Tendremos que lanzar adb con permisos de root:

 $ ./adb kill-server
 $ sudo ./adb start-server
 $ ./adb devices

En caso de tener que instalar otros dispositivos diferentes al Nexus S, puedes encontrar la configuración en http://developer.android.com/guide/developing/device.html.

Cómo añadir Mobfox usando Admob como backfill

Posted on febrero 24th, 2012 in Desarrollo Android | 157 Comments »

Aquí se describe cómo añadir Mobfox a una aplicación Android que, a su vez, usará Admob como backfill.

Paso 1:

Añadir los SDK de Admob y Mobfox al proyecto poniendo los respectivos jars en la carpeta “libs”.

Paso 2:

Editar el fichero AndroidManifest.xml y añadir lo siguiente:

<activity android:name="com.mobfox.sdk.InAppWebView"/>
<activity android:name="com.google.ads.AdActivity"
          android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
          android:configChanges="orientation|keyboard|keyboardHidden"
         />


Paso 3:

Añadir la siguiente vista en el layout correspondiente de main.xml:

<RelativeLayout
   android:id="@+id/mobfoxContent"
   android:layout_width="fill_parent"
   android:layout_height="50dp"
   android:layout_centerHorizontal="true"
   android:layout_alignParentBottom="true" >
</RelativeLayout>


Paso 4:

Añadir los siguiente imports en la Activity:

Import com.google.ads.Ad;
Import com.google.ads.AdListener;
Import com.google.ads.AdRequest;
Import com.google.ads.AdSize;
Import com.google.ads.AdView;
Import com.google.ads.AdRequest.ErrorCode;
Import com.mobfox.sdk.BannerListener;
Import com.mobfox.sdk.MobFoxView;
Import com.mobfox.sdk.Mode;
Import com.mobfox.sdk.RequestException;


Paso 5:

Añadir las siguientes declaraciones:

private final static String ADMOB_PUBLISHER_ID = "";
private final static String MOBFOX_PUBLISHER_ID = "";
private ViewFlipper viewFlipper;
private MobFoxView mobfoxView;
private AdView adMobView;
private AdRequest adMobRequest;
private final static int REFRESH_AD = 101;
private final static long REFRESH_INTERVAL = 30000;
private Handler refreshHandler;
private Looper refreshLooper;
private RelativeLayout layout;


Paso 6:

Añadir lo siguiente al método onCreate():

boolean includeLocation = false;
boolean useAnimation = true;

mobfoxView = new MobFoxView(this, MOBFOX_PUBLISHER_ID, Mode.LIVE, includeLocation, useAnimation);
mobfoxView.setBannerListener(this);

adMobView = new AdView(this, AdSize.BANNER, ADMOB_PUBLISHER_ID);
adMobView.setAdListener(this);
adMobRequest = buildAdMobRequest();

viewFlipper = new ViewFlipper(this) {
    @Override
    protected void onDetachedFromWindow() {
        try {
            super.onDetachedFromWindow();
        }
        catch (IllegalArgumentException e) {
            stopFlipping();
        }
    }
};

viewFlipper.addView(mobfoxView);
viewFlipper.addView(adMobView);

if (useAnimation)
{
    Animation fadeInAnimation =
        new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, +1.0f, Animation.RELATIVE_TO_PARENT, 0.0f);
    fadeInAnimation.setDuration(1000);
    Animation fadeOutAnimation =
        new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, -1.0f);
    fadeOutAnimation.setDuration(1000);
    viewFlipper.setInAnimation(fadeInAnimation);
    viewFlipper.setOutAnimation(fadeOutAnimation);
    viewFlipper.setAnimateFirstView(true);
}

//Show MobFoxView viewFlipper.setDisplayedChild(0);
layout = (RelativeLayout) findViewById(R.id.mobfoxContent);
layout.addView(viewFlipper);
Thread refreshThread = new Thread(){
    @Override
    public void run() {
        Looper.prepare();
        refreshLooper=Looper.myLooper();
        refreshHandler = new Handler(refreshLooper) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case REFRESH_AD:
                    {
                        mobfoxView.loadNextAd();
                        break;
                    }
                }
            }
        };
        Looper.loop();
    }
};
refreshThread.start();


Paso 7:

Añadir los siguientes métodos a la Activity

public AdRequest buildAdMobRequest()
{
    AdRequest adMobRequest =
    new AdRequest();
    //Add targeting info if you like
    //adMobRequest.setGender(Gender.FEMALE);
    //adMobRequest.setBirthday(birthDate);
    //adMobRequest.setLocation(location);
    adMobRequest.addKeyword("game");
    adMobRequest.setTesting(false);
    return adMobRequest;
}

@Override
protected void onPause() {
    super.onPause();
    if (refreshHandler != null)
    {
        refreshHandler.removeMessages(REFRESH_AD);
    }
    if (adMobView!=null)
    {
        adMobView.stopLoading();
    }
    mobfoxView.pause();
}

@Override
protected void onResume() {
    super.onResume();
    if (refreshHandler != null)
    {
        refreshHandler.removeMessages(REFRESH_AD);
        refreshHandler.sendEmptyMessage(REFRESH_AD);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (refreshLooper != null)
    {
        refreshLooper.quit();
        refreshLooper = null;
        refreshHandler = null;
    }
}

@Override
public void bannerLoadSucceeded() {
    this.runOnUiThread(new Runnable() {
        public void run() {
            if (viewFlipper.getCurrentView()!=mobfoxView)
            {
                viewFlipper.setDisplayedChild(0);
            }
        }
    });
}

//Mobfox events
@Override
public void noAdFound() {
    this.runOnUiThread(new Runnable() {
        public void run() {
        }
    });
    try
    {
        adMobView.loadAd(adMobRequest);
    }
    catch (Exception ex)
    {
        if (refreshHandler!=null)
        {
            refreshHandler.sendEmptyMessageDelayed(REFRESH_AD, REFRESH_INTERVAL);
        }
    }
}

@Override
public void bannerLoadFailed(RequestException e) {
    this.runOnUiThread(new Runnable() {
        public void run() {
        }
    });
    try
    {
        adMobView.loadAd(adMobRequest);
    }
    catch (Exception ex)
    {
        if (refreshHandler!=null)
        {
            refreshHandler.sendEmptyMessageDelayed(REFRESH_AD, REFRESH_INTERVAL);
        }
    }
}

//Admob events
@Override
public void onReceiveAd(Ad arg0) {
    this.runOnUiThread(new Runnable() {
        public void run() {
            if (viewFlipper.getCurrentView()!=adMobView)
            {
                viewFlipper.setDisplayedChild(1);
            }
        }
    });
    if (refreshHandler!=null)
    {
        refreshHandler.sendEmptyMessageDelayed(REFRESH_AD, REFRESH_INTERVAL);
    }
}

@Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
    this.runOnUiThread(new Runnable() {
        public void run() {
        }
    });
    if (refreshHandler!=null)
    {
        refreshHandler.sendEmptyMessageDelayed(REFRESH_AD, REFRESH_INTERVAL);
    }
}

@Override
public void onDismissScreen(Ad arg0) {
    // TODO Auto-generated method stub
}
@Override
public void onLeaveApplication(Ad arg0) {
    // TODO Auto-generated method stub
}
@Override
public void onPresentScreen(Ad arg0) {
    // TODO Auto-generated method stub
}


Paso 8:

La Activity debe implementar BannerListener y AdListener, con lo que quedaría algo parecido a esto:

public class MyAndroidApplication extends Activity implements BannerListener, AdListener {


Paso 9:

Añadir los IDs de publisher correspondientes:

private final static String ADMOB_PUBLISHER_ID = "";
private final static String MOBFOX_PUBLISHER_ID = "";

¡Hecho!

Ahora tu aplicación ya recibe anuncios de Mobfox usando Admob como backfill.

Habilitar la opción de mover una App Android a la tarjeta SD

Posted on septiembre 22nd, 2011 in Desarrollo Android | 139 Comments »

Esta opción es interesante y, cada vez más, hay más gente que pide que se incluya en las aplicaciones.

Aunque la opción fue añadida en la versión 2.2, es posible incluirla en versiones previas de la SDK. Incluso una App hecha con la SDK 1.5 puede incluir esta función, aunque eso sí, la opción de mover a la SD sólo estará disponible en aquellos móviles con versión 2.2 o posterior.

Vamos con los pasos a seguir:

1. Modificar el Manifest

Edita el fichero AndroidManifest.xml file de la aplicación y añade el atributo “android:installLocation” en la etiqueta :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.yourapp"
      android:versionName="1.0.1" android:versionCode="3"
      android:installLocation="auto">

En este caso ponemos “auto”, lo que dará al usuario la opción de instalar la App en la memoria del móvil o en la SD. Otros valores son “internalOnly”, que es la opción por defecto si no se añade esta configuración, y “preferExternal”, que instalará la aplicación en la SD primero, si hay espacio para ello.

2. Actualizar el Build Target.

Como ya he mencionado, esto funciona en versiones anteriores a la 2.2, con lo que dejaremos la propiedad “minSdkVersion” tal cual la tenemos. Sin embargo, el “Build target” si debemos modificarlo a la versión 8 (SDK 2.2). En caso contrario, recibiríamos el siguiente error:

error: No resource identifier found for attribute ‘installLocation’ in package ‘android’


3. Cargar la App en el simulador con SDK 2.2

Esto es todo. Si vamos al móvil o simulador, en la administración de aplicaciones, veremos que tenemos disponible el botón de mover al SD.