evt
evt

Reputation: 139

Widget Application ForceCloses on installation

I've run into a road block. I'm running into a series of force closes. When I run my program in the emulator it force closes on install, before I place the widget.

Essentially I've tried to make a widget that has a button. The button is suppose to start a service to change the widget to a new layout(menu). There is also a configuration activity.

Let me know if I need to add more info. I've been using the android dev pages, and a Lars Vogels tutorial as a reference. http://www.vogella.de/articles/AndroidWidgets/article.html

Thank you RIP SJ. I was never a mac-ie but I have appreciated your work.

The Provider:

public class CodeSummitWidgetProvider extends AppWidgetProvider{

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

    Intent intent = new Intent(context.getApplicationContext(), TestService.class);
    PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 0, intent, 0);
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.codesummit_widget_provider_layout);
    views.setOnClickPendingIntent(R.id.tomenu, pendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds, views);
    context.startService(intent);

}
}

The Service:

public class TestService extends Service {

@Override
public void onStart(Intent intent, int startId) {


    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());

    int[] appWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

    if (appWidgetIds.length > 0) {
        for(int widgetId : appWidgetIds) {
            RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.codesummit_widget_menu_layout);
            appWidgetManager.updateAppWidget(widgetId, remoteViews);
        }
        stopSelf();
    }

    super.onStart(intent, startId);
}

The Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.main.codesummit"
  android:versionCode="1"
  android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <receiver android:name="CodeSummitWidgetProvider">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data  android:name="android.appwidget.provider"
                    android:resource="@xml/codesummit_appwidget_info" />
    </receiver>
    <activity android:name=".CodeSummitWidgetConfigure">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
        </intent-filter>
    </activity>
    <service android:name=".TestService" />

</application>

The LogCat:

10-06 23:59:04.925: INFO/ActivityManager(65): Start proc com.main.codesummit for broadcast com.main.codesummit/.CodeSummitWidgetProvider: pid=312 uid=10036 gids={}
10-06 23:59:05.596: DEBUG/AndroidRuntime(312): Shutting down VM
10-06 23:59:05.606: WARN/dalvikvm(312): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
10-06 23:59:05.665: ERROR/AndroidRuntime(312): FATAL EXCEPTION: main
10-06 23:59:05.665: ERROR/AndroidRuntime(312): java.lang.RuntimeException: Unable to start service com.main.codesummit.TestService@44ee5a38 with Intent { cmp=com.main.codesummit/.TestService }: java.lang.NullPointerException
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3063)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.app.ActivityThread.access$3600(ActivityThread.java:125)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2096)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.os.Looper.loop(Looper.java:123)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.app.ActivityThread.main(ActivityThread.java:4627)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at java.lang.reflect.Method.invokeNative(Native Method)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at java.lang.reflect.Method.invoke(Method.java:521)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at dalvik.system.NativeStart.main(Native Method)
10-06 23:59:05.665: ERROR/AndroidRuntime(312): Caused by: java.lang.NullPointerException
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at com.main.codesummit.TestService.onStart(TestService.java:23)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.app.Service.onStartCommand(Service.java:420)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3053)
10-06 23:59:05.665: ERROR/AndroidRuntime(312):     ... 10 more
10-06 23:59:10.696: INFO/Process(312): Sending signal. PID: 312 SIG: 9
10-06 23:59:10.795: INFO/ActivityManager(65): Process com.main.codesummit (pid 312) has died.

Upvotes: 2

Views: 198

Answers (1)

w.donahue
w.donahue

Reputation: 10886

In your onUpdate method you are using the wrong context in a few places. The context that is passed into onUpdate only lives until the onUpdate function finishes executing. So you cannot use it for anything that you want to live for longer then this function runs, for instance your service. The application context lives for the life of the application. To get it from onUpdate call context.getApplicationContext().

So you need to change the context on these lines:

Intent intent = new Intent(context, TestService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);

To:

Intent intent = new Intent(context.getApplicationContext(), TestService.class);
PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 0, intent, 0);

Also the access level for the class is incorrect

class TestService extends Service {

Make this a public class. Since it not public the OS can't use it when it tries to launch the service.

Upvotes: 1

Related Questions