简体   繁体   中英

Update an Android Widget when the screen is turned ON

The question is simple as it seems.

The Android Widget works as a charm, everything is OK.

I just want the widget content to be updated when (in the right moment) the user turn on its device screen .

I can't find a hint for this in internet nor the documentation. This means that I'm clearly overlooking something easy and important.

UPDATE

Thanks for the answer of Murtaza, seems perfect, but for some reason isn't working. My widget has already a receiver, so i added the suggested intent filter:

    <receiver android:name=".MyWidget" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="android.intent.action.SCREEN_ON" />
            <action android:name="android.intent.action.SCREEN_OFF" />
        </intent-filter>

Inside the widget class i overriden the suggested function:

@Override
  public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
      playNotification(context);
    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
      playNotification(context);
    }
 }

The playNotification() plays an alarm. It works properly inside the widget. But when I switch the screen ON and OFF, nothing happens.

UPDATE II - A working widget in Android

I post the whole code of the widget for who need it.

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.widget.RemoteViews;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.Calendar;


/**
 * Implementation of App Widget functionality.
 */
public class MyWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    // There may be multiple widgets active, so update all of them
    final int N = appWidgetIds.length;
    for (int i = 0; i < N; i++) {
        updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
    }
}

@Override
public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);

    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        playNotification(context, true);
    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
        playNotification(context, true);
    }
}

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                            int appWidgetId) {
    String widgetText = "";

    playNotification(context, true);

    widgetText += " DATE:" + Calendar.getInstance().getTime().getHours() + ":" + Calendar.getInstance().getTime().getMinutes();
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.mywidget);
    views.setTextViewText(R.id.appwidget_text, widgetText);
    appWidgetManager.updateAppWidget(appWidgetId, views);
}

public static void playNotification(Context context, boolean alarm) {

    try {
        Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        if (alarm) notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        Ringtone r = RingtoneManager.getRingtone(context, notification);
        if (!r.isPlaying())
            r.play();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

ANDROID MANIFEST

This is what you need to add to the manifest to have a working widget on Android. More, the filters I would like to make work.

   <receiver android:name=".MYWidget" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="android.intent.action.SCREEN_ON" />
            <action android:name="android.intent.action.SCREEN_OFF" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/mywidget_info" />
    </receiver>

PLEASE NOTE THAT the code works. Everything except what concern my question: "Update an Android Widget when the screen is turned ON"

You need to create a Broadcast Receiver for that.

Add these permissions in your Manifest.xml

 <receiver android:name=".MyBroadcastReceiver" android:enabled="true">
    <intent-filter>
       <action android:name="android.intent.action.ACTION_SCREEN_ON"></action>
       <action android:name="android.intent.action.ACTION_SCREEN_OFF"></action>
    </intent-filter>
</receiver>

MyBroadcastReceiver.java

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {

        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
           //update your widget.
        }
    }

}

The question turns into a new one, so I want to show some example. Your question now is, how to update the widget from inside all other classes. As I suspect, Your playNotification(); method is inside the receiver of Your widget. What You have to do is, make an extra class with Your playNotification() method as public , so You can call it from every other class. Look this example, based on the answer from Murtaza and Your update:

create an extra class:

 public class NotificationHelper{
 private Context mContext;


 //make a constructor and set Context or other objects/values if You need it
  public NotificationHelper(Context ctx){

     mContext = ctx;
  }


  public void playNotification(){

    //do Your stuff here inside
  }

}

With this public class, You can do Your stuff from anywhere else. For example inside Your AppWidget Receiver or Your BroadCastReceiver that will be fired if the screen goes on or off:

   @Override
   public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
     NotificationHelper mHelper = new NotificationHelper(context);
     mHelper.playNotification();
   } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
     NotificationHelper mHelper = new NotificationHelper(context);
     mHelper.playNotification();
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM