2013-06-12 4 views
5

में एक गैर गतिविधि वर्ग से संवाद चेतावनी दिखाएं मैं एक non-activity वर्ग DeviceAdminReceiverSample की विधि onDisabled को AlertDialogManager वर्ग के माध्यम से एक चेतावनी संवाद दिखाना चाहते हैं, लेकिन जब भी मुझे लगता है कि विधि के माध्यम से alertDialog फोन यह पाठएंड्रॉयड

निम्नलिखित के साथ त्रुटि उत्पन्न

त्रुटि

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); 
} 
+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 ने सुझाव दिया है, सबसे अच्छा तरीका 'संदर्भ' का उपयोग करने के बजाय पैरामीटर में 'गतिविधि' के साथ काम करना सबसे अच्छा तरीका है।

अपनी व्यक्तिगत कक्षा में, केवल अपने कन्स्ट्रक्टर में एक अनिवार्य पैरामीटर => सार्वजनिक शून्य कन्स्ट्रक्टरऑफ द क्लास (गतिविधि गतिविधि) {...} के रूप में गतिविधि के लिए पूछें।

जब आप अपनी गतिविधि में निर्माता को कॉल करते हैं, तो बस इस पैरामीटर को इंगित करें और आप सीधे कक्षा के अंदर इसके साथ काम करने में सक्षम होंगे।

फिर आप अपनी कक्षा में अपनी अलर्टडिअलॉग विधि में इस 'गतिविधि' की जानकारी का उपयोग कर सकते हैं क्योंकि सुनील को वांछित गतिविधि में सही ढंग से संकेत दिया जाना चाहिए।

उम्मीद है कि यह मदद करता है ... और सुनिश्चित करें कि यह काम करेगा! ; ओ)

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

आप हमेशा एप्लिकेशन में कहीं भी आप एक रजिस्टर कर सकते हैं से वर्तमान गतिविधि प्राप्त करना चाहते हैं आपके आवेदन उदाहरण पर ActivityLifecycle कॉलबैक।

यहां एक अनचाहे कार्यान्वयन है जो आपको करीब ले सकता है।

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

फायदे आप हमेशा अपने वर्तमान गतिविधि पर नज़र रख सकते हैं, लेकिन इसकी एक छोटी सी भी overkill हैं गतिविधि के भीतर से संवाद को संभालने के लिए।

+0

एक सिंगलटन वेबव्यू और एक MutableContextWrapper के साथ काम करता है। – norbDEV

0

यहां इस कार्य को ठीक से करने का एक त्वरित तरीका है जिसने मेरे लिए नौकरी की है। असल में, आप क्या करेंगे एक नया धागा बनाओ।


  1. एक प्रकार है कि मूल गतिविधि वर्ग से मेल खाता है के साथ एक सार्वजनिक और स्थैतिक चर घोषित करें।

    public static Activity1 activity;

Activity1 वर्ग कि चर में रहता है।


  1. विधि onCreate(); बुला पर, बराबर हो चर सेट गतिविधि के संदर्भ में, अन्यथा के रूप में जाना जाता है यह

उदाहरण:

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


3. जब से हम अब गतिविधि के संदर्भ है, हम यह समारोह के अंदर runOnUiThread(); विधि का उपयोग कर एक चेतावनी संवाद के साथ एक समारोह बनाने के लिए उपयोग कर सकते हैं जो चेतावनी संवाद को बुलाएगा। हम runOnUiThread(); के लिए आवश्यक चलने योग्य क्रिया के लिए new Runnable() का उपयोग करेंगे, और अलर्ट संवाद वास्तव में खोलने के लिए, हम एक चलने योग्य आइटम के रन फ़ंक्शन को ओवरराइड करेंगे और कोड को अलर्ट संवाद के लिए रखें।

उदाहरण समारोह:

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

आशा इस मदद करता है :)