簡體   English   中英

RemoteViewsFactory中的onClickPendingIntent

[英]onClickPendingIntent in RemoteViewsFactory

我正在為一個應用程序開發一個Android Widget,問題是我無法在RemoteViewsFactory的按鈕上設置onClickPendingIntent()

我解釋一下:我創建了一個AppWidgetProvider ,它調用的延伸RemoteViewsService它調用的延伸RemoteViewsFactory為完整的一個ListView在我的小部件。 RemoteViewsFactory必須返回所有要更新的項目,或者創建它們並在窗口小部件上顯示。 但是對於列表視圖的每個項目,我有兩種類型的按鈕:

  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;
    }

}

謝謝你:)


編輯: Yeaye! 問題解決與否......

方法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的額外信息。 DoneTaskActivityonCreate()方法中, Bundle var in參數保持為null

救命 :(

'putExtra'的第一個參數必須包含包前綴。 如果你的應用程序包的名稱是'com.test',你應該輸入'com.test.TASK_ID'。 接收部分的名稱相同。

嘗試添加這個:

// 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);

在窗口小部件中使用列表視圖時,您需要使用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上的文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM