从配置活动获取appWidgetId的问题

时间:2012-11-07 23:58:48

标签: android android-activity alarmmanager configure appwidgetprovider

我正在创建一个带有一些小部件的Android应用程序。一切正常,直到我开始创建设置活动...首先,我的代码:

[编辑] 试着说清楚:Bundle(来自intent.getExtras())总是空的......我该怎么做才能纠正它? [/ Edit]

AppWidgetProvider:

package com.br.mcsoft.atheistquotes.provider;

import com.br.mcsoft.atheistquotes.R;
import com.br.mcsoft.atheistquotes.Adapters.DBAdapter;
import com.br.mcsoft.atheistquotes.activity.QuoteActivity;
import com.br.mcsoft.atheistquotes.model.Quote;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.SQLException;
import android.os.Bundle;
import android.util.Log;
import android.widget.RemoteViews;

public class WidgetProviderSmall extends AppWidgetProvider {
    private static final String TAG = "WidgetProviderSmall";
    public static final String URI_SCHEME = "widget_provider_small";
    private static Quote lastQuote = null;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        System.out.println("Updatando...");
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        final int n = appWidgetIds.length;
        for (int i = 0; i < n; i++) {
            updateData(context, i);
            System.out.println("Atualizou os dados...");
            // Cria o RemoteViews
            RemoteViews rv = new RemoteViews(context.getPackageName(),
                    R.layout.widget_layout_small);

            // Adiciona o listener do evento do botão Next...
            Intent active = new Intent(context, WidgetProviderSmall.class);
            active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    appWidgetIds[i]);
            active.setAction(StaticHelper.ACTION_WIDGET_REFRESH);
            PendingIntent actionPendingIntent = PendingIntent.getBroadcast(
                    context, 0, active, 0);
            rv.setOnClickPendingIntent(R.id.ibtNext, actionPendingIntent);

            // Adiciona o listener do evento do clique no Widget...
            active = new Intent(context, WidgetProviderSmall.class);
            active.setAction(StaticHelper.ACTION_CLICK);
            actionPendingIntent = PendingIntent.getBroadcast(context, 0,
                    active, 0);
            rv.setOnClickPendingIntent(R.id.laySmall, actionPendingIntent);

            // Atualiza tudo
            appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        System.out.println("Recebeu alguma chamada...");
        if (intent.getAction().equals(StaticHelper.ACTION_WIDGET_REFRESH)) {
            // Log.i("onReceive", ACTION_WIDGET_REFRESH);
            Bundle extras = intent.getExtras();
            if (extras != null) {
                int widgetId = extras.getInt(
                        AppWidgetManager.EXTRA_APPWIDGET_ID,
                        AppWidgetManager.INVALID_APPWIDGET_ID);
                updateData(context, widgetId);
            }
        } else if (intent.getAction().equals(StaticHelper.ACTION_CLICK)) {
            Intent i = new Intent(context, QuoteActivity.class);
            Bundle b = new Bundle();
            b.putInt("QuoteId", lastQuote.getId());
            i.putExtras(b);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        System.out.println("Ih! OnDelete!");
        Intent intent = new Intent(context, WidgetProviderSmall.class);
        Bundle extras = intent.getExtras();
        if (extras != null) {
            int widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
            AlarmManager alarms = (AlarmManager) context
                    .getSystemService(Context.ALARM_SERVICE);

            Intent widgetUpdate = new Intent();
            widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
                    new int[] { widgetId });

            PendingIntent newPending = PendingIntent.getBroadcast(context, 0,
                    intent, PendingIntent.FLAG_UPDATE_CURRENT);
            // Para o alarme...
            alarms.cancel(newPending);

            // Remove o estado armazenado...
            SharedPreferences config = context.getSharedPreferences(
                    "AtheistQuoteWidget", 0);
            SharedPreferences.Editor edit = config.edit();
            edit.remove(String.format("UpdateRate-%d", widgetId));
            edit.commit();
        }
        super.onDeleted(context, appWidgetIds);
    }

    private void updateData(Context context, int Id) {
        try {
            DBAdapter db;
            db = new DBAdapter(context);
            db.open();
            Quote q = db.getRandomQuote();
            db.close();
            lastQuote = q;

            // Verifica o tamanho e trunca o texto da citação...
            String textQuote = "\"" + q.getQuote() + "\"";
            if (textQuote.length() > 110 + 10) {
                textQuote = textQuote.substring(0, 110) + "...\" [...]";
            }

            // Cria o RemoteViews
            RemoteViews rv = new RemoteViews(context.getPackageName(),
                    R.layout.widget_layout_small);
            // Seta os campos...
            // rv.setTextViewText(R.id.txtWdgQuote, "\"" + q.getQuote() + "\"");
            rv.setTextViewText(R.id.txtWdgQuote, textQuote);
            rv.setTextViewText(R.id.txtWdgAuthor, "— "
                    + q.getAuthor().getName());

            // Atualiza tudo
            AppWidgetManager appWidgetManager = AppWidgetManager
                    .getInstance(context);
            appWidgetManager.updateAppWidget(Id, rv);
        } catch (SQLException e) {
            Log.e(TAG, e.getMessage(), e);
        }
    }
}

的活动:

package com.br.mcsoft.atheistquotes.activity;

import com.br.mcsoft.atheistquotes.R;
import com.br.mcsoft.atheistquotes.provider.WidgetProviderSmall;

import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;

public class SettingsActivity extends Activity {
    private static final String[] Times = new String[] { "5 minut",
            "10 minuts", "15 minuts", "20 minuts", "30 minuts", "1 hora",
            "2 horas" };
    private static int DEFAULT_TIME = 15;
    private int oldTime = 0;
    private int newTime;
    private Spinner spn = null;
    private SharedPreferences config = null;
    private int widgetId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Inicia a excução...
        System.out.println("Entrou...");
        super.onCreate(savedInstanceState);
        System.out.println("Chamou o super e o layoyt...");
        widgetId = 0;
        // Pega o Id do Widget
        Intent intent = new Intent(this, WidgetProviderSmall.class);
        Bundle extras = intent.getExtras();
        if (extras != null) {
            System.out.println("Há extras...");
            widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
        } else {
            System.out.println("Ferrou, não há...");
            finish();
            return;
        }
        // Seta como "cancelar" preventivamente...
        Intent cancelResultValue = new Intent(this, WidgetProviderSmall.class);
        cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                widgetId);
        setResult(RESULT_CANCELED, cancelResultValue);
        System.out.println("Setou o cancel...");
        // Verifica o tempo atualmente setado
        config = this.getSharedPreferences("AtheistQuoteWidget", 0);
        try {
            oldTime = config.getInt(String.format("UpdateRate-%d", widgetId),
                    -1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("Pegou o tempo setado...");
        // Seta o Spinner...
        setContentView(R.layout.activity_settings);
        System.out.println("Chamou o layout...");
        spn = (Spinner) findViewById(R.id.spnTimes);
        ArrayAdapter<String> adp = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, Times);
        adp.setDropDownViewResource(android.R.layout.simple_spinner_item);
        spn.setAdapter(adp);
        if (oldTime == 0)
            oldTime = DEFAULT_TIME;
        // Seta o tempo atual no Spinner
        if (oldTime == 5) {
            spn.setSelection(0);
        } else if (oldTime == 5) {
            spn.setSelection(1);
        } else if (oldTime == 10) {
            spn.setSelection(2);
        } else if (oldTime == 15) {
            spn.setSelection(3);
        } else if (oldTime == 20) {
            spn.setSelection(4);
        } else if (oldTime == 30) {
            spn.setSelection(5);
        } else if (oldTime == 60) {
            spn.setSelection(6);
        } else if (oldTime == 120) {
            spn.setSelection(7);
        }
        System.out.println("Setou o Spinner...");
        // Pega e seta os botões...
        Button ok = (Button) findViewById(R.id.btnOk);
        Button cancel = (Button) findViewById(R.id.btnCancel);
        ok.setOnClickListener(buttonClick);
        cancel.setOnClickListener(buttonClick);
        System.out.println("Setou os botões...");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_settings, menu);
        return true;
    }

    private OnClickListener buttonClick = new OnClickListener() {
        public void onClick(View v) {
            if (v == (Button) findViewById(R.id.btnOk)) {
                newTime = spn.getSelectedItemPosition();
                if (newTime == oldTime) {
                    finish();
                }
                SharedPreferences.Editor configEditor = config.edit();
                configEditor.putInt(String.format("UpdateRate-%d", widgetId),
                        newTime);
                configEditor.commit();
                if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
                    // tell the app widget manager that we're now configured
                    Intent i = new Intent();
                    i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
                    setResult(RESULT_OK, i);

                    Intent widgetUpdate = new Intent();
                    widgetUpdate
                            .setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                    widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
                            new int[] { widgetId });

                    // make this pending intent unique
                    widgetUpdate.setData(Uri.withAppendedPath(Uri
                            .parse(WidgetProviderSmall.URI_SCHEME + "://widget/id/"),
                            String.valueOf(widgetId)));
                    PendingIntent newPending = PendingIntent.getBroadcast(
                            getApplicationContext(), 0, widgetUpdate,
                            PendingIntent.FLAG_UPDATE_CURRENT);

                    // schedule the new widget for updating
                    AlarmManager alarms = (AlarmManager) getApplicationContext()
                            .getSystemService(Context.ALARM_SERVICE);
                    alarms.setRepeating(AlarmManager.ELAPSED_REALTIME,
                            SystemClock.elapsedRealtime(), newTime * 1000,
                            newPending);
                }
                // activity is now done
                finish();
            }
        }
    };
}

“System.out.println”仅用于调试(文本是葡萄牙语,因为它是我的第一语言。)

无论如何,问题在这里显示:

if (extras != null) {
    System.out.println("Há extras...");
    widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
            AppWidgetManager.INVALID_APPWIDGET_ID);
} else {
    System.out.println("Ferrou, não há...");
    finish();
    return;
}

它总是去其他地方...所以整个事情都没有任何错误。 :/

我需要做些什么呢?我是否必须更改AndroidManifest.xml或类似内容?

谢谢!

P.S。:嗯......我对Android开发并不陌生......所以,如果有一些奇怪的事情,请告诉我。

2 个答案:

答案 0 :(得分:1)

解决。

这是该死的Eclipse的错。它坚持在AndroidManifest.XML上显示警告“导出的接收者不需要许可”和/或“导出的活动不需要许可”。

所以,因为我从不喜欢警告而且总是试图解决它们,所以我在配置活动部分的AndroidManifest中输入了:

android:exported="false"

所以...它不会以任何方式起作用......

嗯......无论如何,谢谢。 ;)

答案 1 :(得分:0)

尝试编写此内容而不是您定义的目标: -

Bundle extras = getIntent().getExtras();

而不是这一行: -

 Intent intent = new Intent(this, WidgetProviderSmall.class);