使用TimerTask和Timer与Widget AppWidgetProvider

时间:2015-05-17 15:47:06

标签: android timer widget timertask appwidgetprovider

我正在使用Android创建一个时钟小部件。我已经测试了时钟,逻辑似乎很好,但我需要让它每分钟更新一次。

我在我的XML中将updatePeriodMillis设置为60000,但Android将此限制为30分钟,因此它每半小时才更新一次。

我做了一些研究,并且Service或AlarmManager可能有效,除了我调用的方法需要通过onUpdate()方法传递给它的AppWidgetManager和AppWidgetId。

我尝试了两种(类似的)方法让分钟更新正常工作:

PHImageManager

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(AudioSource))]
public class Bhop : MonoBehaviour{

public AudioClip[] list;
AudioSource audio;
CharacterController characterController;
int number;

void Start () 
{
    audio = GetComponent<AudioSource>();
    characterController = GetComponent<CharacterController>();
    //Loading the items into the array
    list =  new AudioClip[]
    {
        (AudioClip)Resources.Load("Sound/jumplanding1.wav"),
        (AudioClip)Resources.Load("Sound/jumplanding2.wav"), 
        (AudioClip)Resources.Load("Sound/jumplanding3.wav"), 
        (AudioClip)Resources.Load("Sound/jumplanding4.wav")
    };
}

void OnCollisionEnter (Collision col)
{
    int number;
    number = Random.Range(0, list.Length);


    if (col.gameObject.name == "Sound") 
    {
        audio.PlayOneShot(list[number], 0.5f);
    }
}
}

非常感谢任何帮助。

感谢。

编辑:在我调试和发布这篇文章的时候,我最终将应用程序安装了半个小时。看起来计时器在第一次调用onUpdate()半小时后就开始了,但它在最初的30分钟内仍然不起作用。

2 个答案:

答案 0 :(得分:1)

好的,终于有了这个工作(考试因此帖子之间的差距很长)。

我最终使用了服务,待定意图和警报管理器来满足我的需求。

ClockWidget.class:

private static final String TAG = ClockWidget.class.getSimpleName();

@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
    super.onReceive(context, intent);
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName componentName = new ComponentName(context, ClockWidget.class);
    onUpdate(context, appWidgetManager, appWidgetManager.getAppWidgetIds(componentName));
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    Log.d(TAG, "onUpdate");

    ComponentName componentName = new ComponentName(context, ClockWidget.class);
    int[] allWidgetIds = appWidgetManager.getAppWidgetIds(componentName);

    Intent intent = new Intent(context.getApplicationContext(), UpdateService.class);
    intent.setAction(UpdateService.ACTION_UPDATE);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
    context.startService(intent);

    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    m.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pendingIntent);
}

UpdateService.class:

private static final String TAG = UpdateService.class.getSimpleName();

public static final String ACTION_UPDATE = "uk.co.thebillington.laxe.ACTION_UPDATE";

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent == null) {
        return super.onStartCommand(null, flags, startId);
    }

    String action = intent.getAction();
    if (action == null) {
        return super.onStartCommand(intent, flags, startId);
    }

    Log.d(TAG, String.format("onStartCommand: %s", action));

    if (action.equals(ACTION_UPDATE)) {
        int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
        for (int widgetId : allWidgetIds) {
            updateWidget(widgetId);
        }
    }

    return super.onStartCommand(intent, flags, startId);
}

private void updateWidget(int widgetId) {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());

    RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.clock);

    //Do stuff

    appWidgetManager.updateAppWidget(widgetId, views);
}

答案 1 :(得分:0)

  

我做了一些研究,并且Service或AlarmManager可能有效,除了我调用的方法需要通过onUpdate()方法传递给它的AppWidgetManager和AppWidgetId。

将应用小部件ID保存在文件中。或者,使用updateAppWidget()的风格作为第一个参数,将ComponentName而不是应用小部件ID作为第一个参数,将应用小部件的所有实例更新为相同的RemoteViews

您可以从AppWidgetManager using getInstance()获取IntentService

  

我已尝试过两种(类似的)方法让分钟更新正常工作

这是毫无意义的,因为它只会在您的流程运行时起作用。