it-swarm.com.de

Dialogalarm aus einer Nichtaktivitätsklasse in Android anzeigen

Ich möchte einen Alert-Dialog über AlertDialogManager-Klasse für eine non-activity-Klasse DeviceAdminReceiverSample-Methode onDisabled anzeigen. Wenn ich jedoch alertDialog über diese Methode aufrufe, wird ein Fehler mit folgendem Text generiert

Error

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

Ich weiß, das Problem ist mit context Sache, aber ich weiß nicht, was ich da setzen soll, damit es funktioniert. Ich habe versucht this, getApplicationContext(), aber alles eitel. Mein Code für beide Klassen ist unten

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);
}
8
Saqib

Das Problem ist 'You can show AlertDialogs from Activity only'. Dies ist kein kontextbezogenes Thema. 

Dies ist zwar keine gute Idee, um den Dialog vom Empfänger anzuzeigen(besser ist die Verwendung der Benachrichtigung), aber wenn Sie dies möchten, können Sie eine Aktivität als Dialog und Anzeige erstellen

13
Pankaj Kumar

Fügen Sie dies einfach vor Ihrer alertDialog.show(); hinzu.

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

or try following is above doesn't works:
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL); 

und benutze diese Erlaubnis:

<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
34
Eliran Kuta

Wenn Sie die aktuelle Aktivität immer von überall in der App abrufen möchten, können Sie einen ActivityLifecycleCallback in Ihrer Anwendungsinstanz registrieren. 

Hier ist eine nicht getestete Implementierung, die Ihnen vielleicht näher kommt. 

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();
    }

}

Um dies in Ihrer App zu verwenden, würden Sie einen Anruf wie diesen machen ...

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

Die Vorteile sind, dass Sie Ihre aktuelle Aktivität immer im Auge behalten können, aber es ist ein wenig zu übertrieben, um Dialoge nur innerhalb der Aktivität zu bearbeiten.

6
Chris Sullivan

rufen Sie diese Methode in der Aktivitätsklasse auf

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();
    }
1
Sunil Kumar

Wie AJAY vorgeschlagen hat, ist es am besten, mit dem Parameter 'Activity' zu arbeiten, anstatt den 'Kontext' zu verwenden.

Fragen Sie in Ihrer persönlichen Klasse einfach nach der Aktivität in seinem Konstruktor als obligatorischen Parameter => public void constructorOfTheClass (Aktivitätsaktivität) {...}.

Wenn Sie den Konstruktor in Ihrer Aktivität aufrufen, geben Sie einfach diesen Parameter an, und Sie können direkt in der Klasse damit arbeiten.

Dann können Sie diese Aktivitätsinformationen in Ihrer AlertDialog-Methode in Ihrer Klasse verwenden, da SUNIL festgestellt hat, dass die richtige Aktivität in der gewünschten Aktivität angezeigt wird.

Hoffe, es hilft ... und sei sicher, dass es funktionieren wird! ;O)

0
XLE_22

Hier ist eine schnelle Methode, diese Aufgabe richtig auszuführen, die die Arbeit für mich erledigt hat. Grundsätzlich erstellen Sie einfach einen neuen Thread.


  1. Deklarieren Sie eine öffentliche und statische Variable mit einem Typ, der der ursprünglichen Aktivitätsklasse entspricht.

    public static Activity1 activity;

Activity1 ist die Klasse, in der sich die Variable befindet.


  1. Setzen Sie beim Aufruf der Methode onCreate(); die Variable auf den Kontext der Aktivität, auch bekannt als this .

Beispiel:

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


3. Da wir nun den Kontext der Aktivität haben, können wir damit eine Funktion mit einem Alert-Dialog erstellen, indem Sie die runOnUiThread(); -Methode innerhalb der Funktion verwenden, die den Alert-Dialog aufruft. Wir würden eine new Runnable() für die ausführbare Aktion verwenden, die für runOnUiThread(); erforderlich ist. Damit der Alarmdialog tatsächlich geöffnet werden kann, würden wir die Run-Funktion eines ausführbaren Elements überschreiben und den Code für den Alarmdialog dort einfügen.

Beispielfunktion:

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.
        }
    }
}

Hoffe das hilft :)

0
lighthouse64

Folgendes habe ich gemacht und verwendet:

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>

Beispielcode:

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");
0
linuxgnuru