appwidget Never go to onUpdate - android

my Application widget Never go to the onUpdate function
i add 3000 mili for testings but except the first time you add it,
it never goes to the onUpdate function.
what am i doing wrong ?
my manifest file:
<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"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="layout.ClockWidgetClass">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/clock_widget_class_info" />
</receiver>
</application>
my clockWidget:
/**
* Implementation of App Widget functionality.
*/
public class ClockWidgetClass extends AppWidgetProvider {
static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager,
final int appWidgetId) {
//getting shered prefrences
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String name = preferences.getString("randomString", "");
if(!name.equalsIgnoreCase(""))
{
name = name; /* Edit the value here*/
}
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.clock_widget_class);
//set chosen design visible
//set all visibility to 0
views.setViewVisibility(R.id.AnalogClock0, View.INVISIBLE);
views.setViewVisibility(R.id.AnalogClock1, View.INVISIBLE);
views.setViewVisibility(R.id.AnalogClock2, View.INVISIBLE);
views.setViewVisibility(R.id.AnalogClock3, View.INVISIBLE);
//turning on the correct clock
if (name.equals("1")) {
views.setViewVisibility(R.id.AnalogClock0, View.VISIBLE);
} else if (name.equals("2")) {
views.setViewVisibility(R.id.AnalogClock1, View.VISIBLE);
} else if (name.equals("3")) {
views.setViewVisibility(R.id.AnalogClock2, View.VISIBLE);
} else {
views.setViewVisibility(R.id.AnalogClock3, View.VISIBLE);
}
// views.setTextViewText(R.id.appwidget_text, name);
//updateting 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);
}
}
#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
}
#Override
public void onReceive(Context context, Intent intent) {
// Chain up to the super class so the onEnabled, etc callbacks get dispatched
super.onReceive(context, intent);
// Handle a different Intent
Log.d("reciving", "onReceive()" + intent.getAction());
}
}
my Widget xml file:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="#layout/clock_widget_class"
android:initialLayout="#layout/clock_widget_class"
android:minHeight="110dp"
android:minWidth="250dp"
android:previewImage="#drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="3000"
android:widgetCategory="home_screen"></appwidget-provider>

Never might not be correct. It just doesn't happen in the time you expect it to happen. With the documentation for updatePeriodMillis you'll find an important note:
Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes.
So you might have to wait for this 30 minutes before another call to onUpdate() happens.

Related

Widget issue: Exiting the main app resets the static variables in the widget

I have a widget with a button. In my app widget (TestWidget.java) I have a private static boolean variable (buttonClicked) initialized to false.
When I click on the button the boolean buttonClicked is set to true. I have an updatePeriodMillis set to the minimum 30min (1800000ms).
First onUpdate comes: buttonClicked value is true. As expected.
Then I stop my main app. The following onUpdates shows buttonClicked value as false.
launch --> 06-10 10:55:56.365 4186-4186/com.narb.testwidget I/TESTWID: update setButtonClicked false
1st onUpdate after button click --> 06-10 10:56:11.685 4186-4186/com.narb.testwidget I/TESTWID: setButtonClicked true
onUpdate after main app exit --> I/TESTWID: update setButtonClicked false
Why is that?
App widget - TestWidget
public class TestWidget extends AppWidgetProvider {
private static RemoteViews views;
private static boolean buttonClicked = false;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
TestWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
Log.i("TESTWID", "update setButtonClicked "+buttonClicked);
views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
views.setOnClickPendingIntent(R.id.wid_btn_tst, setButton(context));
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public static void setButtonClicked(boolean b){
buttonClicked = b;
Log.i("TESTWID", "setButtonClicked "+buttonClicked);
}
public static PendingIntent setButton(Context context) {
Intent intent = new Intent();
intent.setAction("TEST");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, TestWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
}
Button code - TestWidgetReceiver
public class TestWidgetReceiver extends BroadcastReceiver{
private static boolean isButtonON = false;
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("TEST")){
updateWidgetButton(context, 2);
}
}
private void updateWidgetButton(Context context, int index) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_widget);
if(index == 2) {
if(isButtonON) {
remoteViews.setTextViewText(R.id.wid_btn_tst, "Test Off");
isButtonON = false;
}
else{
remoteViews.setTextViewText(R.id.wid_btn_tst, "Test On");
isButtonON = true;
TestWidget.setButtonClicked(isButtonON);
}
//REMEMBER TO ALWAYS REFRESH YOUR BUTTON CLICK LISTENERS!!!
remoteViews.setOnClickPendingIntent(R.id.wid_btn_tst, TestWidget.setButton(context));
}
TestWidget.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
}
}
Manifest
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="Test"
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=".TestWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/test_widget_info" />
</receiver>
<receiver
android:name=".TestWidgetReceiver"
android:label="widgetBroadcastReceiver" >
<intent-filter>
<action android:name="TEST" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/test_widget_info" />
</receiver>
</application>
In my app widget (TestWidget.java) I have a private static boolean variable (buttonClicked) initialized to false
static variables are a cache, at best.
Then I stop my main app.
I do not know exactly what you mean by that. My guess is that you mean that you remove a task associated with your app from the overview screen.
The following onUpdates shows buttonClicked value as false. Why is that?
If by "stop my main app", you do something like I outlined, you will have terminated your process. At a later point, such as when you click your app widget's button, Android will start a fresh process for you, at which point your static field, at which point your static field will be its default value.
I would have thought that widgets have their own memory copy as they continue to run even if the main app has exited?
No. The views associated with your app widget will exist, in the home screen. That does not include your TestWidget code, which is not part of the home screen.
I'm considering dropping this approach to do an alarmManager with a low refresh time (10 secs).
First, that's not possible on Android 5.1 and above, as it substantially drains the battery. Second, it does not guarantee that your process will stay around.
static variables are a cache, at best. Any app, including those with an app widget, need to store important data somewhere else: SharedPreferences, SQLite database, some other sort of file, a server, etc.
If you force stop the app or the system decides to stop it due to low memory, all classes are dropped from the memory and all static variables are lost. In this case, you should either persist your data to the DB or SharedPreferences or similar or rethink the approach itself. Is it really necessary to do it the way you're doing here?

