RemoteViewsService onGetViewFactory not called - android

I'm sure I'm missing something simple here but onGetViewFactory is not calling while attempting to populate a StackWidget. I've gone over this multiple times and cannot find my error.
The RemoteViewsService is being attached in updateWidget:
public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int widgetId) {
// Create the RemoteViews to represent the widget layout.
Log.i(TAG, "updateWidget: Creating RemoteViews");
RemoteViews widgetViews = new RemoteViews(context.getPackageName(), R.layout.stack_widget_layout);
// Create an intent that points to our widget service.
Log.i(TAG, "updateWidget: Creating Intent");
Intent remoteIntent = new Intent(context, StackWidgetService.class);
// Attach that intent to the RemoteViews as our remote adapter.
Log.i(TAG, "updateWidget: Setting Adapter");
widgetViews.setRemoteAdapter(R.id.stack_view, remoteIntent);
// Set which view should be used as the empty view.
Log.i(TAG, "updateWidget: Setting empty view");
widgetViews.setEmptyView(R.id.stack_view, R.id.text_empty);
// Update the widget.
Log.i(TAG, "updateWidget: Updating widget");
appWidgetManager.updateAppWidget(widgetId, widgetViews);
}
The following should be called after calling appWidgetManager.updateAppWidget but is not:
#Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
// NOT CALLED
Log.i(TAG, "onGetViewFactory: Creating new view factory");
return new StackWidgetViewFactory(getApplicationContext());
}
As far as I can tell, my manifest is correct:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".stackwidget.StackWidgetProvider"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/stack_widget_info" />
</receiver>
<service android:name=".stackwidget.StackWidgetService"
android:exported="true"
android:permission="android.permission.BIND_REMOTEVIEWS"/>
</application>
And here is my stack_widget_info.xml, for safety:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="180dp"
android:updatePeriodMillis="1800000"
android:initialLayout="#layout/stack_widget_layout"
android:autoAdvanceViewId="#layout/stack_item"
android:widgetCategory="home_screen"
android:resizeMode="horizontal |vertical">
</appwidget-provider>

The issue was actually in my widget layout. Constraint layout was causing issues. It runs correctly when changing over to Linear layout.

Related

How to show two different activity in recent task from same application in android?

I want to open an activity from widget and another activity from application launcher. Both the activity should show in recent task at once. Currently the current activity override the previous opened activity. I want both activity in recent task.
Please find the codes here:
public class SimpleAppWidget extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for(int i=0; i<appWidgetIds.length; i++){
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pending = PendingIntent.getActivity(context, 0,intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.activity_main);
views.setOnClickPendingIntent(R.id.btnClick, pending);
appWidgetManager.updateAppWidget(appWidgetId,views);
Toast.makeText(context, "widget added", Toast.LENGTH_SHORT).show();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hcl.mobility.testwidget">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.TestWidget">
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:launchMode="singleTask" />
<receiver android:name="hcl.mobility.testwidget.SimpleAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/simple_app_widget_info" />
</receiver>
</application>
</manifest>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dp"
android:updatePeriodMillis="0"
android:minHeight="146dp"
android:initialLayout="#layout/activity_main">
</appwidget-provider>
app launcher activity in recent task
widget activity in recent task
I want to show both activity in recent task.
delete android:launchMode="singleTask"
addFlags
Intent intent = new Intent(context, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);

How to call an activity before screen lock is shown?

I want to start an activity even before screen lock after rebooting. here is my code
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.bootservicestartup.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BootUpReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
</application>
public class BootUpReceiver extends BroadcastReceiver {
#SuppressLint("InlinedApi")
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent i = new Intent(context, MainActivity.class);
i.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
what the code does is when the phone is rebooted, an activity will be shown. that works. but I also want the activity to be shown even before showing the screen lock.
Hope this helps you if you did it as a service;
You need the following in your AndroidManifest.xml file:
1) In your element:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2) In your element (be sure to use a fully-qualified [or relative] class name for your BroadcastReceiver):
<receiver android:name="com.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
(you don't need the android:enabled, exported, etc., attributes... the Android defaults are correct)
In MyBroadcastReceiver.java:
package com.example;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}

Start MainActivity from AppWidget doesn't work

