In my simple example app i have 2 activity:
MainActivity.java
NewAppWidgetConfigureActivity.java
Also in my app i have class NewAppWidget.java who extends AppWidgetProvider
What i want to accomplish is this:
When i add home widget to screen, i want to open activity NewAppWidgetConfigureActivity.java first. It is ok till now, its working nice.
When i add home widget to screen, my widget has 2 buttons and one TextView.
What i want is this:
when i click first button, i want to open MainActivity.java
when i click second button, i want to open NewAppWidgetConfigureActivity.java.
However, its not working. By clicking buttons nothing happens. I try to implement solutions from other questions but i it does not working.
Here are codes:
Manifest file code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.petar.mywidgetwitbuttons">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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=".NewAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/new_app_widget_info" />
</receiver>
<activity android:name=".NewAppWidgetConfigureActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
</application>
This is code for new_ap_widget_info.xml, where i add all necessary info for my widget, including line of code where i automatically open activity NewAppWidgetConfigureActivity.java when i add widget.
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.example.petar.mywidgetwitbuttons.NewAppWidgetConfigureActivity"
android:initialKeyguardLayout="#layout/new_app_widget"
android:initialLayout="#layout/new_app_widget"
android:minHeight="110dp"
android:minWidth="180dp"
android:previewImage="#drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen" />
This is code for NewAppWidget.java class who extends AppWidgetProvider
package com.example.petar.mywidgetwitbuttons;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
/**
* Implementation of App Widget functionality.
* App Widget Configuration implemented in {#link NewAppWidgetConfigureActivity NewAppWidgetConfigureActivity}
*/
public class NewAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = NewAppWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
Log.d("widget", "onUpdatePrvo: Widget testiramo");
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
Intent intent = new Intent(context, MainActivity.class);
Intent intent2 = new Intent(context, NewAppWidgetConfigureActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
PendingIntent pendingIntent2 = PendingIntent.getActivity(context, 0, intent2, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setOnClickPendingIntent(R.id.buttonCLICK, pendingIntent);
views.setOnClickPendingIntent(R.id.buttonCLICK2, pendingIntent2);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onDeleted(Context context, int[] appWidgetIds) {
// When the user deletes the widget, delete the preference associated with it.
for (int appWidgetId : appWidgetIds) {
NewAppWidgetConfigureActivity.deleteTitlePref(context, appWidgetId);
}
}
#Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
#Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}
Also, when i remove this line of code from provider info, then i can open MainActivity.java on the first button click, and still can not open NewAppWidgetConfigureActivity.java by clicking second button.
android:configure="com.example.petar.mywidgetwitbuttons.NewAppWidgetConfigureActivity"
And here is full provider info code without android:configure=""
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.example.petar.mywidgetwitbuttons.NewAppWidgetConfigureActivity"
android:initialKeyguardLayout="#layout/new_app_widget"
android:initialLayout="#layout/new_app_widget"
android:minHeight="110dp"
android:minWidth="180dp"
android:previewImage="#drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen" />
These easy steps could help you to resolve your problem.
App widget allows certain UI controls not everything. So check what are allowed and what are not.
https://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
Do not extend or create a custom UI control class. Ex;- class CustomButton extends Button
I do see your Intents do not have extra parameters. That might confuse the PendingIntent compare logic internally. So add a custom Action or few extra parameters to the intent.
EX;-
Intent a = new Intent("MainActivity");
Intent b = new Intent("ConfigureActivity");
This works for me.
public class widget_wordss extends AppWidgetProvider {
private static final String ACTION_SIMPLEAPPWIDGET = "ACTION_BROADCASTWIDGETSAMPLE";
private static final String ACTION_SIMPLEAPPWIDGET1 = "ACTION_BROADCASTWIDGETSAMPLE1";
public boolean widg = false;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int
appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_main_words);
Intent intent = new Intent(context, widget_wordss.class);
Intent intent1 = new Intent(context, widget_wordss.class);
intent.setAction(ACTION_SIMPLEAPPWIDGET);
intent1.setAction(ACTION_SIMPLEAPPWIDGET1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.btnOpen, pendingIntent);
views.setOnClickPendingIntent(R.id.btnayar, pendingIntent1);
appWidgetManager.updateAppWidget(appWidgetId, views);
Related
In AndroidStudio i create a new android project an create a app widget and choose option for configuration activity. AndroidStudio generates now the provider-info xml, the declerations in manifest xml an the both java classes. One activity, one widget provider.
This should be runnable but i get error: Could not identify launch activity: Default Activity not found. Error while Launching activity. The launch field also shows a red cross.
I dont understand why because there is no default activity. The configuration activity should start when the widget provider start working. To do so there is a intent-filter for the activitiy with android.appwidget.action.APPWIDGET_CONFIGURE.
I add also categroy in intent-filter LAUNCHER and DEFAULT. In provider and in activity. But still get the error message.
If I choose "Nothing" in launch configuration and I run the app it brings only many error messages: Waiting for application to come online: com.example.desktop_win10.myapplication | com.example.desktop_win10.myapplication.test
But the widget isnt installed and doesnt run. What doing Im wrong? I try out Intellij and AndroidStudio.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.desktop_win10.myapplication" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<receiver android:name=".NewAppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/new_app_widget_info" />
</receiver>
<activity android:name=".NewAppWidgetConfigureActivity" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
</application>
</manifest>
widget_info.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="#drawable/example_appwidget_preview"
android:initialLayout="#layout/new_app_widget"
android:configure="com.example.desktop_win10.myapplication.NewAppWidgetConfigureActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:initialKeyguardLayout="#layout/new_app_widget">
</appwidget-provider>
And there are the two Java classes.
EDIT1:
Now I add category LAUNCHER and action MAIN:
<activity android:name=".NewAppWidgetConfigureActivity" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
If I start the debugger sometimes the widget ist in the widget store and sometimes not.
I also see that in the generated java activity class is a finish method called:
// If this activity was started with an intent without an app widget ID, finish with an error.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
return;
}
But it also doesnt work if I delete thid. I dont unterstand why a the default google example not work.
Here are the java classes:
Activity:
package com.example.desktop_win10.myapplication;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
/**
* The configuration screen for the {#link NewAppWidget NewAppWidget} AppWidget.
*/
public class NewAppWidgetConfigureActivity extends Activity {
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
EditText mAppWidgetText;
private static final String PREFS_NAME = "com.example.desktop_win10.myapplication.NewAppWidget";
private static final String PREF_PREFIX_KEY = "appwidget_";
public NewAppWidgetConfigureActivity() {
super();
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if the user presses the back button.
setResult(RESULT_CANCELED);
setContentView(R.layout.new_app_widget_configure);
mAppWidgetText = (EditText)findViewById(R.id.appwidget_text);
findViewById(R.id.add_button).setOnClickListener(mOnClickListener);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If this activity was started with an intent without an app widget ID, finish with an error.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
return;
}
mAppWidgetText.setText(loadTitlePref(NewAppWidgetConfigureActivity.this, mAppWidgetId));
}
View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
final Context context = NewAppWidgetConfigureActivity.this;
// When the button is clicked, store the string locally
String widgetText = mAppWidgetText.getText().toString();
saveTitlePref(context,mAppWidgetId,widgetText);
// It is the responsibility of the configuration activity to update the app widget
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
NewAppWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
};
// Write the prefix to the SharedPreferences object for this widget
static void saveTitlePref(Context context, int appWidgetId, String text) {
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
prefs.apply();
}
// Read the prefix from the SharedPreferences object for this widget.
// If there is no preference saved, get the default from a resource
static String loadTitlePref(Context context, int appWidgetId) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
String titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);
if (titleValue != null) {
return titleValue;
} else {
return context.getString(R.string.appwidget_text);
}
}
static void deleteTitlePref(Context context, int appWidgetId) {
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.remove(PREF_PREFIX_KEY + appWidgetId);
prefs.apply();
}
}
And Provider:
package com.example.desktop_win10.myapplication;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
/**
* Implementation of App Widget functionality.
* App Widget Configuration implemented in {#link NewAppWidgetConfigureActivity NewAppWidgetConfigureActivity}
*/
public class NewAppWidget extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
#Override
public void onDeleted(Context context, int[] appWidgetIds) {
// When the user deletes the widget, delete the preference associated with it.
for (int appWidgetId : appWidgetIds) {
NewAppWidgetConfigureActivity.deleteTitlePref(context, appWidgetId);
}
}
#Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
#Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = NewAppWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
Did you add:
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
?
As I know, without it android won't know which activity to launch as the main activity.
I'm working on an android project and created a widget for toggling Bluetooth (i.e., Pressing the widget turn on Bluetooth if turned off and vice versa). But the problem is that click listener of button is not working and when I click on the widget on the home screen it does nothing.
I do a lot of googling and tried almost all solutions but unfortunately nothing worked for me. I am unable to get the idea why my code is not working.
Here is the manifest file for project:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gmail.redprince007.togglebluetooth" >
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".BluetoothToggle" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/bluetooth_toggle_info" />
</receiver>
</application>
</manifest>
And xml file for widget layout is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/widget_margin">
<Button
android:id="#+id/btnToggleBluetooth"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bluetooth_on" />
</RelativeLayout>
And AppWidget-proviver.xml is:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="#layout/bluetooth_toggle"
android:initialLayout="#layout/bluetooth_toggle"
android:minHeight="40dp"
android:minWidth="40dp"
android:previewImage="#drawable/ic_bluetooth_icon"
android:updatePeriodMillis="0"
android:widgetCategory="home_screen|keyguard">
</appwidget-provider>
And BluetoothOnOff.Java Is:
public class BluetoothToggle extends AppWidgetProvider {
private static final String TAG = "BluetoothToggle";
private final String toggleBluetoothAction = "ToggleBluetooth";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d(TAG, "onUpdate()");
// There may be multiple widgets active, so update all of them
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.bluetooth_toggle);
remoteViews.setOnClickPendingIntent(R.id.btnToggleBluetooth, pendingIntent);
updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
}
}
#Override
public void onEnabled(Context context) {
Log.d(TAG, "onEnabled()");
// Enter relevant functionality for when the first widget is created
}
#Override
public void onDisabled(Context context) {
Log.d(TAG, "onDisabled()");
// Enter relevant functionality for when the last widget is disabled
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
Log.d(TAG, "updateAppWidget()");
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.bluetooth_toggle);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
Thanks in advance for your reply and help. I spend a day to resolve the issue but all my effort went in vain.
So finally I solve the problem after searching for two days. Here is the correct code:
Intent intent = new Intent(context, BluetoothToggle.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
intent.putExtra(toggleBluetoothAction, toggleBluetoothAction);
And here is the onReceive() method which is called every time I clicked on the widget.
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
if (bundle != null && bundle.getString(toggleBluetoothAction) != null)
{
// My Logic
}
}
Take a look at the intent setAction and putExtra, which are useful in my case to solve the problem. I checked many website but most of them didn't include this piece of code to make widget clickable. All they did is to create an Intent and then immediately create a PendingIndent. I did the same but nothing helped me in any way.
Thanks.
I have got the issue that is very popular on Stackoverflow and there are a lot of recipes how to fix it. But unfortunately, all of them don`t fit me.
I created appWidget with collection (StackView), added ConfigActivity for configuration and permanent update mechanism with assigned time interval. Widget is displayed in a proper way, update works fine but when I want to run Config Activity and click on widget - nothing happens!
Maybe, I've missed some important details and hope you'll suggest me. Here are some of code snippets:
Manifest
<uses-sdk android:minSdkVersion="11"
android:targetSdkVersion="22"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name=".FinApp"
android:allowBackup="true"
android:icon="#mipmap/ic_fin"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".widget.WidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/fin_app_widget_info" />
</receiver>
<activity android:name=".ConfigActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<service
android:name=".widget.WidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS"/>
</application>
AppWidgetProvider
public class WidgetProvider extends AppWidgetProvider {
private static final String TAG = WidgetProvider.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive");
super.onReceive(context, intent);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.w(TAG, "onUpdate: appWidgetIds - " + Arrays.toString(appWidgetIds));
for (int id : appWidgetIds) {
updateAppWidgetInstance(context, appWidgetManager, id);
}
}
public static void updateWidgetsOnDataSetChanged (Context context) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
new ComponentName(context.getPackageName(), WidgetProvider.class.getName()));
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
}
private static void addWidgetListener(Context context, int appWidgetId, RemoteViews widget) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent runConfigActivity = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
widget.setOnClickPendingIntent(R.id.widget_container, runConfigActivity);
}
private static void setupWidgetService(Context context, int appWidgetId, RemoteViews widget) {
Intent adapterIntent = new Intent(context, WidgetService.class);
adapterIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
adapterIntent.setData(Uri.fromParts("content", String.valueOf(appWidgetId), null));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
widget.setRemoteAdapter(R.id.widget_list, adapterIntent);
} else {
//noinspection deprecation
widget.setRemoteAdapter(appWidgetId, R.id.widget_list, adapterIntent);
}
}
private static void updateAppWidgetInstance(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Log.e(TAG, "updateAppWidgetInstance");
RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget_collection_layout);
setupWidgetService(context, appWidgetId, widget);
addWidgetListener(context, appWidgetId, widget);
appWidgetManager.updateAppWidget(appWidgetId, widget);
}
}
widget_collection_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<StackView
android:id="#+id/widget_list"
android:loopViews="true"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
As I understand the point is in the method addWidgetListener
private static void addWidgetListener(Context context, int appWidgetId, RemoteViews widget) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent runConfigActivity = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
widget.setOnClickPendingIntent(R.id.widget_container, runConfigActivity);
}
but I have no idea what's wrong...
After some investigation I came to a conclusion that if I use collection in appWidget and want to open Config Activity tapping on whole widget container that the best practice is using setPendingIntentTemplate method, even if you dont't want to handle item click but the whole list instead (list container).
private static void addWidgetListener(Context context, int appWidgetId, RemoteViews widget) {
Intent intent = new Intent(context, ConfigActivity.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent runConfigActivity = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
widget.setPendingIntentTemplate(R.id.widget_list, runConfigActivity);
}
and add 2 lines in WidgetFactory in method getViewAt(int position)
Intent intent = new Intent();
views.setOnClickFillInIntent(R.id.widget_item_container, intent);
I am for the first time checking how to make a widget app. The first thing I want to do is add a widget to the home screen, a basic textview with a static text. Nothing else.
After reading the guide I tried to construct one. I get to the point that the widget is listed by the system, I run normally the configuration activity. But when I drag and drop the widget to the homescreen, nothing happens. I don't know where to debug, when I do debug my Widgetprovider class all looks fine (resources are not null, view gets updated) so I don't know where to look for an error message.
What is wrong?
At least some direction on where to look would be very appreciated!
Here's the manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tizanacode.ExJakdojade">
<application android:allowBackup="true"
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<activity
android:name="WidgetConfigurationActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:icon="#drawable/ic_launcher"
android:label="Watched Line"
android:name="ExJakdoJade" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/ex_jakdojade_info" />
</receiver>
</application>
Here is the provider class:
public class ExJakdoJade extends AppWidgetProvider {
private static final String ACTION_CLICK = "ACTION_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
ExJakdoJade.class);
/*int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {*/
for (int widgetId : appWidgetIds) {
// Create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.layout);
Log.w("WidgetExample", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(R.id.update, String.valueOf(number));
// Register an onClickListener
Intent intent = new Intent(context, ExJakdoJade.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
}
In my application, I have a Fragment which is attached to the main activity. This Fragment displays data with the help of an adapter. In the adapter, I have inflated a layout which has a clickable text "Watch From Home". The adapter displays data from the server. I want to show the same data on the home screen and when I click on the "Watch From Home" text, a home screen widget should be created without any user interaction.
I made a receiver MyWidgetProvider.What should the method onClickText() for "Watch From Home" have so that it takes me to the widget? I must admit, I am new to android. Thanks
Android Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pack.android.receiver"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="#drawable/icon"
android:label="#string/app_name" >
<receiver android:name="MyWidgetProvider" >
<intent-filter >
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
MyWidgetProvider.Java file
public class MyWidgetProvider extends AppWidgetProvider {
private TextView team1Name;
private TextView team2Name;
private TextView team1Score;
private TextView team2Score;
public static boolean widgetView=false;
private static final String LOG = "com.playup.android.receiver";
public MyWidgetProvider(TextView team1Name, TextView team2Name, TextView team1Score, TextView team2Score){
this.team1Name=team1Name;
this.team2Name=team2Name;
this.team1Score=team1Score;
this.team2Score=team2Score;
initializeViews();
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
// Get all ids
ComponentName thisWidget = new ComponentName(context,MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
public void initializeViews(){
// team1Name= (TextView)content_layout.findViewById(R.id.team1Name);
}
}
UpdateWidgetService
public class UpdateWidgetService extends Service {
private static final String LOG = "com.playup.android.receiver";
#Override
public void onStart(Intent intent, int startId) {
Log.i(LOG, "Called");
// Create some random data
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// Create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),0x7f030061); //Since R could not be resolve, I used the generated ids
Log.w("Widget", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(0x7f0a022a,"Random: " + String.valueOf(number));
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(0x7f0a022a, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
stopSelf();
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
Simply saying, You can't create a home widget without any user interaction.
Update:
Your receiver tag should start like this:
<receiver
android:name=".MyWidgetProvider"
android:label="My widget label" >
<!-- The rest as is -->
</receiver>
Home Screen Widget can only add to Home Screen directly by user.Only user can add widget as guest to Home Screen or other applications.
Edit:
To see your widget in widgets list:
It is necessary that register your AppWidgetProvider in manifest.
Your App has to have Launcher/Main Activity,and App must be directly run by user,before it be visible in widgets list.This is necessary ,because no broadcastreceiver(and so no AppWidgetProvider),no service,... of your App could not register before your App run directly by user.If you look at your manifest,you will see that your App has no Launcher/Main Activity(it has only a receiver),so it can not run by user and your AppWidgetProvider(that is a broadcastreceiver) will not register and thereupon you can not see your widget in widget list.
This had me scratching my head for a while.
I had the meta-data tag as child of the intent-filter tag, which is wrong. The meta-data is to be child of the receiver tag.
Incorrect version
<receiver
android:name=".AppWidgetReceiver"
android:label="AppWidgetReceiver" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/appwidget_info" />
</intent-filter>
</receiver>
Following is the correct version
<receiver android:name=".AppWidgetReceiver"
android:label="AppWidgetReceiver" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/appwidget_info" />
</receiver>