2013-06-12 15 views
5

對話框警告我想通過AlertDialogManager類顯示一個警告對話框到non-activityDeviceAdminReceiverSample的方法onDisabled,但每當我通過這個方法調用alertDialog它與下面的文本顯示從非活性類的Android

生成錯誤

錯誤

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的事情,但我不知道該怎麼把那裏,以便它的工作,我想thisgetApplicationContext()但都是徒勞的。我的兩個類的代碼如下

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); 
} 
+0

創建一個DialogActivity。 –

+0

使用活動對象而不是上下文對象。 – Ajay

回答

10

的問題是 'You can show AlertDialogs from Activity only'。這不是上下文的問題。

雖然這不是從接收機(最好是使用通知),但是如果你想這樣做,你可以創建一個Activity as dialog and show

1

調用此方法在活動課展示對話是個好主意

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

是的,它的正確 – Ajay

+0

謝謝,這個概念幫了我很多, –

0

正如AJAY建議的,最好的方法是在參數中使用「活動」,而不是使用「上下文」。

在你的個人課堂中,只需要在其構造函數中作爲強制性參數請求=> public void constructorOfTheClass(Activity activity){...}。

當您在Activity中調用構造函數時,只需指明該參數,您就可以直接在類中使用它。

然後,您可以在您的課堂內的AlertDialog方法中使用此'活動'信息,因爲SUNIL注意到會在所需的活動中正確提示。

希望它有幫助...並確保它會工作! ; O)

31

之前你alertDialog.show();

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

只需添加這一點,並使用此權限:如果你總是希望從中獲取當前的應用內的任何地方,你可以註冊一個

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 
+0

謝謝,它的工作。你的答案應該被投票。 – VAdaihiep

+1

非常好的發現。謝謝。添加到這個解決方案,根據文檔'允許應用程序使用類型TYPE_SYSTEM_ALERT打開窗口,顯示在所有其他應用程序的頂部。很少的應用程序應該使用此權限;這些窗口用於與用戶進行系統級交互。「因此,我們在使用此解決方案時還需要小心。 –

+0

有同樣的問題,使用這種方式解決它。謝謝 – darthvading

3

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

的優點是你可以隨時保持你當前活動的軌跡,但其有點太大材小用僅用於處理Activity中的對話框。

+0

適用於單身WebView和MutableContextWrapper。 – norbDEV

0

以下是正確執行完成此任務的快速方法。基本上,你會做什麼只是創建一個新的線程。


  1. 聲明一個公共的和靜態變量與類型,原來的活動課相匹配。

    public static Activity1 activity;

活性1是變量存在於類。


  • 一旦調用方法onCreate();,將變量爲等於在活動的背景下,也稱爲,這個
  • 例子:

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

    希望這有助於:)