Native Android UI for using Within LibGdx - java

Hi there StackOverflow!
I had been loocking on a way to Use the native Android Dialogs and Confimation Boxes in Libgdx...
All that i did by now was a Title and an Image under it:
Dialog yourmsgbox = new Dialog("Title", jsons);
yourmsgbox.setBounds(0f,0f,100f,200f);
yourmsgbox.add(choiceImg);
mainClass.addActor(yourmsgbox);
I suck a little at this but all the codes that i find in Google to do that are Or for Desktop or very especific for that Type of game + Even after some tries to copy the code and adapt it to my .java Files im still getting errors....
So if you guys could guide through a step by step ((Or a list Number of online items that i could follow to get this done I WOULD BE VERYY GRATEFULL !!!))
[[My Json file is EXTREMELY BUGGY, so if I could not have to mess with that Stubborn uiskin.json, I would Thank you :]]
Sorry my bad english
Please i'd apreciate a little help!?
UPDATE:: Sorry i have
two MainClasses for this project and i pick the wrong Logcat :)
I just use showMessage(); in the beggining of the create(), it
crashes when i get into the app. Here is what i did:
I Created an Inferface in core Project:
public interface NativeDialogInterface {
void showMessage(final String title, final String message, final String okButtonText);
}
Created AndroidNativeDialog in -android Project folder:
public class AndroidNativeDialog implements NativeDialogInterface {
private Activity activity;
public void initialize(Activity activity) {
this.activity = activity;
}
#Override
public void showMessage(final String title, final String message, final String okButtonText) {
this.activity.runOnUiThread(new Runnable() {
#Override
public void run() {
final AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
alertDialog.setButton(okButtonText, new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface arg0, final int arg1) {
alertDialog.cancel();
}
});
alertDialog.show();
}
});
}
}
*Strange that it says as warning "Method setButton(...) is deprecated"
Then i added new (dialogInterface) in the AndroidLaucher.java:
public class AndroidLauncher extends AndroidApplication {
private AndroidNativeDialog dialogInteface;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
dialogInterface = new AndroidNativeDialog();
initialize(new IndexMain(dialogInteface), config);
}
}
Then in the MainClass what i did was:
btnWindow.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
mainScreen.addActor(andWindow);
dialogInteface.showMessage("TITLE", "ThE MeSsaGe", "Okayy");
Timer.schedule(new Timer.Task() {
#Override
public void run() {
andWindow.setBounds(Gdx.graphics.getWidth(), 0f, 1f, 1f);
}
}, 17);
}
});
I head to that link that "Fuat Coçkun" provided and i learn a lot about these type of structures but it seems i still have something wrongg
Its WORKS perfectly until i click that /\ Button, the button is ok if i delete the showMessage(...);
new LogCat: http://pastebin.com/NbgnyrAJ
Sorry for my bad english.

I can give you example usage of native android AlertDialog with libgdx. Firstly you need an interface in your core Project as follows :
public interface NativeDialogInterface {
void showMessage(final String title, final String message, final String okButtonText);
}
You need different implementations for each of platform you support in your project. Android project implementation will use Dialog, AlertDialog or whatever you want to use as native android component. This example shows AlertDialog implementation:
public class AndroidNativeDialog implements NativeDialogInterface {
private Activity activity;
public void initialize(Activity activity) {
this.activity = activity;
}
#Override
public void showMessage(final String title, final String message, final String okButtonText) {
this.activity.runOnUiThread(new Runnable() {
#Override
public void run() {
final AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
alertDialog.setButton(okButtonText, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
alertDialog.cancel();
}
});
alertDialog.show();
}
});
}
}
You need to call "initialize" method of your instance in your activity(onCreate is proper.) for setting activity field.
You can use any dummy implementation for the Desktop module of your libgdx project. Following implementation only logs the data you passed.
public class DesktopNativeDialog implements NativeDialogInterface {
#Override
public void showMessage(final String title, final String message, final String okButtonText) {
System.out.println("Title : " + title);
System.out.println("Message : " + message);
System.out.println("OkButtonText : " + okButtonText);
}
}
That's all. You should have a field typed NativeDialogInterface in your Core module and call "showMessage" method with your parameter. You will see a console log if you run your application on desktop. You will see native Android alert dialog on your glSurfaceView when you run your application on device/emulator.

I did this and created an expansion for libGDX. You can use it or check the source: https://github.com/TomGrill/gdx-dialogs

Related

Android how to call Activity data type from another class in Main Activity?

