[Android] Cómo twittear algo desde libGDX

K

Hola,

Llevo bastante tiempo leyendo el foro y he aprendido muchas cosas con los comentarios que aparecen aquí.

Estoy desarrollando un juego usando libGDX y mi idea era poder twitear la puntuación en Twitter.

He tomado como base este ejemplo que usa la librería twitter4j y dicho ejemplo es prácticamente lo que quiero hacer.

Sin embargo no sé como integrarlo en un juego que use libGDX.
Sé que en libGDX no puedes usar código "nativo" directamente y que necesitas usa una interfaz y que que cada proyecto (en mi caso solo tengo proyecto de escritorio y de Android) implemente dicha interfaz.
Luego en cada proyecto ya desarrollas el código específico para dicha plataforma.

¿Alguien podría indicarme como poder llamar a una "Activity nativa de Android" al pulsar en un botón (que es un actor) de libGDX?
(Esa nueva Activity es la que hay en el código de ejemplo de twitter4j)

O dicho de otro modo, ¿Como implementáis el envío de puntuaciones a twitter en un juego desarrollado con libGDX?
En un futuro pensaba también hacerlo con facebook, puesto que supongo que será similar y lo que cambiará entiendo que será la API.

Muchísimas gracias por adelantado.

KeTo

Buenas,

creo que no entiendo el problema. Como tú bien dices, puedes crear una interfaz en el "core" que después implementarán tanto la versión de escritorio como la de android. En la de escritorio puedes hacer un print de "puntuación x enviada a twitter" y en la de android lanzas la actividad nativa con el código que has puesto.

Aquí https://github.com/TheInvader360/tutorial-libgdx-google-ads hace algo parecido pero con anuncios en vez de con twitter.

Espero que te sea de ayuda.

FrioneL

#1 Tienes que crear la interfaz en la activity de android y pasarla como parametro al GameListener de libgdx.

K

Ante todo gracias por las respuestas.
El ejemplo que ha puesto KeTo ya lo había visto (y probado en un pequeño 'hola mundo' ) para integrar los baners de publicidad . De hecho lo que probé en su día creo que es casi lo mismo: TheInvader360/tutorial-libgdx-google-ads (via github)

FrioneL el tema es que creo una interfaz en el core, que solo tiene un método void IniciarTwitter que se supone de lanza un nuevo activity, pero no soy capaz de inicializarla correctamente ya bien sea desde el Laucher de Android y pasarla al GameListener. El código no tiene errores sintácticos, pero al ejecutarlo y pulsar en el botón, la aplicación "se cuelga".

De ahí mi duda. ¿Como tendría que inicializar el objeto? ¿Tendría que crear la vista de la actividad como en el ejemplo que ha puesto KeTo?

