2012-03-17 24 views
28

Điều này có vẻ như nó phải đơn giản, nhưng tôi không tìm thấy câu trả lời ở bất cứ đâu. Tôi có một ứng dụng Android thực hiện các tác vụ mạng trong nền. Nếu lỗi xuất hiện trở lại, tôi muốn hiển thị hộp thoại báo lỗi. Khi công việc trả về, tôi không biết Hoạt động nào ở tiền cảnh. Dựa trên this post, có vẻ như chúng tôi không thể sử dụng ngữ cảnh ứng dụng để hiển thị hộp thoại (và thực sự tôi gặp sự cố nếu tôi thử).Làm cách nào để hiển thị hộp thoại trong Android mà không có ngữ cảnh Hoạt động?

Vậy làm cách nào để có được bối cảnh của hoạt động hiện tại? Một lần nữa, người nhận nhiệm vụ mạng đang chạy trong ngữ cảnh Ứng dụng, không phải trong một Hoạt động cụ thể. Bất kỳ ý tưởng nào khác?

Chỉnh sửa: Tôi cần làm rõ. Tôi không muốn hiển thị hộp thoại báo lỗi nếu tôi không phải là ứng dụng nền trước. Tôi chỉ quan tâm đến trường hợp ứng dụng của chúng tôi đang ở nền trước.

+0

Bạn có thể sử dụng [Bánh mì nướng] (http://developer.android.com/reference/android/widget/Toast.html). Afaik không có cách nào để hiển thị một Dialog w/o là ứng dụng foreground đang hoạt động. – zapl

Trả lời

20

Nếu lỗi xuất hiện trở lại, tôi muốn hiển thị hộp thoại báo lỗi.

Vui lòng chỉ thực hiện việc này nếu bạn biết rằng người dùng đang chủ động sử dụng ứng dụng của bạn. Người dùng sẽ rất khó chịu nếu bạn ngắt lời họ ở giữa một thứ khác (chơi trò chơi, xem phim, đọc sách).

Vậy làm cách nào để tôi có được bối cảnh của hoạt động hiện tại?

Bạn không. Tối đa, bạn cho phép hoạt động hiện tại biết rằng nó cần phải làm điều gì đó.

Có ý tưởng nào khác không?

Một khả năng là sử dụng một phát sóng ra lệnh, vì vậy nếu bạn có một hoạt động foreground, nó được kiểm soát, nếu không bạn nâng cao một Notification để cho người dùng biết về các vấn đề mà không popping một hộp thoại. Hoạt động nhận được chương trình phát sóng theo thứ tự có thể hiển thị một số AlertDialog hoặc nói cách khác để cho người dùng biết về sự cố. Tôi đã viết về các chi tiết về cách thực hiện điều này in a blog post (và a book chapter, cho vấn đề đó) và here is a sample application trình diễn kỹ thuật này.

Hoặc, có cuộc gọi dịch vụ startActivity() để bắt đầu a dialog-themed activity.

+0

Nếu anh ta không có bối cảnh, làm thế nào anh ấy có thể tạo và kích hoạt một thông báo? Afaik một thông báo đòi hỏi một bối cảnh được tạo ra? Tôi đang chạy một chuỗi nền mà không bị ràng buộc với bất kỳ hoạt động nào - do đó tôi không có cách nào để nắm bắt bối cảnh hoạt động để bắt đầu thông báo ngay từ đầu. – AgentKnopf

+0

@Zainodis: "Tôi đang chạy một chuỗi nền không bị ràng buộc với bất kỳ hoạt động nào" - đó là lỗi. Bạn nên có nó được quản lý bởi một số thành phần, chẳng hạn như một dịch vụ. Sau đó, 'Service' là' Context' của bạn để theo dõi những gì tôi đã viết trong câu trả lời của mình. – CommonsWare

+0

Cảm ơn gợi ý - chúng tôi từng có một dịch vụ cho nó (chủ đề nền xử lý các kết nối máy chủ) - sau đó chúng tôi quay trở lại một chuỗi nền, bởi vì đôi khi dịch vụ của chúng tôi bị giết (bởi os chúng tôi giả định, vì không có ngoại lệ hoặc những thứ tương tự gây ra sự thất bại đột ngột) vì không có lý do rõ ràng (đó là một trường hợp không có trong trường hợp của chúng tôi). – AgentKnopf

0

Loại tác vụ mạng nào đang diễn ra trong nền. Tôi sẽ đề nghị có thể xem xét lại thiết kế. Có lẽ một thông báo sẽ tốt hơn? Hoặc có thể là màn hình "tóm tắt kết quả". Là một người sử dụng Tôi sẽ thay vì một tín hiệu không gây nhầm lẫn của lỗi nếu tôi không tích cực chờ đợi nhiệm vụ hoàn thành.

6

Tôi đã tạo một lớp trợ giúp triển khai ý tưởng của CommonsWare. Các hoạt động muốn hiển thị cảnh báo chỉ cần gọi Alerts.register() và Alerts.unregister(). Sau đó, bất kỳ ai cũng có thể gọi Alerts.displayError().

Nhận xét chào mừng.

public class Alerts { 

    private static class AlertReceiver extends BroadcastReceiver { 

     private static HashMap<Activity, AlertReceiver> registrations; 
     private Context activityContext; 

     static { 
      registrations = new HashMap<Activity, AlertReceiver>(); 
     } 

     static void register(Activity activity) { 
      AlertReceiver receiver = new AlertReceiver(activity); 
      activity.registerReceiver(receiver, new IntentFilter(MyApplication.INTENT_DISPLAYERROR)); 
      registrations.put(activity, receiver); 
     } 

     static void unregister(Activity activity) { 
      AlertReceiver receiver = registrations.get(activity); 
      if(receiver != null) { 
       activity.unregisterReceiver(receiver); 
       registrations.remove(activity); 
      } 
     } 

     private AlertReceiver(Activity activity) { 
      activityContext = activity; 
     } 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      abortBroadcast(); 
      String msg = intent.getStringExtra(Intent.EXTRA_TEXT); 
      displayErrorInternal(activityContext, msg); 
     } 
    } 

    public static void register(Activity activity) { 
     AlertReceiver.register(activity); 
    } 

    public static void unregister(Activity activity) { 
     AlertReceiver.unregister(activity); 
    } 

    public static void displayError(Context context, String msg) { 
     Intent intent = new Intent(MyApplication.INTENT_DISPLAYERROR); 
     intent.putExtra(Intent.EXTRA_TEXT, msg); 
     context.sendOrderedBroadcast(intent, null); 
    } 

    private static void displayErrorInternal(Context context, String msg) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(context); 
     builder.setTitle("Error") 
       .setMessage(msg) 
       .setCancelable(false) 
       .setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int id) { 
         dialog.cancel(); 
        } 
       }); 
     final AlertDialog alert = builder.create(); 

     alert.show(); 
    } 

} 
+0