I have this code separate class which makes a Snackbar to be displayed within my application, But with my current implementation I am getting a 'java.lang.NullPointerException'. How do I implement it in my main class properly?
here is my snack bar class:
public class SnackBarUtils
{
private static SnackBarUtils mInstance = null;
private Snackbar mSnackBar;
private SnackBarUtils()
{
}
public static SnackBarUtils getInstance()
{
if (mInstance == null)
{
mInstance = new SnackBarUtils();
}
return mInstance;
}
public void hideSnackBar()
{
if (mSnackBar != null)
{
mSnackBar.dismiss();
}
}
public void showProblemSnackBar(final Activity activity, final String message)
{
mSnackBar = Snackbar.make(activity.findViewById(android.R.id.content), message,
Snackbar.LENGTH_INDEFINITE);
// Changing action button text color
View sbView = mSnackBar.getView();
TextView textView = sbView.findViewById(com.google.android.material.R.id.snackbar_text);
mSnackBar.setAction("x", new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Call your action method here
mSnackBar.dismiss();
}
});
textView.setTextColor(Color.WHITE);
sbView.setBackgroundColor(Color.RED);
textView.setMaxLines(3);
mSnackBar.show();
}
}
This is my current implementation within main activity, I have already Initialized the snackbar class like this:
SnackBarUtils snackBarUtils;
and then called it like this:
snackBarUtils.showProblemSnackBar(MainActivity.this, mPlainTextResponse);
what am I doing wrong? Or what is the correct way to do this?
First of all, you would share the stacktrace of the NPE for more context.
For the snackbar utility:
If you are using callbacks, then you can use the utility for displaying a snackbar with that callback as parameter:
interface onProblemSnackbarClickedListener {
void onActionClicked(View view);
}
...
/* inside SnackBarUtils.java */
...
public static void showProblemSnackbar(View view, #StringRes int message, onProblemSnackbarClickedListener listener){
Snackbar mSnackBar = Snackbar.make(view,message,Snackbar.LENGTH_INDEFINITE)
.setAction("x", new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onActionClicked(v);
mSnackBar.dismiss();
}
})
mSnackbar.show();
}
The callback could work for the need to listen to it in the activity/fragment.
For the styling of the Snackbar, you can see this related question:
Style SnackBar in theme app.
Keep in mind the migration from "Support design" to MDC (Material design components), that facilitates the global styling of the snackbar with theme attributes.

Progress bar not showing up till last moment

This is my first android app,
I am calling function result on button click but as its call to findTimeTable takes time i want to show a progress bar but for some reason progress bar fails to show up until last moment just before the dialog box is created which defeats my purpose of showing the progress bar for that time period. In-fact that last moment is only visible when i don't set their visibility back to what it was.
public void result(View view) throws IOException {
findViewById(R.id.loadingPanel).setVisibility(View.VISIBLE);
findViewById(R.id.chooseFile).setVisibility(View.GONE);
findViewById(R.id.chooseDay).setVisibility(View.GONE);
findViewById(R.id.chooseTime).setVisibility(View.GONE);
findViewById(R.id.findFaculty).setVisibility(View.GONE);
String n = findTimetable(index_day, index_time);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("hello" +n);
builder.setCancelable(false);
builder.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i){
}
});
final Dialog mDialog = builder.create();
mDialog.show();
findViewById(R.id.loadingPanel).setVisibility(View.GONE);
findViewById(R.id.chooseFile).setVisibility(View.VISIBLE);
findViewById(R.id.chooseDay).setVisibility(View.VISIBLE);
findViewById(R.id.chooseTime).setVisibility(View.VISIBLE);
findViewById(R.id.findFaculty).setVisibility(View.VISIBLE);
}
I found a relevant answer android progress bar not showing
but as i am not familiar with threads in programming i could not implement it properly on my code.
please help.
Use an AsyncTask for the heavy comupting and add the progress bar in its Pre/Post states, and if you choose to update the GUI from there you need to run that code on the UI Thread.
Example AsyncTask:
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
// Start progressbar
}
#Override
protected String doInBackground(String... params) {
// Computing goes here
return null;
}
#Override
protected void onPostExecute(String result) {
// Stop progressbar
UpdateMyGUI();
}
#Override
protected void onProgressUpdate(Void... values) {
// Update progressbar (?)
}
}
private void updateMyGUI(){
runOnUiThread (new Runnable() {
public void run() {
// Update GUI Here.
}
});
}

Show alert dialog from background process in any activity

How to get result of background process in any Activity?
I'm working with OTA update. App handle that in background with handler. When update is done I have to show alert dialog to the user. I can show it in SettingsActivity where I start with OTA but user can be in any other Activity.
private void checkIsUpdated() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mDevice.getDevice().read(GattUUID.LS_DEVICE_INFORMATION, GattUUID.LC_FIRMWARE, new
BleDevice.ReadWriteListener() {
#Override
public void onEvent(ReadWriteEvent e) {
if (e.wasSuccess()) {
if (firmwareVersion.equals(e.data_string())) {
showAlertDialog("OTA update failed", "Device is not updated");
} else {
showAlertDialog("OTA update is successful.\nDevice is updated to new " +
"firmware!", "Device is updated");
}
Log.i("OTA", "Read firmware is new success");
} else {
Log.e("OTA", "Read firmware is new success");
}
}
});
}
}, 30000);
}
AlertDialog code
private void showAlertDialog(String message, String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.SwipeDialogLight);
builder.setTitle(title)
.setMessage(message)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
if (!alert.isShowing()) {
alert.show();
}
}
As #W4R10CK stated, I thought that too. The BroadcastReceiver might not a very good idea. But later, I gave a thought about it and if you call checkIsUpdated function inside a Service and send the Broadcast from it, it might be a feasible solution.
So basically you need a BaseActivity class and in which you need to have a BroadcastReceiver. You need to register it onResume and again unregister it onPause.
And you need to have an abstract method to be overriden in each of your Activity too.
So your BaseActivity may look like this..
public abstract class BaseActivity extends AppCompatActivity {
private final Context context;
public BaseActivity() {
this.context = setContext();
}
protected abstract Context setContext();
#Override
public void onResume() {
super.onResume();
registerBroadcastReceiver();
}
#Override
public void onPause() {
super.onPause();
unRegisterBroadcastReceiver();
}
// Declare your BroadcastReceiver here
private class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
showAlertDialog(context);
}
}
}
As #rogerwar suggested in the comments, the correct approach is a broadcast receiver.
Vogella has a nice tutorial
Since you want to have it in all activities, you can make a base class for all your activities and in this base class you can register the receiver in the onStart and unregister it in the onStop.

