2011-09-25 4 views
3

Je veux faire un widget très simple:Android: Widget cliquable imageview

Il doit être composé d'une seule vue de l'image

1) sur les SMS entrants, il devrait changer l'image

2) cliquez dessus devrait également changer l'image

J'ai essayé de le faire en utilisant ImageButton, mais a échoué: il y avait des problèmes avec le changement de l'image sur l'événement reçu sms: nouvelle image avait mauvaise échelle.

De toute façon maintenant je veux faire un ImageView sans rien d'autre.

Le problème est que je ne peux pas gérer l'événement onClick:

J'ai un service en cours d'exécution qui doit gérer tous les événements: sms reçus et cliquez sur:

fournisseur widget:

public class MyWidgetProvider extends AppWidgetProvider { 
    @Override 
    public void onDisabled(Context context) { 
     context.stopService(new Intent(context, UpdateService.class)); 
     super.onDisabled(context); 
    } 

    @Override 
    public void onEnabled(Context context) { 
     super.onEnabled(context); 
     Intent intent = new Intent(context, UpdateService.class); 
     context.startService(intent); 
    } 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
        int[] appWidgetIds) { 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 
     for (int i = 0; i < appWidgetIds.length; i++) { 
      int appWidgetId = appWidgetIds[i]; 

      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 
      Intent widgetClickIntent = new Intent(context, UpdateService.class); 
      widgetClickIntent.setAction(UpdateService.ACTION_ON_CLICK); 
      PendingIntent pendingIntentViewClick = PendingIntent.getService(context, 0, widgetClickIntent, 0); 
      remoteViews.setOnClickPendingIntent(R.id.widget_imageview, pendingIntentViewClick); 
      appWidgetManager.updateAppWidget(appWidgetId, remoteViews); 
     } 
    } 
} 

service:

public class UpdateService extends Service { 
    static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED"; 
    static final String ACTION_ON_CLICK = "android.MyWidget.ACTION_ON_CLICK"; 

    private final static IntentFilter intentFilter; 

    static { 
     intentFilter = new IntentFilter(); 
     intentFilter.addAction(ACTION_SMS_RECEIVED); 
     intentFilter.addAction(ACTION_ON_CLICK); 
    } 


    public final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      final String action = intent.getAction(); 

      if (action.equals(ACTION_SMS_RECEIVED)) { 
       reactOnSms(context); 
      } 
      if (action.equals(ACTION_ON_CLICK)) { 
       onCLick(context); 
      } 
     } 
    }; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     registerReceiver(broadcastReceiver, intentFilter); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     unregisterReceiver(broadcastReceiver); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    private void reactOnSms(Context context) { 
     // doSomething 
    } 

    public void onCLick(Context context) { 
     // doSomething 
    } 

Manifest:

<receiver a:name="..."...> 
     <intent-filter> 
      <action a:name="android.provider.Telephony.SMS_RECEIVED"/> 
      <action a:name="android.MyWidget.ACTION_ON_CLICK"/> 
     </intent-filter> 
     <meta-data a:name="android.appwidget.provider" 
        a:resource="@xml/my_widget_provider_info"/> 
    </receiver> 
    <service a:name=".UpdateService" 
      a:label="UpdateService"> 

     <intent-filter> 
      <action a:name="android.provider.Telephony.SMS_RECEIVED"/> 
      <action a:name="android.MyWidget.ACTION_ON_CLICK"/> 
     </intent-filter> 
    </service> 

J'ai essayé Clickable widgets in android

Répondre

5

J'ai trouvé la solution.

Désolé pour ceux d'entre vous qui ont lu la question. Trop de code à l'intérieur, je comprends.

Le problème était que UpdateService n'était pas le vrai gestionnaire de l'intention de diffusion. L'implémentation anonyme de BroadcastReceiver a fait tout le travail.

Le problème est dans ce code (widgetProvider):

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
       int[] appWidgetIds) { 
    super.onUpdate(context, appWidgetManager, appWidgetIds); 
    for (int i = 0; i < appWidgetIds.length; i++) { 
     int appWidgetId = appWidgetIds[i]; 

     RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 
     // wrong: 
     // Intent widgetClickIntent = new Intent(context, UpdateService.class); 
     // widgetClickIntent.setAction(UpdateService.ACTION_ON_CLICK); 
     // PendingIntent pendingIntentViewClick = PendingIntent.getService(context, 0, widgetClickIntent, 0); 
     // correct: 
     Intent widgetClickIntent = new Intent(UpdateService.ACTION_ON_CLICK); 
     PendingIntent pendingIntentViewClick = PendingIntent.getBroadcast(context, 0, widgetClickIntent, 0); 
     /////// 
     remoteViews.setOnClickPendingIntent(R.id.widget_imageview, pendingIntentViewClick); 
     appWidgetManager.updateAppWidget(appWidgetId, remoteViews); 
    } 
}