2012-08-02 27 views
5

Tôi đang triển khai một Widget có ConfigurationActivity và phải tương thích với Eclair (2.1).ngăn chặn kích hoạt của onUpdate của WidgetProvider

Các documentation về AppWidgetProviders onUpdate phương pháp tiểu bang rõ ràng rằng:

... .Tuy nhiên, nếu bạn đã tuyên bố tình Hoạt động cấu hình, phương pháp này không được gọi khi người dùng thêm các Widget App, nhưng được gọi là cho các bản cập nhật tiếp theo. Đó là trách nhiệm của hoạt động cấu hình để thực hiện cập nhật đầu tiên khi cấu hình được thực hiện. (Xem phần Tạo hoạt động cấu hình tiện ích ứng dụng bên dưới.)

Thật không may điều này không đúng (ít nhất là đối với Nexus S của tôi với Jellybean). Trong Fact onUpdate được gọi là trướconCreate các trình kích hoạt ConfigurationActivity của tôi. Tôi muốn biết, nếu có hành vi tương tự trên các điện thoại khác và nếu có thể ngăn chặn cuộc gọi onUpdate bên trong Nhà cung cấp của tôi?

Giải pháp của tôi là lưu trữ cờ trong SharedPreferences bên trong WidgetConfigurationActivity của tôi với AppWidgetId cụ thể đó. Nếu nó không có ở đó, tôi có thể giả định rằng ConfigurationActivity không được gọi trước. Điều này làm việc, nhưng là trong quan điểm của tôi Xem thực sự xấu xí. Nếu tôi không thể ngăn chặn onUpdate kích hoạt, có giải pháp nào tốt hơn không?

+0

có nó được gọi. Chỉ là một phần tài liệu không đúng - thậm chí đôi khi Google cũng gặp phải những điều sai trái. –

+0

Tôi đã nhìn thấy onUpdate được gọi mỗi lần trước khi tạo hoạt động cấu hình, bất kể phiên bản Android, thiết bị hoặc trình giả lập –

Trả lời

4

Có, onUpdate() được gọi khi bạn thêm tiện ích trên màn hình chính. Xem ở đây:

http://developer.android.com/reference/android/appwidget/AppWidgetProvider.html

http://developer.android.com/reference/android/appwidget/AppWidgetManager.html#ACTION_APPWIDGET_UPDATE

Tôi không chắc chắn nếu có một cách để không kích hoạt nó khi một widget được tạo ra. Nhưng bạn có thể ngăn chặn nó kích hoạt lại bằng cách đặt trường "updatePeriodMillis" trong tệp XML Thông tin Widget thành hoặc chỉ để nó trống.

Một cách khác là lưu trữ ID tiện ích ở đâu đó. Bây giờ bất cứ khi nào một widget mới được thêm vào, trong lớp người nhận của bạn, hãy kiểm tra xem ID đã tồn tại hay chưa. Nếu nó không tồn tại (có nghĩa là một widget mới), sau đó không thực thi bất kỳ mã nào. Ngoài ra, hãy xóa ID tiện ích khỏi hồ sơ của bạn bất cứ khi nào tiện ích bị xóa. Vì có khả năng bạn đã xóa một tiện ích, sau đó thêm một tiện ích con mới có cùng ID như cũ.

Hy vọng điều đó sẽ hữu ích!

EDIT: Trong phương pháp onReceive() trong lớp nhận của bạn, làm điều này:

public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); 
    if(appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) 
    { 
     super.onReceive(context, intent); 
    } 

} 

Khi một widget được chọn đầu tiên trong danh sách Widgets, appWidgetId của nó sẽ bằng INVALID_APPWIDGET_ID cho đến khi nó được thêm vào trên màn hình chính. Vì "super.onReceive()" gọi phương thức onUpdate() khi một widget được chọn, onUpdate() sẽ không được gọi là lần đầu tiên.

+0

