0

我正在尝试创建自己的 android 小部件。我希望它包含一个列表视图,该列表视图从在线数据库的异步任务中获取数据。

到目前为止,我有我的 res/xml.stat_widget.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="220dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/widget_stat_view">
</appwidget-provider>

和布局widget_stat_view:

<?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:orientation="vertical" >


    <TextView
        android:id="@+id/statisticsTitle"
        android:gravity="center"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="Your Statistics"
        android:textSize="20sp"
        android:textStyle = "bold"
        android:padding="5dip"
        >
    </TextView>

    <View
        android:layout_width="1dp"
        android:layout_height="30dp">
    </View>

    <ListView
        android:id="@+id/yourStats"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:dividerHeight="0px"
        android:divider="@null"

        >
    </ListView>



</LinearLayout>

我现在正在尝试编写调用异步任务的小部件提供程序。我按照我在正常应用程序活动中使用的异步任务对我的异步任务进行了建模。它尚未设置为更改小部件中的数据,但我在从我的提供者调用它时遇到问题:

package com.example.beerportfoliopro;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.RemoteViews;

import com.beerportfolio.beerportfoliopro.R;

/**
 * Created by Mike on 9/12/13.
 */
public class StatWidgetProvider extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                         int[] appWidgetIds) {

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        String userName = prefs.getString("userName", null);
        String userID = prefs.getString("userID", null);
        String url = "myURL";



        new GetJSONStatWidget(this).execute(url);



    }
    public static void updateWidgetContent(Context context,
                                           AppWidgetManager appWidgetManager) {

        RemoteViews remoteView = new RemoteViews(context.getPackageName(),
                R.layout.widget_stat_view);
        remoteView.setTextViewText(R.id.title, strLatestTitle);
        Intent launchAppIntent = new Intent(context, TutListActivity.class);
        PendingIntent launchAppPendingIntent = PendingIntent.getActivity(context,
                0, launchAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.full_widget, launchAppPendingIntent);
        ComponentName tutListWidget = new ComponentName(context,
                TutWidgetProvider.class);
        appWidgetManager.updateAppWidget(tutListWidget, remoteView);
    }
}

我在上面的代码中遇到的第一个错误:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

错误是:

getDefaultSharedPreferences
                (android.content.Context)
        in PreferenceManager cannot be applied
                to
        (com.example.beerportfoliopro.StatWidgetProvider)

我在这一行也遇到了错误:

new GetJSONStatWidget(this).execute(url);
     

我的异步任务代码是这样的:

package com.example.beerportfoliopro;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.beerportfolio.beerportfoliopro.R;

public class GetJSONStatWidget extends AsyncTask
        <String, Void, String> {

    Context c;
    String b;

    public GetJSONStatWidget(Context context)
    {
        c = context;
    }

    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        return readJSONFeed(arg0[0]);
    }

    protected void onPostExecute(String result){

        //decode json here
        try{

            JSONObject json = new JSONObject(result);

            String beerCount = json.getString("beerCount");
            String breweryCount = json.getString("breweryCount");
            String styleCount = json.getString("styleCount");
            String highABV = json.getString("highABV");
            String highIBU = json.getString("highIBU");


            //todo: everything below is for the listview

            //make array list for stats
            final List<BasicStat> basicStatList = new ArrayList<BasicStat>();

            //create object
            BasicStat stat1 = new BasicStat("Beer Count: ", beerCount);
            basicStatList.add(stat1);

            BasicStat stat2 = new BasicStat("Brewery Count: ", breweryCount);
            basicStatList.add(stat2);

            BasicStat stat3 = new BasicStat("Style Count: ", styleCount);
            basicStatList.add(stat3);

            BasicStat stat4 = new BasicStat("High ABV: ", highABV);
            basicStatList.add(stat4);

            BasicStat stat5 = new BasicStat("High IBU: ", highIBU);
            basicStatList.add(stat5);

            //acces listview
            ListView lv = (ListView) ((Activity) c).findViewById(R.id.yourStats);

            //add items to listview
            StatInfoAdapter adapter1 = new StatInfoAdapter(c ,R.layout.stat_list_item, basicStatList);
            lv.setAdapter(adapter1);




        }
        catch(Exception e){

        }

    }





    public String readJSONFeed(String URL) {
        StringBuilder stringBuilder = new StringBuilder();
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(URL);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream inputStream = entity.getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                }
                inputStream.close();
            } else {
                Log.d("JSON", "Failed to download file");
            }
        } catch (Exception e) {
            Log.d("readJSONFeed", e.getLocalizedMessage());
        }
        return stringBuilder.toString();
    }




}
4

1 回答 1

1

对于您的第一个错误,那是因为 AppWidgetProvider 不是 Activity,因此它不是 Context。如果您查看文档,getDefaultSharedPreferences() 需要一个 Context,但 AppWidgetProvider 实际上是 BroadcastReceiver 的子类。

您也不应该在 AppWidgetProvider 中执行 AsyncTasks,因为它是一个 BroadcastReceiver。一旦 BroadcastReceiver 完成其任务,AsyncTask 将无法完成,因为 BroadcastReceiver 组件丢失。您应该使用服务来做您的“背景”工作。有另一条看起来像的线

PendingIntent notReallyBackground = PendingIntent.getService(...);

资料来源:CommonsWare 的书《The Busy Coder's Guide to Android》

更新:抱歉,PendingIntent 用于您希望稍后发生某些事情时。在上面的行中,这意味着一旦您绑定到的 RemoteViews 被单击,AppWidgetHost 就会启动服务。

如果需要,可以通过调用 startService(Intent) 立即从 BroadcastReceiver 启动新服务。

您可以在这里看到一个很好的示例(查找 UpdateService):http ://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html

这是在小部件上使用 ListViews 的一个很好的链接(使用带有集合的应用小部件):http: //developer.android.com/guide/topics/appwidgets/index.html

我相信你已经看过后者,但我只是想指出它是在 Android 3.0 中引入的,因为 RemoteViews 就像功能有限的 Views,所以与使用 ListViews 相比,你必须使用稍微不同的方法在一个活动中。(例如 setRemoteAdapter)

于 2013-09-13T05:46:44.537 回答