[英]onClickPendingIntent in RemoteViewsFactory
我正在為一個應用程序開發一個Android Widget,問題是我無法在RemoteViewsFactory
的按鈕上設置onClickPendingIntent()
。
我解釋一下:我創建了一個AppWidgetProvider
,它調用的延伸RemoteViewsService
它調用的延伸RemoteViewsFactory
為完整的一個ListView
在我的小部件。 RemoteViewsFactory
必須返回所有要更新的項目,或者創建它們並在窗口小部件上顯示。 但是對於列表視圖的每個項目,我有兩種類型的按鈕:
問題是第二個按鈕,我的解決方案不起作用。
這是問題所在:
所以,這是不起作用的代碼:
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
的額外信息。 在DoneTaskActivity
的onCreate()
方法中, 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.