Xin chào, Tôi sử dụng lớp này như thế nào, tôi có một vấn đề với điều này. Myapplication là gì? – MRT

+0

MyApplication.INTENT_DISPLAYERROR là một hằng số trên, những gì tôi giả định là, ứng dụng ManicBlowfish đại diện cho một String. Bạn có thể thay thế bằng một Chuỗi bạn chọn. – Jon

1

Tôi cũng gặp sự cố. Tôi tìm ra một giải pháp đơn giản và hiệu quả.Usuallay, chúng tôi có một hoạt động cơ bản được sử dụng để xử lý một số logic phổ biến. Vì vậy, có điều này:

public class BaseActionBarActivity extends ActionBarActivity{ //this BaseActionBarActivity is the Base Act 

    private static BaseActionBarActivity current; 

    @Override 
    protected void onStart() { 
    super.onStart(); 
    current=this; 
    } 


    public static BaseActionBarActivity getCurrentContext() { 
    return current; 
    } 
} 

trường hiện tại là Hành động theo ngữ cảnh hiện tại. Và tôi tin rằng không có câu hỏi rò rỉ bộ nhớ. Nó hoạt động tốt cho tôi! Hy vọng hữu ích

0

Tại sao không sử dụng xe buýt sự kiện (https://github.com/greenrobot/EventBus)?

  1. sự kiện Định nghĩa:

    public class ShowErrorMessageEvent { 
    
        public String errorMessage; 
    
        public ShowErrorMessageEvent(String errorMessage) { 
         this.errorMessage = errorMessage; 
        } 
        public String getErrorMessage() { 
         return this.errorMessage; 
        } 
    } 
    
  2. Chuẩn bị thuê bao cho tất cả các hoạt động mà bạn cần:

    @Override 
    public void onStart() { 
        super.onStart(); 
        EventBus.getDefault().register(this); 
    } 
    
    @Override 
    public void onStop() { 
        EventBus.getDefault().unregister(this); 
        super.onStop(); 
    } 
    
  3. Trong mọi hoạt động, hiển thị hộp thoại nếu sự kiện nhận

    public void onEvent(ShowErrorMessageEvent event) { 
        /* Show dialog with event.getErrorMessage() from background thread */ 
    }; 
    
  4. Trong sợi nền của bạn, gửi sự kiện lỗi:

    EventBus.getDefault().post(new ShowErrorMessageEvent("This is an error message!")); 
    
0

bạn cần phải thiết lập lại loại Window mà thoại kèm theo, như sau:. dialog.getWindow() setType (WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

đừng quên tuyên bố quyền "android.permission.SYSTEM_ALERT_WINDOW" trong tệp kê khai của bạn.

1

Dưới đây là triển khai sẽ cho phép hiển thị AlertDialog trên đầu hoạt động hiện tại (đây là ví dụ về hộp thoại tin nhắn, nhưng cũng có thể được sử dụng cho cảnh báo).

public class AlertsDialogue 
{ 
    private AlertDialog.Builder alertDialogBuilder; 
    private AlertDialog alert; 

    public AlertsDialogue(Context context, String title, String message) 
    { 
     alertDialogBuilder = new AlertDialog.Builder(context); 
     alertDialogBuilder.setTitle(title); 
     alertDialogBuilder.setIcon(R.drawable.ic_launcher); 
     alertDialogBuilder.setMessage(message) 
      .setCancelable(false) 
      .setPositiveButton(context.getString(R.string.text_ok), new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) 
       { 
        alert.dismiss(); 
       } 
      }); 

     alert = alertDialogBuilder.create(); 
     Window window = alert.getWindow(); 
     if (window != null) 
     { 
      // the important stuff.. 
      window.setType(WindowManager.LayoutParams.TYPE_TOAST); 
      alert.show(); 
     } 
     else 
      Toast.makeText(context, message, Toast.LENGTH_LONG).show(); 
    } 
} 

Hộp thoại sẽ được hiển thị ngay cả khi ngữ cảnh được khởi tạo không còn hoạt động, giống như Toast.

Gọi với new AlertsDialogue(MyActivity.this, "title", "message");

Không yêu cầu thêm quyền trong tệp AndroidManifest.

Các vấn đề liên quan