I've implemented the Google Play Games API in my game recently, but some issues appeared after that.
The problem is for some reason my game is not loading my Custom View class when I start the aplication and call the method setContentView() but this only happens when I build the release version of the apk.
gv = new GameView(this);
setContentView(gv); //not loading on release version or if the debuggable is set to true in build.gradle
I also tryied to put this line on build.gradle
debuggable false
the result was that the release version started working but with this line I cant upload it to playStore and the reason of this thread is obviusly because I need this working on the playStore.
Some Notes of test:
- The Google play services connects well both release and debug apks, but in release a black screen appears isntead of my GameView Class
- The setContentView() doesn't works when running the apk on release version or if the debuggable is set to true in build.gradle.
- The setContentView() works fine when running the apk on debug version
- The setContentView() works fine if I load a XML file in any situations (but my game doesnt uses any XMLs).
Main Activity Class
public class Main extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
GameView gv;
public static DBHandler db;
public static String version = "0.0.0";
public static GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fullScreen(true); //PRE ESTABELECE O TAMANHO DA TELA DEIXANDO NO FULLSCREEN PRIMEIRAMENTE
(Toast.makeText(this, "inicializando GameView", Toast.LENGTH_SHORT)).show();
gv = new GameView(this);
setContentView(gv);
// Create the Google Api Client with access to the Play Games services
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
// add other APIs and scopes here as needed
.setViewForPopups(gv)
.build();
// ...
//setContentView(R.layout.loading_screen);
db = new DBHandler(this);
Log.w("Main", ""+db.getPointsCount()+" - registros encontrados.");
//VERSAO ---
PackageInfo pInfo = null;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
version = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}// ...
}
protected void onDestroy(){
super.onDestroy();
gv.relase();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
fullScreen(hasFocus);
}
void fullScreen(boolean hasFocus){
if (hasFocus) {
final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
Log.e("Main","Conectando ao Google Play...");
}
@Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
Log.e("Main","Desconectado da google API PlayGames!");
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.e("Main","onConnected");
Games.Achievements.unlock(mGoogleApiClient, "CgkI8au7i4oUEAIQAg");
(Toast.makeText(this, "Conectado ao Google Play Game", Toast.LENGTH_SHORT)).show();
}
@Override
public void onConnectionSuspended(int i) {
Log.e("Main","onConnectionSuspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e("Main","onConnectionFailed");
(Toast.makeText(this, "Não foi posivel conectar ao Google Play Services.", Toast.LENGTH_SHORT)).show();
}
}
Build.gradle
apply plugin: 'com.android.application'
android {
signingConfigs {
DannarkKey {
keyAlias 'dannark'
keyPassword '23021994'
storeFile file('C:/Users/Daniel/AndroidstudioProjects/DannarkKey.jks')
storePassword '23021994'
}
}
compileSdkVersion 23
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.jumpers.gamelogic"
minSdkVersion 14
targetSdkVersion 21
versionCode 24
versionName "2.7.4"
}
buildTypes {
release {
debuggable false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.google.android.gms:play-services:9.0.0'
}
GameView.class
/**
* Created by Daniel on 19/03/2016.
*/
public class GameView extends View implements Runnable {
Context context;
private static final int INTERVAL = 10;
private boolean running = true;
private Paint p;
public static HUD hud;
public static PrintText pt;
public static ArrayList<SpawnMessageWindows> spawnMsgs = new ArrayList<>();
public static ScoreScreen scoreScreen;
public static HandleEventsTouchsSpawnedObjects handleEventsTouchs = new HandleEventsTouchsSpawnedObjects();
public static Load load;
public static Fase fase;
public static Player player;
public static Menu menu;
public static Camera cam;
Bitmap layerImg2;
public static Canvas layer2;
public static LaterCanvas laterCanvas;
public static int lar;
public static int alt;
public static int touchFocus = 0;
public static ArrayList<String> variaveisName = new ArrayList<>();
public static ArrayList<Float> variaveisValue = new ArrayList<>();
private long preTime = 0;
public static int timeInGame = 0;
public static boolean isPlaying = false;
// blocksIDsUsedForTutorial TEM O OBJETIVO DE MOSTRAR MENSSAGENS DE TUTORIAS PELA PRIMEIRA VES CASO VC NUNCA TENHA USADO
// UM SCRIPT, SE TIVER DENTRO DESSA LISTA, ENTÃO A MENSAGEM NAO APARECERA.
public static ArrayList<Integer> blocksIDsUsedForTutorial = new ArrayList<>();
public GameView(Context context) {
super(context);
this.context = context;
load = new Load(context);
p = new Paint();
Thread t = new Thread(this);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
preTime = System.currentTimeMillis()/1000;
addVariavel("variavel1", 0); //TESTE
addVariavel("valor3", 0); //TESTE
addVariavel("valor4", 0); //TESTE
addVariavel("valor5", 0); //TESTE
addVariavel("valor6", 0); //TESTE
addVariavel("valor7", 0); //TESTE
addVariavel("valor8", 0); //TESTE
}
void init(){
while (getWidth() == 0){ }//aguarndando getWidth
lar = getWidth();
alt = getHeight();
player = new Player();
fase = new Tutorial_001(context);//new Fase1(context);
hud = new HUD();
pt = new PrintText();
menu = new Menu(context);
cam = new Camera(getWidth(), getHeight(), player);
layerImg2 = Bitmap.createBitmap(lar, alt, Bitmap.Config.ARGB_8888);
layer2 = new Canvas(layerImg2);
laterCanvas = new LaterCanvas(context);
setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//int action = event.getActionMasked();
TextKeyBoard.handleTouch(v, event);
NumericKeyBoard.handleTouch(v, event);
hud.handleTouch(v, event);
menu.handleTouch(v, event);
cam.handleTouch(v, event);
handleEventsTouchs.handleTouch(v, event); //SEGURA TODOS OS EVENTOS DE OBJETOS CRIADOS POSTEIORMENTE
return true;
}
});
}
@Override
public void run() {
init();
while (running){
try {
Thread.sleep(INTERVAL);
}catch (Exception e){
Toast t = Toast.makeText(getContext(), "Game Loop:"+e.getMessage(), Toast.LENGTH_LONG);
t.show();
Log.e("GameLogic", "GameLoop erro Inesperado: "+e.getMessage());
}
update();
}
}
public void update(){
//dispara o metodo de desenho
postInvalidate();
timeInGame = (int)((System.currentTimeMillis()/1000)-preTime); //TEMPO JOGADO EM SEGUNDOS
}
public void draw(Canvas c){
super.draw(c);
if(c!=null && player != null && hud != null && menu != null && cam!=null) {
c.drawColor(Color.BLACK);
if(isPlaying) {
cam.draw(c, p);
hud.draw(c, p);
pt.draw(c, p);
if(scoreScreen != null) {
scoreScreen.draw(c);
}
laterCanvas.drawBeforeMsgs(c); //DESENHA TODOS OS DESENHOS SOBREPOSTOS NA MESMA CANVAS.
if(spawnMsgs.size() > 0){
spawnMsgs.get(0).draw(c, p);
}
laterCanvas.drawAfterMsgs(c); //DESENHA TODOS OS DESENHOS SOBREPOSTOS NA MESMA CANVAS.
//c.drawBitmap(layerImg2,0,0,p);
}else {
menu.draw(c, p);
}
}
}
public void relase(){
running = false;
}
public static void addVariavel(String variavelNome, float variavelValor){
if(variaveisName.contains(variavelNome) == false) {
variaveisName.add(variavelNome);
variaveisValue.add(variavelValor);
}
}
public static void removeVariavel(int index){
variaveisName.remove(index);
variaveisValue.remove(index);
}
public static void setVariavelValor(int valiavelIndex, float variavelValor){
variaveisValue.set(valiavelIndex, variavelValor);
}
}