Lo siento si son preguntas elementales, pero no veo la salida :(

1 respuesta
cabron

#4

Te contesto escribiendo el código directamente aquí, así que sin resaltado de sintaxis ni errores de compilación lo más probable es que algo esté mal, pero bueno la idea es que entiendas como funciona más que darte la solución lista para que la copies y pegues.

Salvo que haya cambiado mucho libgdx desde la última vez que lo usé, tendrás una clase que implementa ApplicationListener

public class MiJuego implements ApplicationListener {

//bla bla
}

La forma más directa de hacerlo (que no necesariamente la mejor) es usar inyección de dependencias y un método en la clase principal del juego:


//Todo esto en el proyecto core

public interface Twitter
{
     void enviar Twitter(Strint texto);
}

public class MiJuego implements ApplicationListener {

private Twitter twitter;
static public  MiJuego juego;

//Constructor
public MiJuego(Twitter twitter) 
{
   this.twitter = twitter;
}

public Twitter obtTwitter()
{
    return twitter;
}

@Override
public void create() {				
	
juego = this;	
 }
}

Ahora en tu proyecto android, tendrás una clase que hereda de AndroidApplication, donde creas una instancia de la clase MiJuego, pues bien, tienes que crear una clase TwitterAndroid que implemente la interfaz anterior, y que haga lo que tenga que hacer para enviar un Twitter en Android:

//Todo esto en el proyecto android

public class TwitterAndroid implements Twitter
{
    void enviarTwitter(String texto)
    {

     //Lo que se apara enviar el Twitter
}
}


public class MainActivity extends AndroidApplication {

 @Override
    public void onCreate(Bundle savedInstanceState) {    	
        super.onCreate(savedInstanceState);

  MiJuego juego = new MiJuego (new TwitterAndroid());
}

}

En tu proyecto de Escritorio haces lo mismo, pero con otra clase que envíe los twits como se haga desde ahí (o vacío si solo quieres que no pete):


public class TwitterEscritorio implements Twitter
{
    void enviarTwitter(String texto)
    {

     //Lo que se apara enviar el Twitter
}
}


public class Main {
	public static void main(String[] args) {
		LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();		
		
	new LwjglApplication(new MiJuego(new TwitterEscritorio), cfg);
	
}
}

Luego es tan simple como que cada vez que quieras enviar un Twitter obtener una referencia a la clase actual mediante la variable estática:


//En cualquier sitio

MiJuego.juego.obtTwitter().enviarTwitter("texto");

Si quieres evitar usar una variable global para obtener la instancia actual del juego y de ahí la clase Twitter concreta que has metido mediante inyección de dependencias, tendrías que tirar de implementar el patrón service locator o algo similar.

1
K

Muchísimas gracias cabron.
Esa implementación es exactamente lo que estoy usando (inyección en el constructor)
el problema lo tengo precisamente en la implementación de enviarTwitter en el proyecto de Android.
Si pongo un breakpoint en dicho método veo que el código se para allí, pero el programa falla.
Lo único que tengo en ese método es esto:

Intent myIntent = new Intent(this, TwitterMainActivity.class);
startActivity(myIntent);

Donde TwitterMainActivity es la actividad que se supone que envía el tweet (y que como proyecto independiente funciona correctamente)

El problema lo tengo ahí, en ese par de líneas. Creo que hay algo que se me escapa (crear la vista, registrarla o algo)

1 respuesta
cabron

#6

¿has registrado TwitterMainActivity en AndroidManifest.xml?

<activity android:name="tu.paquete.TwitterMainActivity" />

También es posible que te pete por que libgdx se ejecuta en un thread dedicado para Opengl, y hacer algo relacionado con la interfaz de usuario desde este thread hace que la aplicación pete, la solución es ejecutarlo dentro del thread para la interfaz de usuario:

runOnUiThread(new Runnable() {
				
			@Override
			public void run() {
				Intent myIntent = new Intent(this, TwitterMainActivity.class);
                                    startActivity(myIntent);	    	
				
			}
		});
1
K

Gracias de nuevo,
Es que creo que el problema es ese.
Las dos actividades están registradas

Para hacerlo más sencillo he cambiado la Activity que envia el Tweet por una activity en blanco.

Desde el core llamo al método openTwitter que implementa ImyTwitter:
En el proyecto Android la implemetación es esta:

public class MyTwitter extends Activity implements ImyTwitter {	
	@Override
	public void openTwitter() {
		// TODO Auto-generated method stub
		int x = 0;
		x++;
		try {
		      runOnUiThread(new Runnable() {
		    	@Override
		        public void run() {
		    		Intent myIntent = new Intent(this, TwitterMainActivity.class);
		    		startActivity(myIntent);
		        }
		      });
		    } catch (Exception e) {
		    }		
	}
}

(Tengo que extender a Activity si no no puedo usar el Intent)

Pues bien, ahí dentro lo que intento hacer es llamar a Activity TwitterMainActivity para que envíe el tweet (ahora es una 'Activity' vacía que solo tienen un layout asociado y un caption.

Sin embargo, ahora al hacer lo del runOnUiThread, si que tengo un error de sintaxis en :
Intent myIntent = new Intent(this, TwitterMainActivity.class);
donde me dice que el constructor no es el correcto.

No entiendo nada :(

1 respuesta
YaW

#8 te está fallando la compilación porque el "this" en ese caso no se refiere a la Activity y por tanto no es un contexto, ahí el "this" se refiere al Runnable. Si pones MyTwitter.this lo solucionarás.

De todas formas lo estás planteando mal, no es la llamada a la Activity donde haces lo de Twitter lo que tienes que meter en un thread, es la propia llamada a Twitter lo que tienes que meter en un thread.

Si pones el código del TwitterMainActivity igual queda más claro que estás haciendo, pero básicamente cuando vayas a comprobar los credenciales de twitter, crearlos o enviar un tweet es cuando tienes que hacer el thread. Y sería mejor hacerlo con un AsyncTask para poder ir informando al usuario del progreso :)

Usuarios habituales