Android ListView widgets are sometimes unresponsive to clicks - android

I've implementing a widget with RemoteViewsService containing with a ListView of items where all the items are clickable to launch a service. In short I'm using setPendingIntentTemplate in my AppWidgetProvider.onUpdate() and setOnClickFillInIntent in my RemoteViewsService.RemoteViewsFactory().
And in most cases I get the expected behavior. However, when using up some memory and going back to try to click on an item in the list again sometimes nothing happens when clicking on items in a list: the service isn't launched, and no touch feedback is given. If I have several widgets one of the lists may have the problem while the others don't.
Does anyone know how to solve this problem?
Some other testing has revealed that:
If I scroll for a while in a list with the problem and then try to click again, it works! My first thought was that the reason was that RemoteViewsFactory.getView was called and so updated the pending intent, but checking the logs I can see that this method isn't entered.
I've also logged RemoteViewsService.RemoteViewsFactory.onDestroy to see if the reason for the problem was that this was removed, but this was not the case.
If I manage to call AppWidgetManager.updateAppWidget (so that AppWidgetProvider.onUpdate will run) the problem dissapears (I call updateAppWidget from inside my main app).
These three observations seems to point to the problem being in AppWidgetManager rather than RemoteViewsFactory.
AppWidgetProvider.onUpdate:
#Override
public void onUpdate(Context iContext, AppWidgetManager iWidgetMgr,
int[] iWidgetIds){
Log.d(DbgU.getAppTag(), DbgU.getMethodName());
//Going through all widgets placed (could be more than one)
for(int i = 0; i < iWidgetIds.length; i++){
//Setting up the remote view service
Intent tmpRVServiceIntent = new Intent(iContext,
RemoteViewsServiceC.class);
tmpRVServiceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
iWidgetIds[i]);
tmpRVServiceIntent.setData(Uri.parse(tmpRVServiceIntent.toUri(
Intent.URI_INTENT_SCHEME)));
//Setting up the remote views
RemoteViews tmpRemoteViews = new RemoteViews(iContext.getPackageName(),
R.layout.widget);
tmpRemoteViews.setRemoteAdapter(R.id.widget_listview,
tmpRVServiceIntent);
tmpRemoteViews.setEmptyView(R.id.widget_listview,
R.id.widget_empty_view);
//Setting up the pending intent template (the id will be filled
//in later in RemoteViewsFactoryC.getViewAt())
Intent tmpTemplateIntent = new Intent(iContext,
LauncherServiceC.class);
tmpTemplateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
iWidgetIds[i]);
PendingIntent tmpPendingIntent = PendingIntent.getService(iContext,
0, tmpTemplateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
tmpRemoteViews.setPendingIntentTemplate(R.id.widget_listview,
tmpPendingIntent);
//Applying the update for the views
iWidgetMgr.updateAppWidget(iWidgetIds[i], tmpRemoteViews);
}
}
RemoteViewsService.RemoteViewsFactory.getViewAt:
#Override
public RemoteViews getViewAt(int inPosition) {
Log.v(DbgU.getAppTag(), DbgU.getMethodName()
+ ", inPosition = " + inPosition);
//Moving the cursor to the current position
mItemCursor.moveToPosition(inPosition);
//Extracting values from the database
String tmpName = mItemCursor.getString(
mItemCursor.getColumnIndexOrThrow(ItemTableM.COLUMN_NAME));
long tmpItemId = mItemCursor.getLong(
mItemCursor.getColumnIndexOrThrow(ItemTableM.COLUMN_ID));
Uri tmpItemUri = DatabaseU.getItemUriFromId(tmpItemId);
//Setting up the remote views object
RemoteViews retRemoteViews = new RemoteViews(
mContext.getPackageName(), R.layout.widget_listitem);
retRemoteViews.setTextViewText(R.id.widget_listitem_textView, tmpName);
//Adding action URI to the intent template which was set for all the
//list rows in WidgetProviderC.onUpdate
Intent tmpFillInIntent = new Intent();
tmpFillInIntent.setData(tmpItemUri);
retRemoteViews.setOnClickFillInIntent(R.id.widget_listitem_textView,
tmpFillInIntent);
return retRemoteViews;
}
I've been having this problem for a long time and am very grateful for any help

I have also had the same problem for a long time.
On Sony devices that have Android 4.0, if you swipe to another home pane and then back to the one where the widget is, then widget list elements will not be clickable. Sony Android 4.1 and above do not have this problem but sometimes they show wrong list element.
On some Samsung devices that have Android 4.1 I have seen the same problem.
Android 4.0 emulator homescreen does not have this problem.
I have tried to fix it in many ways, also in this way: stackoverflow.com/questions/21891008/a-textview-in-a-listview-s-row-cannot-click-after-setting-descendantfocusabilit
However, I could not fix the problem which lead me to believe that it is a homescreen problem.
To confirm that, I decided to install "Go Launcher" on a Sony Android 4.0 device, and there everything works as it should!
The answer: It is a homescreen problem which is most likely not possible to solve without using some kind of hack. Please tell me I am wrong.

