I can't make a widget clickable


Last Updated:

  1. decola

    decola Member This Topic's Starter

    Joined:
    May 22, 2010
    Messages:
    5
    Likes Received:
    0
    Hi all. I am new to Android development.
    I have developed a very simple widget that was meant to interact with the user via an ImageButton.
    What I am trying to do now is as follows. When a user taps the button (after adding the widget to their home screen), I want the phone to dial a certain telephone number. A sort of speed dial for your home screen.
    Unfortunately when I tap the button nothing happens.
    This is the body of my SpeedDialAppWidgetProvider.onUpdate method:




    Log.d("", "beginning of onUpdate");

    final int N = appWidgetIds.length;

    for (int i=0; i<N; i++) {
    int appWidgetId = appWidgetIds;

    Log.d("", "dealing with appWidgetId: " + appWidgetId);

    // Create an Intent to launch ExampleActivity
    Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:1234567"));
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, dialIntent, 0);


    Log.d("", "pendingIntent classname " + pendingIntent.getClass().getName());

    // Get the layout for the App Widget and attach an on-click listener to the button
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.speed_dial_appwidget);
    remoteViews.setOnClickPendingIntent(R.id.dial_icon, pendingIntent);

    Log.d("", "remoteViews classname " + remoteViews.getClass().getName());

    // Tell the AppWidgetManager to perform an update on the current App Widget
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);

    Log.d("", "end of onUpdate");


    I can see the method is called and the result of the logging makes sense.
    The speed_dial_appwidget.xml file is like this:


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    androidrientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >

    <ImageButton id="@+id/dial_icon"
    android:src="@drawable/speed_dial"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    </LinearLayout>
    Can you please help me with this?
    Thanks in advance, Dan
     

    Advertisement
  2. IanGClifton

    IanGClifton Well-Known Member

    Joined:
    Feb 7, 2010
    Messages:
    111
    Likes Received:
    19
    Does your application have CALL_PHONE permission? Is there any other place where you set the remoteviews or call updateAppWidget?
     
  3. decola

    decola Member This Topic's Starter

    Joined:
    May 22, 2010
    Messages:
    5
    Likes Received:
    0
    Yes,
    my Manifest contains:
    <uses-permission android:name="android.permission.CALL_PHONE" />

    I have tried to replace the ImageButton with a Button but that doesn't help.

    Ian, why did you ask me whether there is any other place where I set the remoteviews or call updateAppWidget? Should that matter?

    The problem is the log doesn't display any error while my OnUpdate method is called.
    I really don't know what to do. I am stuck...

    Thanks Ian for your reply. I hope you can follow up.
     
  4. decola

    decola Member This Topic's Starter

    Joined:
    May 22, 2010
    Messages:
    5
    Likes Received:
    0
    I have tried to change the intent to something "less troublesome": now I am just trying to open up a web page:

    Intent dialIntent = new Intent("android.intent.action.VIEW", Uri.parse("http://www.example.com"));

    I click the button and nothing happens.

    So the problem is that the Intent is not triggered at all when I click the widget.
    Should I implement any method other than onUpdate?
     
  5. IanGClifton

    IanGClifton Well-Known Member

    Joined:
    Feb 7, 2010
    Messages:
    111
    Likes Received:
    19
    The reason I ask about the RemoteViews/updateAppWidget is because Android caches your most recently set RemoteViews. That means if you set the onClick listener in one location but in another location you modify the RemoteViews and do not set it, the listener will be gone. For a simple example, say you have a text view and an image. When the app loads, you set the text view and bind a listener to the image and then call updateAppWidget. At this point, everything should work as you'd expect.

    Later, you decide to change the string in the text view, so you get a new RemoteViews object and change the text view's string and then call updateAppWidget. Since the onClick listener was not set up this time, that listener will go away, and your image will seem like it is not responding. Every time you make a call to updateAppWidget, your RemoteViews object should contain everything necessary to construct your widget.

    If that seems okay, you can try using Intent.ACTION_DIAL as the action (instead of Intent.ACTION_CALL) to see if you can get the dialer to come up.

    Does nothing new appear in the log when you tap the dial_icon?
     
  6. decola

    decola Member This Topic's Starter

    Joined:
    May 22, 2010
    Messages:
    5
    Likes Received:
    0
    Hi Ian.

    No, when I tap I can't see any new error in the log.

    As I said, I also tried to use this Intent:
    Intent dialIntent = new Intent("android.intent.action.VIEW", Uri.parse("http://www.example.com"));
    that doesn't require any permission but the problem is still there.

    This is my whole code.



    File AndroidManifest.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.widget.speedDial"
    android:versionCode="1"
    android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
    <receiver android:name="com.example.android.widget.speedDial.SpeedDialAppWidgetProvider" >
    <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
    android:resource="@xml/speed_dial_appwidget_info" />
    </receiver>
    </application>
    <uses-sdk android:minSdkVersion="3" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    </manifest>



    File xml/speed_dial_appwidget_info.xml:
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="72dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="100000"
    android:initialLayout="@layout/speed_dial_appwidget" >
    </appwidget-provider>



    File layout/speed_dial_appwidget.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:eek:rientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
    <Button id="@+id/dial_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    </LinearLayout>



    File SpeedDialAppWidgetProvider.java:
    package com.example.android.widget.speedDial;

    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.util.Log;
    import android.widget.RemoteViews;

    public class SpeedDialAppWidgetProvider extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    Log.d("", "beginning of onUpdate");

    final int N = appWidgetIds.length;

    for (int i=0; i<N; i++) {
    int appWidgetId = appWidgetIds;

    Log.d("", "dealing with appWidgetId: " + appWidgetId);

    // Create an Intent to launch ExampleActivity
    Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:123456789"));
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, dialIntent, 0);


    Log.d("", "pendingIntent classname " + pendingIntent.getClass().getName());

    // Get the layout for the App Widget and attach an on-click listener to the button
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.speed_dial_appwidget);
    remoteViews.setOnClickPendingIntent(R.id.dial_icon, pendingIntent);

    Log.d("", "remoteViews classname " + remoteViews.getClass().getName());

    // Tell the AppWidgetManager to perform an update on the current App Widget
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);

    Log.d("", "end of onUpdate");

    }
    }
    }
     
  7. IanGClifton

    IanGClifton Well-Known Member

    Joined:
    Feb 7, 2010
    Messages:
    111
    Likes Received:
    19
    Hey Decola,

    Try changing your button from:

    <Button id="@+id/dial_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

    to:

    <Button
    android:id="@+id/dial_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

    See if that works for you.
     
    decola likes this.
  8. decola

    decola Member This Topic's Starter

    Joined:
    May 22, 2010
    Messages:
    5
    Likes Received:
    0
    Hi Ian,
    great! It works now.

    Thanks for your great help. You rock, dude!
    :)
     

Share This Page

Loading...