当屏幕打开时更新Android小部件

5
这个问题看起来很简单。
Android小部件运行良好,一切正常。
我只想在用户打开设备屏幕时(在正确的时刻)更新小部件内容。
我在互联网和文档中找不到任何提示。这意味着我显然忽略了某些易于理解但重要的东西。
更新:
感谢Murtaza的答案,看起来很完美,但由于某种原因它并没有起作用。我的小部件已经有一个接收器,所以我添加了建议的意图过滤器。
    <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>

在小部件类中,我覆盖了建议的函数:
@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);
    }
 }

playNotification()会播放一个警报。它在小部件内正常工作。但是当我打开和关闭屏幕时,什么都不发生。

第二次更新 - Android中的工作小部件

我发布了整个小部件的代码供需要的人使用。

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清单文件

以下是在Android上创建工作小部件所需添加到清单文件的内容。此外,我想要使其工作的筛选器。

   <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>

请注意,代码是可行的。除了我问题所涉及的部分之外:"当屏幕开启时更新Android小部件"


没有帮助,我的问题是关于小部件的,它们没有 onPause() 和 onResume() 生命周期。 - donnadulcinea
我知道,但重点是要看BroadcastReceiver的示例。通过此接收器,您可以知道屏幕是否打开或关闭。如何更新您的小部件是另一回事。当屏幕打开时,您将收到接收器的通知,然后您可以更新您的小部件。Murtaza的答案是正确的。 - Opiatefuchs
在下面的代码中,您必须从接收器内部执行工作或调用另一个类中的方法来更新您的小部件。 - Opiatefuchs
是的,你说得对。APPWIDGET_UPDATE只由小部件处理。如果屏幕打开,它不会自动更新。当您想要了解有关执行操作的某些信息时,广播接收器非常有用。但是每个操作都必须注册,例如打开或关闭屏幕,或者在手机关闭时启动。 - Opiatefuchs
1
好的,但我的意思是创建一个外部类,在其中放置playNotification()方法。然后,您可以从小部件和接收器中调用它来打开屏幕。这非常重要,否则它将无法正常工作。此外,请删除您的小部件接收器中的SCREEN_ON和SCREEN_OFF意图过滤器,它们对该接收器没有任何影响。如果可以的话,我认为最好的方式是您把代码发送给我,我会检查并给出一个解决方案。我的邮件地址是opiatefuchs@gmail.com - Opiatefuchs
显示剩余7条评论
2个回答

1
你需要为此创建一个广播接收器。
在你的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.
        }
    }

}

这段代码听起来很完美,但是将它插入到我的小部件中却无法运行。 - donnadulcinea
3
<action android:name="android.intent.action.USER_PRESENT" /> 这个会起作用。 - Muhammad Mehdi Raza

0
问题变成了一个新的问题,所以我想展示一些例子。你现在的问题是如何从所有其他类中更新小部件。我猜测,你的playNotification();方法在小部件的接收器中。你需要做的是,创建一个额外的类,将你的playNotification()方法设为public,这样你就可以从任何其他类中调用它。看看这个例子,基于Murtaza的答案和你的更新:

创建一个额外的类:

 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
  }

}

使用这个公共类,您可以从任何地方执行您的操作。例如,在您的AppWidget接收器或广播接收器中,如果屏幕开启或关闭,它将被触发:
   @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();
   }
}

谢谢Opiafechus,我还更正了清单上的一个错误(android.intent.action.SCREEN_ON而不是ACTION_SCREEN_ON),并应用了您建议的代码(与我昨天更新时写的相同),但它不起作用,即小部件在屏幕打开时不调用playNotification()。 - donnadulcinea
你能否请发布你更新后的代码?我需要查看调用playNotification的类、你的接收器和完整清单文件。 - Opiatefuchs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接