I am trying to create an AlertDialog
, I have done this hundred of times but this time it is not working. I have this code on my onResume()
method in my activity:
@Override
protected void onResume() {
super.onResume();
if (DEBUG)
Log.i("BrazoRobot", "onResume()");
isSystemRdy = false;
mBluetoothHelper = new BluetoothHelper(this, bluetoothName);
mBluetoothHelper.connect();
mBluetoothHelper.setOnBluetoothConnected(this);
}
The object BluetoothHelper
which is not an Activity class is correctly created and I am passing the activity context to it:
public BluetoothHelper (final Context ctx, final String bluetoothName) {
mActivity = ((Activity)ctx);
this.ctx = ctx;
this.bluetoothName = bluetoothName;
}
The problem is on the connect()
method where I am creating the dialog:
if (!mBluetoothAdapter.isEnabled()) {
AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));
mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (DEBUG)
Log.i("BrazoRobotBT", "Turning on Bluetooth...");
mBluetoothAdapter.enable(); // Enciendo el Bluetooth
}
});
mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (DEBUG)
Log.i("BrazoRobotBT", "Exit");
mActivity.finish();
}
});
mDialog.show();
}
I am getting the following exception at mDialog.show()
. ctx
is the activity context I passed in the constructor, I also tried passing mActivity
which is ((Activity) ctx)
to AlertDialog.Builder
but I get the same exception.
The dialog is to ask user to enable Bluetooth. I know the correct way to do it is using the Built-In method calling startActivityForResult() but I want to have everything inside my custom class and I can't have onActivityResult() on my class if it isn't an Activity, that's why I am doing it on this way.
Why is this happening? AFAIK I am creating the dialog on the UI thread. I also tried creating the dialog in onCreate()
method but it is still the same.
03-06 21:06:20.320: E/WindowManager(31411): Activity com.roboticarm.andres.BrazoRobot has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4130de20 V.E..... R.....ID 0,0-495,244} that was originally added here
03-06 21:06:20.320: E/WindowManager(31411): android.view.WindowLeaked: Activity com.roboticarm.andres.BrazoRobot has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4130de20 V.E..... R.....ID 0,0-495,244} that was originally added here
03-06 21:06:20.320: E/WindowManager(31411): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
03-06 21:06:20.320: E/WindowManager(31411): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
03-06 21:06:20.320: E/WindowManager(31411): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.Dialog.show(Dialog.java:281)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
03-06 21:06:20.320: E/WindowManager(31411): at com.bluetoothutils.andres.BluetoothHelper.connect(BluetoothHelper.java:119)
03-06 21:06:20.320: E/WindowManager(31411): at com.roboticarm.andres.BrazoRobot.onResume(BrazoRobot.java:247)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1185)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.Activity.performResume(Activity.java:5217)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2862)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2901)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2364)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.ActivityThread.access$600(ActivityThread.java:153)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
03-06 21:06:20.320: E/WindowManager(31411): at android.os.Handler.dispatchMessage(Handler.java:99)
03-06 21:06:20.320: E/WindowManager(31411): at android.os.Looper.loop(Looper.java:137)
03-06 21:06:20.320: E/WindowManager(31411): at android.app.ActivityThread.main(ActivityThread.java:5204)
03-06 21:06:20.320: E/WindowManager(31411): at java.lang.reflect.Method.invokeNative(Native Method)
03-06 21:06:20.320: E/WindowManager(31411): at java.lang.reflect.Method.invoke(Method.java:511)
03-06 21:06:20.320: E/WindowManager(31411): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)
03-06 21:06:20.320: E/WindowManager(31411): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
03-06 21:06:20.320: E/WindowManager(31411): at dalvik.system.NativeStart.main(Native Method)
EDIT 1 (onWindowFocusChanged)
Tried this code as suggested:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
// Conecto al dispositivo bluetooth
mBluetoothHelper = new BluetoothHelper(this, "linvor");
mBluetoothHelper.connect();
if(DEBUG) Log.i("BrazoRobotBT", "Interface");
mBluetoothHelper.setOnNewBluetoothDataReceived(this);
setPreferences();
// Indico que entro en el Analizador lógico
mBluetoothHelper.write(logicAnalyzerMode);
}
}
But I keep getting exactly the same error.
EDIT 2 (Activity test)
I have tried creating a Dialog in onCreate() and onResume() in an Activity and it is created perfectly with this simple code:
public class CustomDialog extends Activity{
private static final boolean DEBUG = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder mDialog = new AlertDialog.Builder(this);
mDialog.setTitle(getString(R.string.BTRequestTitle));
mDialog.setMessage(getString(R.string.BTRequestSummary));
mDialog.setPositiveButton(getString(R.string.Yes), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
}
});
mDialog.setNegativeButton(getString(R.string.No), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(DEBUG) Log.i("BrazoRobotBT", "Exit");
}
});
mDialog.show();
}
}
But, if I put this code inside my class method called from my Activity I get the exception.
EDIT 3 (Strange Fact)
This is my connect() method where I get the exception when I call it from my Activity and the Dialog is shown:
public void connect (){
// Compruebo que el dispositivo tenga Bluetooth
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Si no hay Bluetooth en el dispositivo muestro un dialogo alertando al usuario y salgo de la Activity
AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
dialog.setTitle(ctx.getString(R.string.NoBTAlertTitle));
dialog.setMessage(ctx.getString(R.string.NoBTAlertText));
dialog.setPositiveButton(ctx.getString(R.string.Ok), new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
mActivity.finish(); // Cierro porque no existe un módulo Bluetooth
}
});
}
// Si el dispositivo tiene Bluetooth me conecto
else{
// Compruebo que el Bluetooth esté activado, sino pido al usuario que lo active
if (!mBluetoothAdapter.isEnabled()) {
//mActivity.startActivity(new Intent(mActivity, CustomDialog.class));
AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));
mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
mBluetoothAdapter.enable(); // Enciendo el Bluetooth
}
});
mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(DEBUG) Log.i("BrazoRobotBT", "Exit");
mActivity.finish();
}
});
mDialog.show();
}
// Compruebo si el dispositivo no esta en los dispositivos emparejados (paired)
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// Loop a travez de los dispositivos emparejados (paired)
for (BluetoothDevice device : pairedDevices) {
if(DEBUG) Log.i("BrazoRobotBT", "Name: " + device.getName() + " -- Address: " + device.getAddress());
// Si el dispositivo coincide con el que busco lo asigno
if(device.getName().equals(bluetoothName)){
mBluetoothDevice = device;
// Establezco una conexión Bluetooth para enviar datos
establishConnection();
break;
}
}
}
// Sino salgo, debe estar en los dispositivos emparejados
else{
mActivity.finish();
}
}
}
But if I create a separated method and call from the Activity also, I don't get the exception when the Dialog is shown:
public void dialog(){
AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));
mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
}
});
mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(DEBUG) Log.i("BrazoRobotBT", "Exit");
mActivity.finish();
}
});
mDialog.show();
}
And use it:
mCustomClass.dialog(); // Dialog is shown, no exception