Reputation: 893
I'm trying to implement a "Rate Me" dialog in a game I'm working on, as per the instructions on this page:
http://www.androidsnippets.com/prompt-engaged-users-to-rate-your-app-in-the-android-market-appirater
I think I've implemented everything according to the instructions provided, but when I call the AppRater.showRateDialog(this, null) method my game crashes and I get the following error output in LogCat:
06-20 19:29:34.622: E/AndroidRuntime(25236): FATAL EXCEPTION: GLThread 6087
06-20 19:29:34.622: E/AndroidRuntime(25236): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
06-20 19:29:34.622: E/AndroidRuntime(25236): at android.os.Handler.<init>(Handler.java:121)
06-20 19:29:34.622: E/AndroidRuntime(25236): at android.app.Dialog.<init>(Dialog.java:114)
06-20 19:29:34.622: E/AndroidRuntime(25236): at android.app.Dialog.<init>(Dialog.java:138)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.kittykazoo.distantshores.android.AppRater.showRateDialog(AppRater.java:45)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.kittykazoo.helpers.InputPoller.updateMainMenu(InputPoller.java:140)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.kittykazoo.helpers.InputPoller.update(InputPoller.java:68)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.kittykazoo.gameworld.GameWorld.update(GameWorld.java:141)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.kittykazoo.screens.GameScreen.render(GameScreen.java:20)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.badlogic.gdx.Game.render(Game.java:46)
06-20 19:29:34.622: E/AndroidRuntime(25236): at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:422)
06-20 19:29:34.622: E/AndroidRuntime(25236): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
06-20 19:29:34.622: E/AndroidRuntime(25236): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
Here's the source code for my main Android class:
public class AndroidLauncher extends AndroidApplication {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
DistantShores ds = new DistantShores();
initialize(ds, config);
// Designate AppRater
DistantShores.setAppRater(new AppRater(this));
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
...and the source code for the AppRater class:
public class AppRater implements AppRaterInterface {
private Activity mContext;
SharedPreferences prefs;
SharedPreferences.Editor editor;
private Button b1, b2, b3;
public AppRater(Activity mContext) {
this.mContext = mContext;
prefs = mContext.getSharedPreferences("kk_distantshores_apprater", 0);
editor = prefs.edit();
}
public boolean isTimeoutElapsed() {
if (prefs.getLong("lastShow", System.currentTimeMillis()) >= TIMEOUT)
return true;
return false;
}
public void showRateDialog() {
if (prefs.getBoolean("dontshowagain", false)) {
return;
}
editor.putLong("lastShow", System.currentTimeMillis());
final Dialog dialog = new Dialog(mContext);
dialog.setTitle("Rate " + APP_TITLE);
LinearLayout ll = new LinearLayout(mContext);
ll.setOrientation(LinearLayout.VERTICAL);
final TextView tv = new TextView(mContext);
tv.setText("If you enjoy using " + APP_TITLE
+ ", please take a moment to rate it. Thanks for your support!");
tv.setWidth(240);
tv.setPadding(4, 0, 4, 10);
ll.addView(tv);
b1 = new Button(mContext);
b1.setText("Rate " + APP_TITLE);
b1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final Uri uri = Uri.parse("market://details?id=" + APP_PNAME);
final Intent rateAppIntent = new Intent(Intent.ACTION_VIEW, uri);
if (mContext.getPackageManager().queryIntentActivities(rateAppIntent, 0).size() > 0) {
mContext.startActivity(rateAppIntent);
dialog.dismiss();
} else {
/* the device has no way to handle market urls */
dialog.setTitle("Error!");
tv.setText("No Market app detected. In order to rate this app the Google Play Store must be installed.");
b1.setVisibility(View.GONE);
b2.setVisibility(View.GONE);
b3.setText("Cancel");
}
}
});
ll.addView(b1);
b2 = new Button(mContext);
b2.setText("Remind me later");
b2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialog.dismiss();
}
});
ll.addView(b2);
b3 = new Button(mContext);
b3.setText("No, thanks");
b3.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (editor != null) {
editor.putBoolean("dontshowagain", true);
editor.commit();
}
dialog.dismiss();
}
});
ll.addView(b3);
dialog.setContentView(ll);
dialog.show();
}
}
Upvotes: 0
Views: 95
Reputation: 893
I managed to get it working by encapsulating the dialog code in a runOnUiThread() instance
Upvotes: 0
Reputation: 1858
Your dialogue needs an activity context, looks like you are creating the dialogue in non-ui thread. Please check which context you are passing to dialogue constructor.
Upvotes: 1