Related

QListWidget row size with a custom QListWidgetItem

Using Qt Designer, I created an Item class inheriting from QWidget, and added a few widgtes.
Then, again using Qt Designer, I created a MainWindow from QMainWindow, and added a QListWidget object called list, and a QPushButton called pushButton.
On MainWindow::MainWindow(QWidget *parent), I added to the default code:
ui->list->setSizeAdjustPolicy(QListWidget::AdjustToContents);
On void MainWindow::on_pushButton_clicked(), I wrote:
Item *my_item = new Item(this);
QListWidgetItem * item = new ListWidgetItem();
item->setSizeHint(QSize(0, 400));

ui->list->addItem(item);
ui->list->setItemWidget(item, my_item );
Testing on the Linux Ubuntu running on my notebook, it all goes well, but when I run on my Android Moto G4 cell phone, the Item objects inserted in list are never displayed correctly. Using 400 in setSizeHint makes the widgets to be displayed, but cut at the bottom. Using, say, 100, makes the widgets to be squeezed, impossible to read.
Does anyone have any idea on how to make it work?
Thanks!!

Android Widget: RemoteViewsFactory does not display items correctly if getViewAt() method takes too long to execute

I have an android widget that displays user thumbnails in a GridView. The code follows the android sample code for implementing a widget that shows a collection. Here is the code for my getViewAt() method:
#Override
public RemoteViews getViewAt(int position)
{
if (mWidgetItems == null || position > mWidgetItems.size() - 1)
{
return getLoadingView();
}
WidgetUiUser user = mWidgetItems.get(position);
RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.widget_grid_item);
views.setTextViewText(R.id.widgetLocation, user.getShortLocation());
views.setViewVisibility(R.id.widgetLocation, View.VISIBLE);
Intent srcIntent = ProfileActivity.createIntent(MyApplication.getInstance(), user, PageSourceHelper.Source.SOURCE_WIDGET);
srcIntent.setAction(IntentRoutingActivity.getUniqueIntentAction()); //required for this activity to work properly
views.setOnClickFillInIntent(R.id.widgetGridItemLayout, IntentRoutingActivity.createWidgetFillInIntent(srcIntent));
// Fetch bitmap synchronously
Bitmap bitmap = mImageFetcher.getBitmap(user.getImageUrl());
views.setImageViewBitmap(R.id.widgetImage, bitmap);
return views;
}
Everything works fine and all grid items get displayed correctly, providing the synchronous image load executes quickly.
However, if I run the app on a slow network where image downloads can take a few seconds, I quickly see that many of my grid items fail to load completely. I added some logcat output, and could see that the adapter fails to request the grid items that are not loading.
So for instance, my widget shows a 3x3 grid of users, and the entire GridView holds 80 or so. When working correctly, I see the adapter request around the first 20 grid items, and they all load correctly. When image loads are slow, I see the adapter request items 0, 3, 5, and 8 (for example, it varies) but no requests are made for any other items. If I start to scroll the GridView, more items start to get requested but many items still fail to request at all.
It seems that taking too much time in getViewAt() is somehow breaking the display behaviour, despite the fact that android documentation says it is fine to perform long operations in this method. Anyone seen this problem or know of a solution?

Android KitKat 4.4 TalkBack view refresh issue

I'm running my app on an Android 4.4.2 (KitKat) device.
My app has a ListView.
When I add the last item to the list view, it shows some content, and about 5 seconds later, it changes (loads a different view to that specific list item).
While TalkBack is on -
If, in that 5 seconds window, I click on the last item - the TalkBack marks it, reads it, and does not let the view change.
I do not have this issue on previous Android version.
Anyone knows why this happens? and if I can override this behavior?
Thanks!
PB
I did not find a direct solution.
I have solved the issue by overriding accessibility default behavior.
I removed the mark around the view and kept only the reading part.
This is the code I used:
view.setAccessibilityDelegate(new AccessibilityDelegate() {
#Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
//call super to perform the action
boolean ret = super.performAccessibilityAction(host, action, args);
//call super with remove-focus action to remove the mark around the view
super.performAccessibilityAction(host, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, args);
return ret;
}
});

sendUserActionEvent() is null

