0

upd2. The problem has gone after a sort of black magic routine (uninstall, clean Eclipse project, reboot Android device, rebuild, install, run). It is not solved, it has gone. Could anyone please explain what has happened?

upd. Seems, no Java code running at all in my Android widget project modeled after Hello Widget tutorial (ref. comments). Is there any way to run some code to make my widget useful? I believe it is possible because there are a lot of do-something widgets. How they make it?

I modeled a simple Android widget after Hello Widget tutorial: http://nm-blog.sanid.com/2009/07/android-hellowidget-tutorial/

Running it I can see that it's not working at all - the text view is not altered.

Here's some code:

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pell.hellowidget"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >        
        <receiver android:name="HelloWidgetProvider" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/hello_widget_provider" />
        </receiver>                
    </application>
</manifest>

res/xml/hello_widget_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="280dp"
  android:minHeight="180dp"
  android:updatePeriodMillis="10000"
  android:initialLayout="@layout/hello_widget_layout"
  android:resizeMode="vertical" />

res/layout/hello_widget_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

src/com/pell/hellowidget/HelloWidgetProvider.java:

package com.pell.hellowidget;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;

public class HelloWidgetProvider extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1,
                1000);

        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    private Date currentTime;

    private class MyTime extends TimerTask {
        RemoteViews remoteViews;
        AppWidgetManager appWidgetManager;
        ComponentName thisWidget;
        DateFormat format = SimpleDateFormat.getTimeInstance(
                SimpleDateFormat.MEDIUM, Locale.getDefault());

        public MyTime(Context context, AppWidgetManager appWidgetManager) {
            this.appWidgetManager = appWidgetManager;
            remoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.hello_widget_layout);
            thisWidget = new ComponentName(context, HelloWidgetProvider.class);
        }

        @Override
        public void run() {
            currentTime = new Date();
            remoteViews.setTextViewText(R.id.textView1,
                    format.format(currentTime));
            appWidgetManager.updateAppWidget(thisWidget, remoteViews);
        }
    }
}

As far as I understand it is not working due to nobody instantiates com.pell.hellowidget.HelloWidgetProvider object. What is Java/Android Widget/etc analog for the entry point (int main(int argc, char * argv[]), WinMain, etc)? Who (and how) instantiates AppWidgetProvider object?

pell
  • 33
  • 1
  • 8
  • I just altered ``. There is no HelloWidgetFoo class definition. But project is compiled OK and .apk is installed OK and widget can be added to home screen. What does it mean? – pell Mar 27 '13 at 18:17
  • Another experiment: deleted `extends AppWidgetProvider` and all `@Override` and `super.onBlah-blah-blah` declarations. Project is compiled, installed and running as before. Does it mean nobody cares about my Java code? How could I do something useful with my widget in such a situation when no Java code is possible to run? – pell Mar 27 '13 at 18:25
  • upd. Adding the widget to the home screen I get a message `Unabel to launch com.pell.hellowidget/10147 for broadcast Intent { act=android.appwidget.action.APPWIDGET_UPDATE flg=0x10 cmp=com.pell.hellowidget/.HelloWidget (has extras) }: process is bad`. – pell Mar 27 '13 at 18:38
  • 1
    Finally it was fixed by uninstalling the widget, adding dot to the line ``, restarting my Android device, cleaning project in Eclipse, rebuilding project in Eclipse and installing the widget again. What it was? Is it a sort of black magic or something? – pell Mar 27 '13 at 18:47
  • Hi pell, was my answer below helpful? How could I improve it? Did I misunderstand your question? – Neil Townsend Mar 28 '13 at 08:39
  • Hi Neil, thank you for the answer. My the best understanding now is that widget does not have "entry point" or "message cycle" by default. It's just a widget. To make it "alive" one should create "entry point"/"message handler" and control the widget state from there. Right? – pell Mar 28 '13 at 21:14
  • I think you're correct - I've updated the answer to hopefully clarify and provide a link to a pretty good example. Thanks for the tick, much appreciated. – Neil Townsend Mar 28 '13 at 22:25

1 Answers1

0

As per your final comment, the . in the android:name can sometimes be essential. As a rule, I always use fully qualified name ("com.super.cool.thing.MySpecialClassActivity") in the manifest because it makes it very clear.

The "entry point" for an AppWidget is the provider class. However, it is only instantiated when it is called and, once onUpdate (or onDestroy) returns, the class is gone. Whilst (I think) you can do what you've done, it wouldn't be considered good practice - generally you should create a defined separate thread from which to manage your widget, either a Service, an AsyncTask, a Thread etc.

Typically, the onUpdate method will create an intent designed to start a Service class which will control the widget. An example of this is in http://www.vogella.com/articles/AndroidWidgets/article.html, section 8 in particular. I would only quibble with one point in that tutorial: it's generally advised to not use updatePeriod. I've also put some considerations for using Services and other things together in Service being re-Created by AlarmManager.

Community
  • 1
  • 1
Neil Townsend
  • 6,024
  • 5
  • 35
  • 52