Tôi thực sự tự hỏi: Update-Doc: 'Điều này có thể được gửi để phản hồi một phiên bản mới cho nhà cung cấp AppWidget này được khởi tạo, khoảng thời gian cập nhật được yêu cầu đã hết hiệu lực hoặc khởi động hệ thống.' ** VS ** 'nếu bạn đã khai báo Hoạt động cấu hình, phương thức này không được gọi khi người dùng thêm App Widget.' Tôi đã đặt updateInterval thành "0", và tôi đã làm, những gì bạn đề nghị (lưu trữ bên trong SharedPreferences của Id). –

+0

Tìm cách không gọi onUpdate() lần đầu tiên. Kiểm tra câu trả lời EDITED của tôi. Làm việc tốt của tôi tôi chỉ thực hiện giống nhau trong ứng dụng của tôi. –

+0

Tôi không nhận được 'AppWidgetManager.INVALID_APPWIDGET_ID' lần đầu tiên Nhà cung cấp của tôi kích hoạt. Trong thực tế nó là Id chính xác, giống như vậy, mà 'AppWidgetConfigActivity' của tôi sẽ nhận được. (JellyBean Galaxy Nexus) –

0

Tôi cũng gặp lỗi này.

Thậm chí tôi đã cài đặt updatePeriodMillis thành 0. Cập nhật của tôi đang chạy trước khi tôi bắt đầu Cấu hình hoạt động của tiện ích con. Tôi nghĩ rằng đây là một lỗi trong widget android.

0

tôi giải quyết vấn đề này bằng cách thêm một hành động đến mục đích trong onUpdate sau đó làm một nếu séc onReceive để xem nếu phụ tùng được nhấp:

tôi thêm intentClick.setAction(WIDGET_CLICKED); mà chỉ được kích hoạt khi nhấn vào widget.

public class WidgetProvider extends AppWidgetProvider { 

    private static final String TAG = WidgetProvider.class.getSimpleName(); 
    private static String WIDGET_CLICKED = "widget_clicked"; 

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    Log.e(TAG, "onUpdate()"); 

    remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 
    watchWidget = new ComponentName(context, WidgetProvider.class); 

    Intent intentClick = new Intent(context, WidgetProvider.class); 
    intentClick.setAction(WIDGET_CLICKED); 
    intentClick.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, "" + appWidgetIds[0]); 

    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetIds[0], intentClick, 0); 
    remoteViews.setOnClickPendingIntent(R.id.img_btn, pendingIntent); 
    remoteViews.setInt(R.id.img_btn, "setBackgroundResource", R.drawable.play); 

    appWidgetManager.updateAppWidget(watchWidget, remoteViews); 
} 

@Override 
public void onReceive(Context context, Intent intent) { 
    super.onReceive(context, intent); 

    Log.e(TAG, "onReceive()"); 
    Bundle extras = intent.getExtras(); 

    //If AND ONLY IF WIDGET_CLICKED 
    if (extras != null && intent.getAction().equals(WIDGET_CLICKED)) { 
     remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 

     //If isPlaying 
     if (isPlaying) { 
      //setBackground as PLAY 
      remoteViews.setInt(R.id.img_btn, "setBackgroundResource", R.drawable.play); 
      isPlaying = false; 

      Intent i = new Intent(context, MediaPlayerService.class); 
      i.putExtra("command", "stopSong"); 
      context.startService(i); 

      //If NOT playing 
     } else { 
      //setBackground as STOP 
      remoteViews.setInt(R.id.img_btn, "setBackgroundResource", R.drawable.stop); 
      isPlaying = true; 

      Intent i = new Intent(context, MediaPlayerService.class); 
      i.putExtra("command", "playRandomSong"); 
      context.startService(i); 
     } 

     watchWidget = new ComponentName(context, WidgetProvider.class); 

     (AppWidgetManager.getInstance(context)).updateAppWidget(watchWidget, remoteViews); 
    } 
} 
Các vấn đề liên quan