简体   繁体   English

Android Widget-如何检查父应用程序是否正在运行

[英]Android Widget - How to check if parent app is running

Speaking in Android. 用Android说话。 I have an application and a widget. 我有一个应用程序和一个小部件。 The widget is supposed to auto update every n seconds, and it works fine until the parent app is killed. 该小部件应该每隔n秒自动更新一次,并且在父应用程序被杀死之前可以正常工作。 Once the app is killed, it does not update any longer. 一旦应用被杀死,它就不再更新。 This occurs on both my timer based updates and the onClickPendingIntent updates. 我的基于计时器的更新和onClickPendingIntent更新都发生这种情况。

Is there any way to check if the parent application is running within the widget, and if it is not running to start it? 有什么方法可以检查父应用程序是否在窗口小部件中运行以及是否没有运行以启动它? (preferably without using getRunningTasks (or any other extra permissions), but if I have to that's fine) (最好不使用getRunningTasks(或任何其他额外的权限),但如果可以的话)

Here's the important bits of my widget code, for debugging it will display two numbers, one number that is updated based on the timer and one number that is updated on keypress. 这是我的小部件代码的重要部分,要进行调试,它将显示两个数字,一个数字是根据计时器更新的,另一个数字是在按键时更新的。 The widget is drawn based on the timer. 该小部件是根据计时器绘制的。

    private static final String SYNC_CLICKED = "automaticWidgetSyncButtonClick";
public static int counter = 0; // time based update
public static int counter2 = 0; // onClick update


public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    Timer timer = new Timer();
    // 2 seconds for debug   
    timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 2000);

    RemoteViews remoteViews;
    ComponentName watchWidget;
    remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_main);
    watchWidget = new ComponentName(context, HelloWidget.class);

    remoteViews.setOnClickPendingIntent(R.id.widget_textview, getPendingSelfIntent(context, SYNC_CLICKED));
    appWidgetManager.updateAppWidget(watchWidget, remoteViews);
}

protected PendingIntent getPendingSelfIntent(Context context, String action) {
    Intent intent = new Intent(context, getClass());
    intent.setAction(action);
    return PendingIntent.getBroadcast(context, 0, intent, 0);
}

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

    if (SYNC_CLICKED.equals(intent.getAction())) {
        counter2++;

        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

        RemoteViews remoteViews;
        ComponentName watchWidget;

        remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_main);
        watchWidget = new ComponentName(context, WidgetUpdater.class);

        remoteViews.setTextViewText(R.id.widget_textview, "Updating...");

    // unrelated async task here

        appWidgetManager.updateAppWidget(watchWidget, remoteViews);

    }
}

private class MyTime extends TimerTask {
    RemoteViews widgetView;
    AppWidgetManager appWidgetManager;
    SharedPreferences settings;
    ComponentName thisWidget;


    public MyTime(Context context, AppWidgetManager appWidgetManager) {
        this.appWidgetManager = appWidgetManager;
        settings = context.getSharedPreferences("prefs", 0);
        widgetView = new RemoteViews(context.getPackageName(), R.layout.widget_main);
        thisWidget = new ComponentName(context, HelloWidget.class);
    }

    @Override
    public void run() {
        counter++;
        String hashrate = settings.getString("hashrate", null);
        String rejected = settings.getString("rejected", null);
        widgetView.setTextViewText(R.id.widget_textview, counter + "-" + counter2);
        appWidgetManager.updateAppWidget(thisWidget, widgetView);
    }
} 

Once again, when the parent app gets killed my widget stops updating. 再一次,当父应用被杀死时,我的小部件停止更新。 Is there any way for me to start the parent application using my onClick method in the widget if it's not presently running? 如果当前没有运行,我可以使用小部件中的onClick方法启动父应用程序吗?

The problem is eventually your AppWidgetProvider will be destroyed by the system. 问题是您的AppWidgetProvider最终将被系统破坏。 It's really just a BroadcastReceiver , the lifecycle of which is limited to the duration of onReceive(), as per the documentation: 根据文档,它实际上只是一个BroadcastReceiver ,其生命周期仅限于onReceive()的持续时间:

A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). BroadcastReceiver对象仅在对onReceive(Context,Intent)的调用期间有效。 Once your code returns from this function, the system considers the object to be finished and no longer active. 一旦您的代码从该函数返回,系统将认为该对象已完成并且不再处于活动状态。

Letting your BroadcastReceiver hold onto your TimerTask implementation will fail, as you have already experienced. 正如您已经体验到的那样,让BroadcastReceiver保留TimerTask实现将失败。 The best approach it to use AlarmManager to send a PendingIntent at the next scheduled interval. 最好的方法是使用AlarmManager在下一个计划的时间间隔发送PendingIntent This PendingIntent could either start up a BroadcastReceiver or a Service (perhaps an IntentService ) which will perform the update and schedule the next alarm. 这个PendingIntent可以启动BroadcastReceiverService (也许是IntentService ),后者将执行更新并安排下一个警报。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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