ActivityNotFoundException Intents + Widget

I'm trying to create a Widget which update the text every time I press the save button and get the information from 2 editText. When I press the button to send by Intent the variables it throws
"android.content.ActivityNotFoundException: Unable to find explicit activity class"
in the logcat. Here my code:
Main.class
public class MainActivity extends AppCompatActivity {
Button save;
EditText Nom;
EditText Cognom;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
save = (Button) findViewById(R.id.save);
Nom = (EditText) findViewById(R.id.editTextNom);
Cognom = (EditText) findViewById(R.id.editTextCognom);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i;
i = new Intent(MainActivity.this, NewAppWidget.class);
i.putExtra("NOM",Nom.getText().toString());
i.putExtra("COGNOM",Cognom.getText().toString());
startActivity(i);
}
});
}
}
WidgetClass
public class NewAppWidget extends AppWidgetProvider {
static Intent intent = new Intent();
static String nom = intent.getExtras().getString("NOM");
static String cognom = intent.getExtras().getString("COGNOM");
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.TextViewNom, nom);
views.setTextViewText(R.id.TextViewCognom, cognom);
// 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);
}
}
#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
}
}
Manifest:
<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=".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>
</application>
Error:
android.content.ActivityNotFoundException: Unable to find explicit activity class
Dude first thing is you can not start an widget provider like an activity.
If you want update widget widget from activity you can do like this.
Intent intent = new Intent(this, MyAppWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
// Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
int[] ids = AppWidgetManager.getInstance(getApplication())
.getAppWidgetI‌​ds(new ComponentName(getApplication(), MyAppWidgetProvider.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);
You can pass your parameter to this intent or better you save your values in Shared Preference and use it in your widget provider class in onUpdate method.
I read your widgetprovider class, you will get many errors when using this class. For understanding android widget, you can fork and understand this Github sample.
In this sample you will get how to update widget, how to have multiple widget controls and much more. So i strongly recommend you go through this sample.
AppWidgetProvider extends BroadcastReceiver NOT ACTIVITY
i = new Intent(MainActivity.this, NewAppWidget.class);
startActivity(i);
To use startActivity you need to provide Activity class's child object
NewAppWidget is not an Activity !!

Run app widget - Could not identify launch activity

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.

Home screen widget does not show up in android

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>

Using sendBroadcast for update android widgets

I am creating a appwidget which needs to update when some changing in app's database.
What I do:
1. Create working widget
2. Override onReceive method:
public static final String DATABASE_CHANGED = " utimetable.DATABASE_CHANGED";
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (action.equals(DATABASE_CHANGED) || action.equals(Intent.ACTION_DATE_CHANGED))
{
AppWidgetManager gm = AppWidgetManager.getInstance(context);
int[] ids = gm.getAppWidgetIds(new ComponentName(context, widget_provider.class));
this.onUpdate(context, gm, ids);
}
else
{
super.onReceive(context, intent);
}
}
In AndroidManifest:
<receiver android:name=".widget_provider" android:label="#string/widget_today_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="utimetable.DATABASE_CHANGED" />
<action android:name="android.intent.action.DATE_CHANGED" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/widget_row" />
</receiver>
Add Broadcast sending into all DB changing functions:
public static void sendUpdateIntent(Context context)
{
Intent i = new Intent(context, widget_provider.class);
i.setAction(widget_provider.DATABASE_CHANGED);
context.sendBroadcast(i);
}
But widget still not updated when I make changes in DB.
What should I do?
just guessing looking at your code, but that space after the first " looks wrong
.... DATABASE_CHANGED = " utimetable.DATABASE_CHANGED";

Categories

Resources