4

我正在为应用程序开发一个 Android 小部件,问题是我无法onClickPendingIntent()RemoteViewsFactory.

我解释一下:我创建了一个AppWidgetProvider,它调用了一个扩展,RemoteViewsService它调用了一个扩展,用于在我的小部件RemoteViewsFactory中完成一个。必须返回所有项目以进行更新或创建它们并显示在小部件上ListViewRemoteViewsFactory但是对于列表视图的每个项目,我有两种类型的按钮:

  1. 一个打开 gmaps/dialer/sms 的按钮(有效)。
  2. 一个按钮,它在我的应用程序中调用一个活动并在参数中将其发送到项目的 ID。

问题是第二个按钮,我的解决方案不起作用。

这是问题所在:

因此,这是不起作用的代码:

row.setOnClickPendingIntent(R.id.taskButton, onClickPendingIntent);

// Creating an onclick event for the done button
Intent doneIntent = new Intent(mContext, WidgetProvider.class);
doneIntent.putExtra("DONE_TASK", "DOOOOM");

PendingIntent onDoneIntent = PendingIntent.getActivity(mContext, 0, doneIntent, 0);
row.setOnClickPendingIntent(R.id.doneButton, onDoneIntent);

这是完整的WidgetFactory课程:

import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.Vector;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

public class WidgetFactory implements RemoteViewsService.RemoteViewsFactory {

    private Vector<EventInfo> mAllEvents;
    private Context mContext;

    public WidgetFactory(Context ctxt, Intent intent) {
        // Creating member vars
        mContext = ctxt;

        updateAllEventsVector();
    }