UtteranceProgressListener won't call the functions

I am trying to make a speech powered app, however I have run into a major problem.
My UtteranceProgressListener Class will not call any of the given methods regardless of where I place the Speak method.
Here is my code:
This is my OnCreate Method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
voiceBtn = (Button) findViewById(R.id.startListeningBtn);
voiceBtn.setEnabled(false);
textToSpeech = new TextToSpeech(mContext,new botListener());
}
This is the OnInitListner Imeplementation
public class botListener implements TextToSpeech.OnInitListener{
#Override
public void onInit(int i) {
if(i == TextToSpeech.SUCCESS)
{
int s = textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String s) {
Toast.makeText(getApplicationContext(),"Done Speaking",Toast.LENGTH_SHORT).show();
}
#Override
public void onDone(String s) {
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
}
#Override
public void onError(String s) {
Toast.makeText(getApplicationContext(),"Done Speaking",Toast.LENGTH_SHORT).show();
}
});
Log.d(TAG,String.valueOf(s));
int result = textToSpeech.setLanguage(Locale.ENGLISH);
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
Log.e(TAG,"Language not supported");
Intent installLanguage = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installLanguage);
}
Log.d(TAG,"Started Voice Speaker");
}
else{
Log.e(TAG,"initialization failed");
}
}
}
Now, when I press the button, the event that fires is:
public void initVoiceRecog(View v){
//Toast.makeText(mContext,"Clicked",Toast.LENGTH_SHORT).show();
Speak("hello","1");
// does some other things here after that
}
private void Speak(String text,String identifierID){
if(Build.VERSION.SDK_INT>21) {
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,identifierID);
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, params, identifierID);
}
else{
// ttsMap is a HashMap
ttsMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,identifierID);
textToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH,ttsMap );
}
}
My Question is, after saying hello, it does not fire the OnStart() or the OnError() or the OnDone() methods. Why is this happening?
I tried with the deprecated setOnUtteranceListner() as well, same result. It does not fire any of the methods, the Toasts don't show up.
Please tell a fix or a workaround for this.
The Devices I tried on are:
API 19 Micromax Canvas Nitro
API 21 Samsung S4
API 23(Marshmellow) ASUS Zenfone
I finally figured out why the callbacks were not working. Turns out, they were working and calling on a separate thread. So to execute the normal functionality, call the functions in the 'Activity.this.RunOnUiThread' and put this in the call back fuctions.

Android Safe vs Unsafe Usage of Inner Classes

I'm new to Android development and I've been having a lot of trouble finding ways to make sure my app doesn't leak memory. I've read online that using inner classes can cause memory leaks, especially when they may outlive their Activity. Here are some of the inner classes I use. Which of these, if any, could cause a memory leak?
public class TitleScreenActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_title_screen);
final MyHandler mHandler = new MyHandler(this);
final Intent intent = new Intent(mHandler.mActivity.get(), IntroActivity.class);
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(intent);
mHandler.mActivity.get().finish();
}
}, 2000);
}
private static class MyHandler extends Handler {
public final WeakReference<TitleScreenActivity> mActivity;
public MyHandler(TitleScreenActivity activity) {
mActivity = new WeakReference<>(activity);
}
}
}
I based this code off of what I found in this article. However, I don't think it would be possible for me to make my Runnable static, like they did in the article. Can this code cause a memory leak, even though I finish the Activity in the runnable?
Another example:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.no_tiles);
builder.setPositiveButton(R.string.store, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// start new Activity
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Do nothing, just close dialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
I have trouble believing that this could cause a leak because it doesn't contain an explicit reference to an Activity, View, etc and it (to the best of my knowledge) the dialog gets destroyed when the user clicks a button, so the listeners would be destroyed as well. However, I wanted to make sure.
Last example:
TranslateAnimation translate;
translate = new TranslateAnimation(0, 0, 0, 100);
translate.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
// modify a few variables
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
translate.setDuration(200);
findViewById(R.id.game_board).startAnimation(translate);
I'm not sure if this could cause because theoretically the animation could outlive the Activity it's in.
All help is appreciated, thanks!

Categories