I'm developing an Android app. I have been testing it with the AVD (Nexus 5 API 22) and my LG G2 (5.0.2). When I released my first beta version I used a Moto G (4.4.4) to test it, and it works completely different.
E.g., when clicking a button, in the Moto G an item is added twice to a ListView, whereas in the other two works fine. Also in the G2 the background is not displayed, and in the other two it can be seen perfectly.
Right now I have tested it in a Xperia U (4.0.4) and everything works fine.
The Android Studio is configured for the API 15 in compiledSdkVersion, minSdkVersion and targetSdkVersion.
What's happening? I don't understand anything. What can I do to fix it?
EDIT: I add code snippets where the app fails.
TimePickerFragment class
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Alarm pickedAlarm = new Alarm();
int pk;
pickedAlarm.setHour(hourOfDay);
pickedAlarm.setMinute(minute);
pickedAlarm.setActivity(getActivity());
pk = db.insertNewAlarm(hourOfDay, minute);
pickedAlarm.set_id(pk);
pickedAlarm.setAdapter(adapter);
pickedAlarm.setDb(db);
adapter.add(pickedAlarm);
adapter.notifyDataSetChanged();
pickedAlarm.startCountdown(false);
Toast.makeText(getActivity().getApplicationContext(), "Alarm set and countdown started.", Toast.LENGTH_SHORT).show();
}
It seems that in Moto G this function is called twice...
MainActivity, when there is the botton to show the timePicker:
public void addAlarmClick(View view) {
TimePickerFragment timePicker = new TimePickerFragment();
timePicker.show(getFragmentManager(), "timePicker");
}
Related
For my Android app I use Google Play Services for things like: Chromecast, Maps and analytics.
In my build.gradle file I compile version 12.0.0:
implementation "com.google.android.gms:play-services-cast-framework:12.0.0"
implementation "com.google.android.gms:play-services-cast:12.0.0"
implementation "com.google.android.gms:play-services-base:12.0.0"
implementation "com.google.android.gms:play-services-maps:12.0.0"
implementation "com.google.android.gms:play-services-analytics:12.0.0"
implementation "com.google.android.gms:play-services-vision:12.0.0"
implementation "com.google.android.gms:play-services-gcm:12.0.0"
The problem is that the app crashes when people don't have version 12 or newer installed on their device.
So what I did is the following:
In AndroidManifest.xml:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
And a small class to check if play services is up-to-date or installed:
public boolean checkIfInstalled(Context applicationContext) {
try {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(applicationContext);
// Version is out of date
if (resultCode != ConnectionResult.SUCCESS) {
final AlertDialog.Builder builder = new AlertDialog.Builder(applicationContext);
builder.setMessage("Google Play Services is required to use this app. Install Play Services or update to the latest version to continue.");
builder.setPositiveButton("Go to Play store", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.i("PlayServicesCheck", "clicked on the button");
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
return false;
}
return resultCode == ConnectionResult.SUCCESS;
} catch (Exception err) {
return false;
}
}
In onCreate (when the app launches) I call this function to check if everything is alright. The function returns false when it's outdated. So my code works at this point.
#Override
protected void onCreate(Bundle savedInstanceState) {
boolean isInstalled = checkIfInstalled(getApplicationContext());
// this works, I get the right value back from the checkIfInstalled function
if (isInstalled) {
Log.i("PlayServicesCheck", "Installed");
// Do nothing
} else {
Log.i("PlayServicesCheck", "Not Installed");
// Give alert, stop everything else
}
super.onCreate(savedInstanceState);
}
But how do I stop the app from launching when this happens? Right now it says: "version outdated" but it will still continue to start the app which leads to a crash.
Thanks
You can call finishAndRemoveTask.
The problem with checking from the store that it takes time for Google to deploy the version to all the servers, therefore, it can happen that you're forced to update but when you enter into the store you still don't see the new version.
In any case, it would be better if you would have a server where you return the minimum version. This will let you fine tune on which changes you want to force the user to download and on which you don't. It can sometimes be disturbing for the user if each version is forced.
Similar questions to this have been trivial at best for answers. I am using a faily up-to-date Google Play Game Services apk 'com.google.android.gms:play-services:7.0.0' and I have onInvitationReceived() and onConnected() implemented.
However, onInvitationReceived() doesn't seem to be called when the invitee accepts the game invite in-game. And while I'm fairly certain onConnected() is called no matter what when the player connects via callback after mGoogleClient.connect() , it seems like the invitation is dropped or something because the player is not redirected to the game screen as I specified if the Bundle contains an invitation (I'm assuming this is called when the app is closed but either way, only a status bar notification is shown for the invite).
Any insight into this would be appreciated. Here are the relevant methods:
onConnected() is from a class, that extends AndroidGame, and AndroidGame extends Activity (I've tried it in both classes, now I just have it overridden in the child class of AndroidGame):
#Override
public void onConnected(Bundle connectionHint) {
// Connected to Google Play services!
// The good stuff goes here.
Games.Invitations.registerInvitationListener(mGoogleClient, Network.getInstance().mListener);
if (connectionHint != null) {
Invitation inv =
connectionHint.getParcelable(Multiplayer.EXTRA_INVITATION);
if (inv != null) {
// accept invitation
RoomConfig.Builder roomConfigBuilder = RoomConfig.builder(Network.getInstance());
roomConfigBuilder.setMessageReceivedListener(Network.getInstance());
roomConfigBuilder.setRoomStatusUpdateListener(Network.getInstance());
roomConfigBuilder.setInvitationIdToAccept(inv.getInvitationId());
RoomConfig roomConfig = roomConfigBuilder.build();
Games.RealTimeMultiplayer.join(mGoogleClient, roomConfig);
// prevent screen from sleeping during handshake
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// go to game screen
setScreen(new CharSelectScreen(this));
}
}
}
onInvitationReceived is from my Network class, which is basically a singleton which handles other listeners as well. onInvitationReceived() is both overridden in the Network class and in the anonymous inner class, just to cover my assets:
#Override
public void onInvitationReceived(Invitation invitation) {
Intent intent = Games.Invitations.getInvitationInboxIntent(game.getGoogleClient());
game.startActivityForResult(intent, RC_INVITATION_INBOX);
mIncomingInvitationId = invitation.getInvitationId();
AlertDialog.Builder builder = new AlertDialog.Builder(game.getApplicationContext());
builder.setMessage("Join Game?")
.setTitle("Bit Game Invitation!");
builder.setPositiveButton("Join", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if(!game.getGoogleClient().isConnected()) {
game.getGoogleClient().connect();
}
// User clicked OK button
Bundle am = RoomConfig.createAutoMatchCriteria(1, 3, 0);
RoomConfig.Builder roomConfigBuilder = RoomConfig.builder(Network.getInstance());
roomConfigBuilder.setMessageReceivedListener(Network.getInstance());
roomConfigBuilder.setRoomStatusUpdateListener(Network.getInstance());
roomConfigBuilder.setAutoMatchCriteria(am);
roomConfigBuilder.setInvitationIdToAccept(mIncomingInvitationId);
RoomConfig roomConfig = roomConfigBuilder.build();
Games.RealTimeMultiplayer.join(game.getGoogleClient(), roomConfig);
// prevent screen from sleeping during handshake
game.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
dialog.dismiss();
// go to game screen
game.setScreen(new CharSelectScreen(game));
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
I solved it, with the short answer being I did not follow the Android Realtime Multiplayer recipe (guidelines) as closely as I should have.
The guidelines calls for easy access to Google Play sign-in, either automatically when starting the app or I'd imagine preferably, a button to sign in. When I added this, my callback onConnected() code worked, the invitation allowed the user to proceed to the designated game screen with a default waiting room pop-up (implementation shown here). I am still debugging the onInvitationReceived() callback, but I suspect that when the invitation is received when the game is open, the game crash means there is something wrong with my implementation.
All in all, I think it was a bit of misunderstanding on my end, the documentation is fairly intuitive. Thank you for helping, and I hope this will help future Google Play Game Services developers.
I have this app where when it navigates to another activity it does a transition animation. Now I have already got that working properly but, to get it to work i have to turn the animation setting on my phone on. I have been searching on Google and I can"t seem to find solution to my problem. So my problem is this,is it possible to turn this setting on from within the app, with a code, instead of having to manually do it?
Here is the code but as i have said above this works perfectly and I'm using a Telstra next G Huawei phone, just want to no if i can code it so i can turn the animation setting on if i decide to put it on a different phone.
//Button to restart from beginning:
//Declaring the button for OnClickListener and EditText to send data:
private void Restart() {
Button Next = (Button)findViewById(R.id.restart3);
Next.setOnClickListener(new View.OnClickListener() {
//The action the button takes when clicked:
#Override
public void onClick(View v) {
//Goes back to the start of app:
Intent i = new Intent(Height.this, Page_1.class);
//clears the stack of all Activities that were open before this one so that they don't stack up:
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
//The transition animation when going onto next page:
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
// to end the current activity:
finish();
}
});
}
I have used the code on this Android developers page to create a time picker when a button is pressed. However, I'm not getting the right look for it. I'm targeting my app to API 18 and the minimum is 10, because I want to support 2.3 due to the high usage. The minimum required SDK doesn't seem to have effect on the problem (I set it to 16):
I'm debugging the application on my HTC One S with Android 4.1.2, API 16. I get this kind of time picker but I want it to look modern, like in the Android developers page linked earlier.
http://www.b2creativedesigns.com/Tutorials/TimePicker/tutorial_timepicker2.png
Why does it use this prehistoric looking time picker?
I create the dialog using the following snippet. I call it from a FragmentActivity.
DialogFragment newFragment = TimePickerFragment.newInstance(2);
newFragment.show(getSupportFragmentManager(), "endtime");
This is the code for TimePickerFragment.
public static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
private static int id;
public static TimePickerFragment newInstance(int _id) {
Bundle args = new Bundle();
args.putInt("id", _id);
id = _id;
TimePickerFragment f = new TimePickerFragment();
f.setArguments(args);
return f;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
id = getArguments().getInt("id");
int hour = start / 60; // start is a global variable, no problems in these
int minute = start % 60;
if(id == 2) {
hour = end / 60;
minute = end % 60;
}
return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
System.out.println(hourOfDay + ":" + minute);
setTime(id, hourOfDay, minute);
}
}
Use ContextThemeWrapper to explicitly provide your Holo-based theme for the Dialog, e.g.
return new TimePickerDialog(
new ContextThemeWrapper(getActivity(), R.style.YourAppStyleInheritingFromHolo),
this, hour, minute, DateFormat.is24HourFormat(getActivity()));
You need to use the Holo theme for the Holo widgets to work in your app. For example :
in your Manifest, under application :
android:theme="#style/AppTheme"
and in your res/values folder :
<style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar">
</style>
while using this in values-v11 and values-v14 :
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.NoActionBar">
</style>
The system will switch between Theme.Light and Theme.Holo.Light depending on the Android version on the device.
You might want to take a look at this library. It is a backported TimePicker from Android 4.2 which works from android 2.1 upwards.
https://github.com/SimonVT/android-timepicker
I have an app that, for now, runs a loop where it updates the game state ~25 times/s and tries so draw it 40 times/s. the update works fine, it shows just a bit more than 25. but on the emulator, the game draws under 20 fps, no matter how much there is to draw. even if I only paint the background green it has low fps.
I sent the app to someone who tested it on his phone, there it runs correctly with 40fps drawing speed and 25fps updating speed.
I tested it on the emulator with different API levels, the drawing fps is always way too slow. I use eclipse. do I have to make any special setting for the emulator or so?
There was another problem too, the guy who tested it on his phone got an error message when starting the app, it said the app wouldn't react and the option for wait and shutdown. after waiting 5-10 seconds the content view would be displayed. I create the content view and assign the variable in the onCreate method, without starting the loop. In the onStart method I set the contentView and start the loop, but it runs an empty while loop until I set a boolean in the onResume method. any ideas?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view= new MainMenu(this); }
protected void onStart() {
super.onStart();
this.setContentView(view);
view.startGameView();
}
public void startGameView() {
loop=new GameLoop(this);
loop.start();
}
protected void onResume() {
super.onResume();
view.resumeGameView();
}
public void resumeGameView() {
loop.b_pause=false;//loop starts to execute code for drawing/updating
}
the code for the activity change:
public void changeActivity(Class c, String str)
{
Intent i=new Intent(this, c);
startActivity(i);
}