I'm trying to launch my MainActivity from my AppWidget with pending intent but I can't figure out why it doesn't fire the intent. The widget has a ListView with up to 3 items, which is bind to a RemoteViewsService. I want to start my MainActivity when any of the rows is clicked. Can anyone tell me what I might done wrong?
I already checked some related posts like this Launching an activity from an AppWidget, and even tried to run the sample from here https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget, and while the sample works, still can't tell what I did differently.
Here are some of my code that are relevant, please let me know if I should post more, and apologize in advance if my post doesn't look right as this is my first question:
Widget layout:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/stocks"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
AppWidgetProvider class:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d(LOGTAG, "onUpdate");
Log.d(LOGTAG, "appWidgetIds.length="+appWidgetIds.length);
for (int i = 0; i < appWidgetIds.length; ++i) {
Log.d(LOGTAG, "appWidgetIds[i]="+appWidgetIds[i]);
}
// update each of the app widgets with the remote adapter
for (int i = 0; i < appWidgetIds.length; ++i) {
updateWidget(context, appWidgetManager, appWidgetIds[i]);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
public void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
Log.d(LOGTAG, "updateWidget id="+appWidgetId);
// Sets up the intent that points to the StackViewService that will
// provide the views for this collection.
Intent intent = new Intent(context, StockAppWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// 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.
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.stock_appwidget);
rv.setRemoteAdapter(R.id.stocks, intent);
Intent contentIntent = new Intent(context, MainActivity.class);
//contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent startAppPendingIntent =
PendingIntent.getActivity(context, 0, contentIntent, 0);
rv.setPendingIntentTemplate(R.id.stocks, startAppPendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, rv);
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="x40241.chris.yuan.a4.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Light.DarkActionBar" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SearchableActivity" >
<intent-filter>
<action android:name="x40241.chris.yuan.a4.app.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".StockServiceImpl" />
<service android:name=".StockAppWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<receiver android:name=".ServiceLauncher">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".StockAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/stock_appwidget_info" />
</receiver>
</application>
</manifest>
I think I found the answer, or at least a workable solution in a related post:
AdapterViewFlipper in app widget: setPendingIntentTemplate() and setOnClickFillInIntent() not working
It turns out I wasn't setting the FillInIntent properly. I should call setOnClickFillInIntent on the top level view of the list item instead of the list itself. Here's the code change that made it work in RemoteViewsFactory:
public RemoteViews getViewAt(int position) {
if (DEBUG) Log.d(LOGTAG, "StockRemoteViewsFactory getViewAt position="+position);
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
rv.setTextViewText(R.id.text_symbol, mStockItems.get(position).getSymbol());
rv.setTextViewText(R.id.text_price, String.format("$%.2f", mStockItems.get(position).getPrice()));
Intent fillInIntent = new Intent(Intent.ACTION_MAIN);
fillInIntent.putExtra(StockAppWidgetProvider.ITEM_NUM, position);
// set on the top level view of the list item, instead of the list view itself
//rv.setOnClickFillInIntent(R.id.stocks, fillInIntent);
rv.setOnClickFillInIntent(R.id.general_layout, fillInIntent);
return rv;
}

App widget does not update textview even onUpdate method works

My problem is I have an app widget which needs to be updated in every 32 mins. However, it's not updating the textview. I placed Log entry to my onUpdate method to see is it working on Logcat, and i confirmed method is working properly but just it's not changing the value of textview. Here is my code;
AppWidgetProvider:
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
ComponentName thisWidget=new ComponentName(context,
IzUlasimProvider.class);
int[] allWidgetIds=appWidgetManager.getAppWidgetIds(thisWidget);
for(int id:allWidgetIds){
String now=new SimpleDateFormat("HH:mm").format(new Date());
RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.widget);
views.setTextViewText(R.id.tvWidget,now);
appWidgetManager.updateAppWidget(id, views);
now=null;
}
Log.w("Update","Update Finished");
}
My config file:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="#layout/widget"
android:minHeight="110dp"
android:updatePeriodMillis="1920000"
android:minWidth="250dp" android:configure="com.izulasim.widget.IzWidgetConfig">
AndroidManifest part for the widget:
<receiver android:name="com.izulasim.widget.IzWidgetProvider">
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/widget_config" />
</receiver>
<activity
android:name="com.izulasim.widget.IzWidgetConfig"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<provider android:name=".IzUlasimProvider"
android:authorities="com.izulasim.provider.IzUlasim" />

Embed widget in android activity - not responding

I'm trying to make a home screen. I've got the widget to display but I need to send some kind of notify to it so it will start. Perhaps I'm missing something in the AndroidManifest.xml?
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.Fredrik" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".HomeScreen" android:label="#string/app_name"
android:launchMode="singleInstance" android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
HomeScreen.java:
public class HomeScreen extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final AppWidgetManager widgets = AppWidgetManager
.getInstance(getApplicationContext());
List<AppWidgetProviderInfo> installedProviders = widgets
.getInstalledProviders();
for (AppWidgetProviderInfo ws : installedProviders) {
if (ws.label.startsWith("Music (Large)")) {
AppWidgetHost h = new AppWidgetHost(getApplicationContext(), 10);
int id = h.allocateAppWidgetId();
AppWidgetHostView v= h.createView(this, id, ws);
setContentView(v);
h.startListening();
break;
}
}
}
}
Does anyone have a clue?
According to this post, you cannot program widget insertion yourself: http://groups.google.com/group/android-developers/browse_thread/thread/e4a5b4a87afcf707?pli=1
You have to call an intend that will give the user the ability to pick.
I was still surprised to hear you managed to get it to display...

Categories

Resources