-2

嗨,我正在尝试制作一个 android 小部件。在这个小部件中,我试图通过调用 Web 服务并从中获取数据并在特定的关系间隔后将其显示在文本视图中来更新我的文本视图的值,但我遇到了异常。

Exception:java.lang.RuntimeException: Unable to start service com.example.newwidget.UpdateService@40ce9518withIntent{cmp=com.example.newwidget
/.UpdateService (has extras) }: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 

这是我尝试过的代码,

小部件.java

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

   public class Widget extends AppWidgetProvider {


@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
    Toast.makeText(context, "OnUpdate", Toast.LENGTH_LONG).show();

      ComponentName thisWidget = new ComponentName(context,
                Widget.class);
            int[] allWidgetIds =       appWidgetManager.getAppWidgetIds(thisWidget);
            Toast.makeText(context, "allWidgetIds", Toast.LENGTH_LONG).show();

            // Build the intent to call the service
            Intent intent = new Intent(context.getApplicationContext(),
                UpdateService.class);
            Toast.makeText(context, "call UpdateService", Toast.LENGTH_LONG).show();

            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
            Toast.makeText(context, "", Toast.LENGTH_LONG).show();

            // Update the widgets via the service
            context.startService(intent);
}

 }

更新服务.java

   import java.io.IOException;

   import org.apache.http.HttpEntity;
   import org.apache.http.HttpResponse;
   import org.apache.http.client.ClientProtocolException;
   import org.apache.http.client.HttpClient;
   import org.apache.http.client.ResponseHandler;
   import org.apache.http.client.methods.HttpGet;
   import org.apache.http.impl.client.BasicResponseHandler;
   import org.apache.http.impl.client.DefaultHttpClient;

   import android.app.ProgressDialog;
   import android.app.Service;
   import android.appwidget.AppWidgetManager;
   import android.content.ComponentName;
   import android.content.Context;
   import android.content.Intent;
   import android.os.IBinder;
   import android.util.Log;
   import android.widget.RemoteViews;
   import android.widget.Toast;

   public class UpdateWidget extends Service {
    private RemoteViews views;
    private String url;
    private String strAPIRender;
    private final HttpClient Client = new DefaultHttpClient();
    private String Content;
    private String Error = null;
    private ProgressDialog Dialog = new ProgressDialog(null);
    private HttpResponse response;
    private HttpEntity httpEntity;


@Override
     public void onStart(Intent intent, int startId) {
        Log.d("AppWidget.UpdateService", "onStart()");
    Toast.makeText(UpdateWidget.this, "Onstart", Toast.LENGTH_LONG).show();
        // Build the widget update for today
    Toast.makeText(UpdateWidget.this, "Updateviews", Toast.LENGTH_LONG).show();

        RemoteViews updateViews = buildUpdate(this);
        Log.d("WordWidget.UpdateService", "update built");

Toast.makeText(UpdateWidget.this, "buildupdate finish", Toast.LENGTH_LONG).show();

        // Push update for this widget to the home screen
    ComponentName thisWidget = new ComponentName(this, WidgetAppActivity.class);

        AppWidgetManager manager = AppWidgetManager.getInstance(this);

    Toast.makeText(UpdateWidget.this, "final update", Toast.LENGTH_LONG).show();
    manager.updateAppWidget(thisWidget, updateViews);

    Log.d("WordWidget.UpdateService", "widget updated");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public RemoteViews buildUpdate(Context context) {
        // Pick out month names from resources
Toast.makeText(UpdateWidget.this, "buildupdate", Toast.LENGTH_LONG).show();
url = "http://www.webservicex.net/currencyconvertor.asmx/ConversionRate?FromCurrency=USD&ToCurrency=INR";

        grabURL(url);
Toast.makeText(UpdateWidget.this, "grabURL finish", Toast.LENGTH_LONG).show();

        String result = strAPIRender;

views = new RemoteViews(context.getPackageName(), R.layout.activity_widget_app);
        views.setTextViewText(R.id.update, result);
        return views;
    }
    public void grabURL(String url) {
Toast.makeText(UpdateWidget.this, "in grabURL method", Toast.LENGTH_LONG).show();



        Toast.makeText(null, "execute url", Toast.LENGTH_LONG).show();
        try {
            HttpGet httpget = new HttpGet(url);
    ResponseHandler<String> responseHandler = new BasicResponseHandler();
            Content = Client.execute(httpget, responseHandler);
        } catch (ClientProtocolException e) {
            Error = e.getMessage();
        //cancel(true);
    } catch (IOException e) {
            Error = e.getMessage();
            //cancel(true);
        }



        parseXml(Content);
    }



    public String parseXml(String content) {
        try {

            System.out.println(content);
            try {

                strAPIRender = XMLHandler.GetTagValue("double",content);


            } catch (Exception e) {
                System.out.println(" catch b");
            }

        } catch (Exception e) {
            System.out.println(" exception in parseXML");
        }
        return strAPIRender;


    }


}

清单文件

      <uses-sdk android:minSdkVersion="8" />
  <uses-permission android:name="android.permission.INTERNET"/>

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

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_info" />
    </receiver>
    <service android:name="com.example.newwidget.UpdateService"></service>
   </application>
4

1 回答 1

0

从 UpdateService 中删除以下行:

private ProgressDialog Dialog = new ProgressDialog(null);

该“对话框”不会出现(快速浏览该类)以在任何地方使用。如果您确实打算使用它,则不能像那样实例化它(它需要一个真实的上下文)。这应该可以解决您所询问的特定错误。

(即使您修复了该错误,我也不确定此代码是否会按预期工作。您可能还想考虑一下,只是为了初学者:删除所有 toast 以进行调试并使用日志记录和 logcat,和/或调试器;不要将主 UI 线程(默认情况下也使用这些服务)用于网络 I/O(请参阅 IntentService 以获得简单的解决方法);不要从服务中执行对话框/警报/toast;并注意非-标准命名约定,例如以大写开头的成员变量,这使得代码难以遵循(特别是当它不一致时,即使它不遵循约定)。)

于 2013-01-15T16:41:54.443 回答