Search code examples
androidandroid-widgetbroadcastreceiverappwidgetprovider

Android widget works well in emulator but on phone it turns into the Google App widget


I created an Android widget.
In a Genymotion Nexus 4 emulator running Android 4.4.4 everything works well.
On my Nexus 4 device running Android 4.4.4 I put the widget on the home screen and it turns into the Google App widget.
Then it turns into my widget then again into the Google App widget and so on. It does this until I remove the widget from the home screen.
Also I am using parse.com as online storage and on my phone the data doesn't seem to be obtained. I can't really tell for sure because the widget keeps changing.
My widget contains 3 files.
One that extends the application class:

public class MyApp extends Application
{
    private MyModel model;

     @Override
    public void onCreate() {
        Parse.enableLocalDatastore(this);
        ParseObject.registerSubclass(GdbdData.class);
        Parse.initialize(this, "-", "-");

        if(model == null) {
            Intent intent = new Intent(this,GdbdWidgetProvider.class);
            intent.setAction(WidgetUtils.WIDGET_REFRESH_STORAGE);
            intent.putExtra("userId",123);
            sendBroadcast(intent);
        }

        super.onCreate();
    }

One WidgetProvider:

@Override
public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);
    final String action = intent.getAction();
    if (action.equals(WidgetUtils.WIDGET_REFRESH_STORAGE))
    {
        MyApp app = ((MyApp)context.getApplicationContext());
        int userId = intent.getIntExtra("userId",0);
        TryGetModelFromRemoteStorage(userId,context);
    }

}


static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
{
    MyApp app = ((MyApp)context.getApplicationContext());
    MyModel model = app.getModel();

    // Construct the RemoteViews object
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.the_widget);

    PendingIntent clickerPendingIntent = buildButtonPendingIntent(context);

    // I change some textviews and imageviews inside the widget here

    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}

public static PendingIntent buildButtonPendingIntent(Context context) {

    // initiate widget update request
    Intent intent = new Intent();
    intent.setAction(WidgetUtils.WIDGET_UPDATE_ACTION);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    return pendingIntent;
}

And one broadcastreceiver that handles a button on the widget:

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(WidgetUtils.WIDGET_UPDATE_ACTION)) {
        updateWidget(context);
    }
}

private void updateWidget(Context context) {


    MyApp app = ((MyApp)context.getApplicationContext());
    MyModel model = app.getModel();

    //I update some fields in the model based on some business rules at this point

    MyWidgetProvider.SendUpdateMessageToWidgets(context);


}

Does anyone know what I am doing wrong?

Edit 1: Adding manifest file as requested

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.my.app.main" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:name="MyApp"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name=".GdbdWidgetProvider" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/the_widget_info" />
        </receiver>
        <receiver
            android:name=".TapMarkDayIntentReceiver"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.my.app.intents.UPDATE_WIDGET" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/the_widget_info" />
        </receiver>
    </application>

</manifest>

Edit 2, added widget xml file:

  <?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="140dp" android:minHeight="140dp"
    android:updatePeriodMillis="1000000"
    android:previewImage="@drawable/example_appwidget_preview"
    android:initialLayout="@layout/the_widget" android:widgetCategory="home_screen"
    android:initialKeyguardLayout="@layout/the_widget"></appwidget-provider>

Solution

  • Sorry for not answering the last comments but I was really busy.
    Thank you to everyone for your help.
    What happened was that I had return statements in my WidgetProvider's onUpdate, onEnabled, onDisabled and orReceive methods and apparently this is a bad thing. Once I removed them this no longer occured.