Показать диалоговое предупреждение от неактивного класса в Android

android android-alertdialog

48361 просмотра

7 ответа

812 Репутация автора

Я хочу показать диалог оповещения через AlertDialogManagerкласс методу non-activityкласса , но всякий раз, когда я вызываю через этот метод, он генерирует ошибку со следующим текстомDeviceAdminReceiverSampleonDisabledalertDialog

ошибка

06-12 12:01:19.923: E/AndroidRuntime(468): FATAL EXCEPTION: main
06-12 12:01:19.923: E/AndroidRuntime(468): java.lang.RuntimeException: Unable to start           
receiver com.android.remotewipedata.DeviceAdminReceiverSample:   
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not   
for an application

Я знаю, что проблема с contextвещью, но я не знаю, что туда поставить, чтобы она работала, я пытался this, getApplicationContext()но все напрасно. Мой код для обоих классов ниже

AlertDialogManager

public class AlertDialogManager {

public void showAlertDialog(Context context, String title, String message,
        Boolean status) {
    final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setTitle(title);
    alertDialog.setMessage(message);

    if (status != null)
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                alertDialog.dismiss();
            }
        });
    alertDialog.show();
}

}

DeviceAdminReceiverSample

public class DeviceAdminReceiverSample extends DeviceAdminReceiver {
static final String TAG = "DeviceAdminReceiver";
AlertDialogManager alert = new AlertDialogManager();

/** Called when this application is no longer the device administrator. */
@Override
public void onDisabled(Context context, Intent intent) {
    super.onDisabled(context, intent);
    Toast.makeText(context, R.string.device_admin_disabled,
            Toast.LENGTH_LONG).show();
    // intent.putExtra("dialogMessage", "Device admin has been disabled");
    // intent.setClass(context, DialogActivity.class);
    // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    // context.startActivity(intent);
    alert.showAlertDialog(context, "Alert",
            "Device admin has been disabled", true);
}
Автор: Saqib Источник Размещён: 12.06.2013 07:06

Ответы (7)


13 плюса

68580 Репутация автора

Решение

Проблема в том, You can show AlertDialogs from Activity onlyчто Это не проблема контекста.

Хотя показывать диалог от получателя не очень хорошая идея (лучше использовать уведомление), но если вы хотите это сделать, вы можете создать действие в виде диалога и показать

Автор: Pankaj Kumar Размещён: 12.06.2013 07:10

1 плюс

6433 Репутация автора

вызвать этот метод в классе деятельности

public static void showAlert(Activity activity, String message) {

        TextView title = new TextView(activity);
        title.setText("Title");
        title.setPadding(10, 10, 10, 10);
        title.setGravity(Gravity.CENTER);
        title.setTextColor(Color.WHITE);
        title.setTextSize(20);

        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        // builder.setTitle("Title");
        builder.setCustomTitle(title);
        // builder.setIcon(R.drawable.alert_36);

        builder.setMessage(message);

        builder.setCancelable(false);
        builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();

            }

        });

        AlertDialog alert = builder.create();
        alert.show();
    }
Автор: Sunil Kumar Размещён: 12.06.2013 07:12

0 плюса

1830 Репутация автора

Как предположил AJAY, лучше всего работать с параметром «Activity» вместо использования «context».

В вашем личном классе просто запросите активность в его конструкторе в качестве обязательного параметра => public void constructorOfTheClass (Activity activity) {...}.

Когда вы вызываете конструктор в вашем Activity, просто укажите этот параметр, и вы сможете работать с ним внутри класса напрямую.

Затем вы можете использовать эту информацию об «действии» в вашем методе AlertDialog в вашем классе, поскольку SUNIL заметил, что правильно запрашивается в желаемом действии.

Надеюсь, это поможет ... и быть уверенным, что это сработает! ; О)

Автор: XLE_22 Размещён: 01.09.2014 07:48

39 плюса

2860 Репутация автора

Просто добавьте это перед вашим alertDialog.show();

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

или попробуйте следующее, если выше не сработало:

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL); 

и используйте это разрешение:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Автор: Eliran Kuta Размещён: 04.07.2015 02:18

6 плюса

476 Репутация автора

Если вы всегда хотите получать текущую активность из любого места в приложении, вы можете зарегистрировать ActivityLifecycleCallback в своем экземпляре приложения.

Вот непроверенная реализация, которая может приблизить вас.

public class TestApp extends Application {

    private WeakReference<Activity> mActivity = null;

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                mActivity = new WeakReference<Activity>(activity);
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                mActivity.clear();
            }

            /** Unused implementation **/
            @Override
            public void onActivityStarted(Activity activity) {}

            @Override
            public void onActivityResumed(Activity activity) {}
            @Override
            public void onActivityPaused(Activity activity) {}

            @Override
            public void onActivityStopped(Activity activity) {}

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
        });
    }

    public Activity getCurrentActivity() {
        return mActivity.get();
    }

}

Затем, чтобы использовать это в вашем приложении, вы должны сделать такой звонок ...

Activity activity = ((TestApp)getApplicationContext()).getCurrentActivity(); 

Преимущества в том, что вы всегда можете отслеживать свою текущую активность, однако это слишком излишне для простой обработки диалогов изнутри действия.

Автор: Chris Sullivan Размещён: 08.06.2016 09:33

-2 плюса

26 Репутация автора

Вот быстрый метод правильного выполнения этой задачи, который сделал эту работу для меня. По сути, вы просто создадите новую тему.


  1. Объявите открытую и статическую переменную с типом, который соответствует исходному классу активности.

    public static Activity1 activity;

Activity1 - это класс, в котором находится переменная.


  1. После вызова метода onCreate();установите переменную равной контексту действия, иначе известного как this .

Пример:

@Override 
    protected void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );
    activity = this;
}


3. Поскольку у нас теперь есть контекст действия, мы можем использовать его для создания функции с диалоговым окном оповещения, используя runOnUiThread();метод внутри функции, который будет вызывать диалоговое окно оповещения. Мы использовали бы new Runnable()для выполняемого действия, необходимого для runOnUiThread();, и чтобы фактически открыть диалоговое окно предупреждения, мы бы переопределили функцию запуска выполняемого элемента и поместили туда код для диалогового окна предупреждения.

Пример функции:

public static void exampleDialog(){
Activity1.activity.runOnUiThread(new Runnable){
@Override
    public void run(){
    //alert dialog code goes here.  For the context, use the activity variable from Activity1.
        }
    }
}

Надеюсь это поможет :)

Автор: lighthouse64 Размещён: 09.04.2017 07:52

0 плюса

142 Репутация автора

Вот что я сделал и использовал:

myDialog.java:

import android.app.Activity;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class myDialog {
    private Activity mActivity;

    myDialog(Activity a) {
        this.mActivity = a;
    }

    @SuppressWarnings("InflateParams")
    public void build(String title, String msg) {
        LayoutInflater inflater = LayoutInflater.from(mActivity);
        View subView = inflater.inflate(R.layout.dialog_box_text, null);
        final TextView message = subView.findViewById(R.id.message);
        message.setText(msg);
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        builder.setTitle(title);
        builder.setView(subView);
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }
}

dialog_box_text.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="  "
        android:maxLines="1"
        android:textColor="@color/colorBlack" />
</LinearLayout>

Пример кода:

public class MainActivity extends AppCompatActivity {
    private myDialog md;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        md = new myDialog(this);

...

        md.build("Title", "Message");
Автор: linuxgnuru Размещён: 04.04.2018 05:01
Вопросы из категории :
32x32