I've got a real doozy here. When I click on spinners, open menu items, or open context menus on long-clicks I get the same Logcat message:
08-02 21:20:57.264: E/ViewRootImpl(31835): sendUserActionEvent() mView == null
The tag is ViewRootImpl, and the message is sendUserActionEvent() mView == null. I could not find anything helpful about this on the web. I searched through the Android sources and found some references to mView, but I could not find the file in which this log message is printed. For reference, I'm using a Samsung Galaxy S4 running 4.2.2, or API 17. The same message does NOT occur when debugging on a Nexus 7 running Android 4.3. Any ideas? Is this a Samsung-specific issue?
I also encuntered the same in S4. I've tested the app in Galaxy Grand , HTC , Sony Experia but got only in s4. You can ignore it as its not related to your app.
I solved this problem on my Galaxy S4 phone by replacing context.startActivity(addAccountIntent);
with startActivity(new Intent(Settings.ACTION_ADD_ACCOUNT));
Same issue on a Galaxy Tab and on a Xperia S, after uninstall and install again it seems that disappear.
The code that suddenly appear to raise this problem is this:
public void unlockMainActivity() {
SharedPreferences prefs = getSharedPreferences("CALCULATOR_PREFS", 0);
boolean hasCode = prefs.getBoolean("HAS_CODE", false);
Context context = this.getApplicationContext();
Intent intent = null;
if (!hasCode) {
intent = new Intent(context, WellcomeActivity.class);
} else {
intent = new Intent(context, CalculatingActivity.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
(context).startActivity(intent);
}
Even i face similar problem after I did some modification in code related to Cursor.
public boolean onContextItemSelected(MenuItem item)
{
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
Cursor c = (Cursor)adapter.getItem(info.position);
long id = c.getLong(...);
String tempCity = c.getString(...);
//c.close();
...
}
After i commented out //c.close(); It is working fine.
Try out at your end and update
Initial setup is as... I have a list view in Fragment, and trying to delete and item from list via contextMenu.
This has to do with having two buttons with the same ID in two different Activities, sometimes Android Studio can't find, You just have to give your button a new ID and re Build the Project
It is an error on all Samsung devices, the solution is:
put this line in your activity declaration in Manifest.
android:configChanges="orientation|screenSize"
also when you start the activity you should do this:
Intent intent = new Intent(CurrentActivity.this, NextActivity.class);
intent.setType(Settings.ACTION_SYNC_SETTINGS);
CurrentActivity.this.startActivity(intent);
finish();
I used this to make an activity as fullscreen mode, but this question does not need the fullscreen code, but in all cases might someone need it you can refer to this question for the rest of the code:
How to make VideoView full screen

android: showquickcontact() works great on froyo, not on eclair, which throws an ActivityNotFound exception

I've done a lot of googling over the days and I haven't been able to get this problem solved. I'm writing an app and a widget in which I want the quick contact dialog displayed when the user clicks on an ImageView or some other view element by calling QuickContact.showQuickContact(). For some reason, every time I try on Eclair, I get the following error thrown:
01-02 17:51:28.869: ERROR/AndroidRuntime(657):
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.sx.favwidget/com.sx.favwidget.PopupActivity}:
android.content.ActivityNotFoundException: No Activity found to handle
Intent { act=com.android.contacts.action.QUICK_CONTACT
dat=content://com.android.contacts/contacts/lookup/0n4D29415739
flg=0x14200000 (has extras)
(I left out the rest of the logcat, but I can put it back if you guys need it)
When I try the exact same code on Froyo, it just works. I don't want to have my app targeted only for Froyo users - I'm targeting 2.1 as the minimum OS level. I've found some other people on Stack Overflow struggling with getting QuickContacts to display.
I could use a QuickContactBadge, and that does work on Eclair, but I'm not allowed a QuickContactBadge in an AppWidget, so I have do this instead. I dug through Android's source code and found the relevant XML files and code for creating the layout but I can't just easily compile it myself because it's a huge headache with all the private API calls.
Here is my code. It's simple.
grid.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
String name = ((TextView)v.findViewById(R.id.grid_item_label)).getText().toString();
Cursor sc = getContentResolver().query(Contacts.CONTENT_URI, new String[] {Contacts.LOOKUP_KEY, Contacts._ID}, Contacts.DISPLAY_NAME + "= ?", new String[] {name}, null);
sc.moveToFirst();
String lookup_key = sc.getString(sc.getColumnIndex(Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup_key);
QuickContact.showQuickContact(getApplicationContext(), v, uri, QuickContact.MODE_SMALL, null);
}
}
It's just so strange that it works on Froyo, not Eclair, but the API call has been there since Android 2.0. Can anyone help me here??
Thanks so much!!!
I solved this as well some time ago but forgot to post how. What I did was launch a new activity that was transparent, and I got the rectangle from which the intent was launched. This activity had only a QuickContactBadge element, so I positioned it using the rectangle and performed a click action automatically on it. Once this was displayed, I finished the activity - but the badge remains. Therefore, when the person clicked out of the QuickContactBadge, they'd be right back to where they started.
I didn't get a chance to peruse your (Omegamon) code thoroughly - is your method similar to mine?

Categories

Resources