[Java for Android App Development] Chmis:
I've tried to create simple dialer widget that will get contacts from contact book, put them into stackview and when clicked create a popup where you can call or create a message. I worked well as an application, but when I turned it into actual widget, I've encountered something weird. Despite all the methods firing, the items are not updated and stay on loading layout.

I've compared it to the example, tried to switch parts of code and nothing works. Even funnier, my code works perfectly when I put it in example widget, but example code doesn't work in mine. The same thing happens for listview and gridview. Is there any other file I should edit?

I provide the code, layouts and manifest. Logcat shows all methods firing in right order, so there's nothing to see there.

WidgetProvider.java

public class WidgetProvider extends AppWidgetProvider {

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

Log.d("WIDGET", "Called onUpdate()");

for (int i = 0; i < appWidgetIds.length; ++i){

// Set up the intent that starts the StackViewService, which will
// provide the views for this collection.
Intent intent = new Intent(context, WidgetService.class);
// Add the app widget ID to the intent extras.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
// Instantiate the RemoteViews object for the app widget layout.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.main);
rv.setRemoteAdapter(R.id.stackView, intent);
rv.setEmptyView(R.id.stackView, R.id.emptyView);

appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
Log.d("WIDGET", "Widget updated");

}

super.onUpdate(context, appWidgetManager, appWidgetIds);

}

}

WidgetService.java

package com.chmis.superdialer;

import java.util.Collections;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

public class WidgetService extends RemoteViewsService {

@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
}

}

class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {

Context context;
Intent intent;

public StackRemoteViewsFactory(Context applicationContext, Intent intent) {

this.context = applicationContext;
this.intent = intent;

}

@Override
public void onCreate() {

Log.d("SERVICE", "Called onCreate()");

//Get contact Cursor
Cursor contactCursor = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null);

//Get contacts from cursor, store them as Contact objects inside ArrayList
while (contactCursor.moveToNext()) {

String name = contactCursor.getString(contactCursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phone = contactCursor.getString(contactCursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
long id = contactCursor.getLong(contactCursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.CONTACT_ID));

Contact.array.add(new Contact(name, phone, id));

}

//Sort contacts by name
Collections.sort(Contact.array, new ContactComparator(Contact.JOHN_SMITH));

}

@Override
public RemoteViews getViewAt(int position) {

Log.d("SERVICE", "Called getViewAt(" + position + ")");

RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.main);
rv.setTextViewText(R.id.contactNameTextView, Contact.array.get(position).getDefaultName());

// Return the remote views object.
return rv;

}

@Override
public int getCount() {
Log.d("SERVICE", "Called getCount(), returned " + Contact.array.size());
return Contact.array.size();
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public RemoteViews getLoadingView() {
return null;
}

@Override
public int getViewTypeCount() {
return 0;
}

@Override
public boolean hasStableIds() {
return true;
}

@Override
public void onDataSetChanged() {}

@Override
public void onDestroy() {
Contact.array.clear();
Log.d("SERVICE", "Called onDestroy()");
}

}

main.xml

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

<StackView
android:id="@+id/stackView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:loopViews="true" />

<TextView
android:id="@+id/emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@android:color/transparent"
android:textStyle="bold"
android:textColor="#ffffff"
android:text="@string/no_contacts" />

</FrameLayout>

contact_stack_item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/transparent_dark" >

<ImageView
android:id="@+id/contactPhotoImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:contentDescription="@string/contact_image_description"
android:src="@drawable/contact_photo_default" />

<TextView
android:id="@+id/contactNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/contactPhotoImageView"
android:layout_alignLeft="@+id/contactPhotoImageView"
android:layout_alignRight="@+id/contactPhotoImageView"
android:background="@color/transparent_dark"
android:gravity="center_horizontal"
android:text="@string/contact_name_placeholder"
android:textColor="@android:color/white" />

</RelativeLayout>

manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.chmis.superdialer"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />

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

<application android:label="@string/app_name" >
<receiver android:name="WidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>

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

<service
android:name="WidgetService"
android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS" />
</application>

</manifest>

[MENTION=309187]edit[/MENTION] I've copied the whole service code again and now it decided to work. I don't know anything anymore.