4

アプリ用の Android ウィジェットを開発していますが、問題はonClickPendingIntent()のボタンに設定できないことRemoteViewsFactoryです。

私は説明します: 私は自分のウィジェットで完全な aの拡張をAppWidgetProvider呼び出すを作成しました。更新のためにすべてのアイテムを返すか、それらを作成してウィジェットに表示する必要があります。しかし、リスト ビューの各アイテムには、2 種類のボタンがあります。RemoteViewsServiceRemoteViewsFactoryListViewRemoteViewsFactory

  1. gmaps/dialer/sms を開くボタン (動作します)。
  2. アプリでアクティビティを呼び出し、アイテムの ID をパラメーターで送信するボタン。

問題は 2 番目のボタンです。私の解決策は機能しません。

問題は次のとおりです。

したがって、これは機能しないコードです。

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()メソッドではDoneTaskActivityBundlevar in パラメータは のまま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;
}

また、個々のリスト項目は PendingIntents を設定できないため、標準の PendingIntent を使用する必要があります。 AppWidgetsのドキュメントを参照してください。

于 2015-10-05T05:57:53.453 に答える
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 に答える
0

「putExtra」の最初のパラメータには、パッケージ プレフィックスを含める必要があります。アプリのパッケージ名が「com.test」の場合、「com.test.TASK_ID」を入力する必要があります。受け取り側も同名。

于 2015-05-15T17:40:30.743 に答える