    private void updateAllEventsVector() {
        SharedInstances sharedInstances = SharedInstances.get();
        mAllEvents = new Vector<EventInfo>(); 

        if (sharedInstances != null) {
            TaskRequestManager taskManager = sharedInstances
                    .getTaskRequestManager();
            CalendarRequestManager calManager = sharedInstances
                    .getCalendarRequestManager();

            Vector<TaskEvent> tasks = null;
            Vector<CalendarEvent> events = null;

            if (taskManager != null) 
                tasks = taskManager.readTasksToday(mContext);

            if (calManager != null)
                events = calManager.readCalendarEventsToday(mContext);

            if (!tasks.isEmpty())
                mAllEvents.addAll(tasks);


            if (!events.isEmpty())
                mAllEvents.addAll(events);

            mAllEvents = sortByDate(mAllEvents);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Vector<EventInfo> sortByDate(Vector<EventInfo> events)
    {

        Vector<EventInfo> sortedEvents = new Vector<EventInfo>();

        for(EventInfo event : events)
        {
            if ((event.getStartTime()+event.getEventDuration()) > GregorianCalendar.getInstance().getTimeInMillis())
                sortedEvents.add(event);
        }

        Collections.sort(events, new Comparator() {
            public int compare(Object arg0, Object arg1)
            {
                EventInfo event0 = (EventInfo)arg0;
                EventInfo event1 = (EventInfo)arg1;

                if (event0.getStartTime()+event0.getEventDuration() > event1.getStartTime()+event1.getEventDuration())
                    return 1;
                else if (event0.getStartTime()+event0.getEventDuration() == event1.getStartTime()+event1.getEventDuration())
                    return 0;
                else if (event0.getStartTime()+event0.getEventDuration() < event1.getStartTime()+event1.getEventDuration())
                    return -1;

                return 0;
            }
        });

        return sortedEvents;
    }

    @Override
    public int getCount() {
        return mAllEvents.size();
    }

    @Override
    public long getItemId(int arg0) {
        return (arg0);
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public RemoteViews getViewAt(int position) {

        // Getting item view
        RemoteViews row = new RemoteViews(mContext.getPackageName(),
                R.layout.done_task_item);

        EventInfo eventInfo = mAllEvents.get(position);



        row.setInt(R.id.item_event, "setBackgroundColor", Color.argb(60, Color.red(eventInfo.getColor()), Color.green(eventInfo.getColor()), Color.blue(eventInfo.getColor())));

        // Converts startTime and endTime in string
        String startTime = TimeCursor.getAdaptativeTime(eventInfo.getStartTime());
        String endTime = TimeCursor.getAdaptativeTime((eventInfo
                .getEventDuration() + eventInfo.getStartTime()));

        //Get title
        String title = eventInfo.getTitle();

        // Setting data in the view
        row.setTextViewText(R.id.titleTask, title);
        row.setTextViewText(R.id.periodTask, startTime + " to " + endTime);

        //Check type of event
        if (eventInfo.isTask()) {
            //endDate > GregorianCalendar.getInstance().getTimeInMillis() ) {

            //Check if action exists
            if (eventInfo.getAction() != null) {

                //Get the action title
                String action = eventInfo.getAction()
                        .getTitleText();

                //Create a onClickPendingIntent for taskButton
                PendingIntent onClickPendingIntent = null;

                //Add related button
                if (action.equals("Call"))
                {
                    //Set call icon to taskButton
                    row.setImageViewResource(R.id.taskButton, R.drawable.ic_call_white );

                    //Get numbers from the contact
                    Vector<TelOrEmailItem> tel = eventInfo.getContact().getAllPhoneNumbers(mContext.getResources() , mContext, eventInfo.getAction());

                    // Creating an onclick event for call somebody
                    Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+tel.get(0).getMainText()));
                    onClickPendingIntent = PendingIntent.getActivity(
                            mContext, 0, callIntent, 0);

                }
                else if (action.equals("SMS"))
                {
                    //Set sms icon to taskButton
                    row.setImageViewResource(R.id.taskButton, R.drawable.ic_sms_white);
                    //Get numbers from the contact
                    Vector<TelOrEmailItem> tel = eventInfo.getContact().getAllPhoneNumbers(mContext.getResources() , mContext, eventInfo.getAction());

                    // Creating an onclick event for call somebody
                    Intent smsIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"+tel.get(0).getMainText()));
                    onClickPendingIntent = PendingIntent.getActivity(
                            mContext, 0, smsIntent, 0);
                }
                /*else if (action.equals("Chat with"))
                    row.setImageViewResource(R.id.taskButton, R.drawable.ic_chat_white);*/
                else if (action.equals("eMail") || action.equals("Mail") || action.equals("Write to"))
                {
                    //Set email icon to taskButton
                    row.setImageViewResource(R.id.taskButton, R.drawable.ic_email_white);

                    //Get numbers from the contact
                    Vector<TelOrEmailItem> tel = eventInfo.getContact().getAllEMails(mContext, eventInfo.getAction());

                    //Creating an onclick event for email somebody
                    Intent emailIntent = new Intent(Intent.ACTION_SEND);
                    emailIntent.setType("plain/text");

                    emailIntent.putExtra(Intent.EXTRA_EMAIL, 
                                    new String[]{tel.get(0).getMainText()}); 

                    onClickPendingIntent = PendingIntent.getActivity(
                            mContext, 0, emailIntent, 0);
                }
                /*else if (action.equals("Skype"))
                    row.setImageViewResource(R.id.taskButton, R.drawable.ic_skype_white);*/

                //Assign the intent to the taskButton
                row.setOnClickPendingIntent(R.id.taskButton, onClickPendingIntent);

                // Creating an onclick event for the done button
                Intent doneIntent = new Intent(mContext, WidgetProvider.class);

                doneIntent.putExtra("DONE_TASK", "DOOOOM");

                PendingIntent onDoneIntent = PendingIntent.getActivity(mContext, 0, doneIntent, 0);

                row.setOnClickPendingIntent(R.id.doneButton, onDoneIntent);

            }
            else
                row.setViewVisibility(R.id.taskButton, View.GONE); //hidde the taskButton

            return row;

        }
        //Check if it's an event
        else if(eventInfo.isEvent()) {

            //hidde task button (Done)
            row.setViewVisibility(R.id.doneButton, View.GONE);

            CalendarEvent ev = eventInfo.getCalendarEvent();
            String location = ev.getEventLocation();
            if (location != null && !location.isEmpty())
            {
                //Set the locate icon on the taskButton
                row.setImageViewResource(R.id.taskButton, R.drawable.ic_locate_white);

                //Define the place to open the map
                Intent mapIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q="+location));
                PendingIntent onMapIntent = PendingIntent.getActivity(
                        mContext, 0, mapIntent, 0);
                row.setOnClickPendingIntent(R.id.taskButton, onMapIntent);
            }
            else
                row.setViewVisibility(R.id.taskButton, View.GONE);

            return row;
        }


        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public boolean hasStableIds() {
        return (true);
    }

    @Override
    public void onCreate() {
    }

    @Override
    public void onDataSetChanged() {
        // On data changes, update mTasks
        updateAllEventsVector();
    }

    @Override
    public void onDestroy() {
        mAllEvents = null;
    }

}

谢谢你:)


编辑: 耶耶!问题解决与否...

方法onClickPendingIntent()现在有效,代码如下:

// Creating an onclick event for the done button
Intent onClickDone = new Intent(mContext, DoneTaskActivity.class);
onClickDone.putExtra("TASK_ID", eventInfo.getTaskEvent().getTaskId());
PendingIntent onClickPendingDone = PendingIntent.getActivity(mContext, 0, onClickDone, 0);
row.setOnClickPendingIntent(R.id.doneButton, onClickPendingDone);

但存在另一个问题:DoneTaskActivity没有收到额外声明为TASK_ID. 在 的onCreate()方法中DoneTaskActivity,参数中的Bundlevar 保持为null

帮助 :(

4

3 回答 3

1

在小部件中使用列表视图时,您需要使用setOnClickFillInIntent侦听器。来自官方文档;

在小部件中使用集合(例如 ListView、StackView 等)时,在单个项目上设置 PendingIntents 的成本非常高,因此是不允许的。相反,可以在集合上设置单个 PendingIntent 模板

在您的 RemoteViewsFactory 中,您可以像这样使用它;

public RemoteViews getViewAt(int position) {
    // position will always range from 0 to getCount() - 1.

    // Construct a RemoteViews item based on the app widget item XML file, and set the
    // text based on the position.
    RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
    rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);

    // Next, set a fill-intent, which will be used to fill in the pending intent template
    // that is set on the collection view in StackWidgetProvider.
    Bundle extras = new Bundle();
    extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
    Intent fillInIntent = new Intent();
    fillInIntent.putExtras(extras);
    // Make it possible to distinguish the individual on-click
    // action of a given item
    rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);

    ...

    // Return the RemoteViews object.
    return rv;
}

您还需要使用标准的 PendingIntent,因为单个列表项无法设置 PendingIntents,请参阅AppWidgets上的文档。

于 2015-10-05T05:57:53.453 回答
0

'putExtra' 的第一个参数必须包含一个包前缀。如果您的应用程序包名称为“com.test”,则应输入“com.test.TASK_ID”。接收部分同名。

于 2015-05-15T17:40:30.743 回答
0

尝试添加这个:

// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
onClickDone.setData(Uri.parse(onClickDone.toUri(Intent.URI_INTENT_SCHEME)));

row.setOnClickPendingIntent(R.id.doneButton, onClickPendingDone);
于 2015-08-16T21:49:36.233 回答