Android Widget - Click for action, update under 30 minutes, separate instances

前端 未结 1 536
隐瞒了意图╮
隐瞒了意图╮ 2020-12-20 09:01

I\'ve tried to create a widget that, on click calls a routine on Configuration activity, on update calls another routine on Configuration activity, update must be under 30 m

相关标签:
1条回答
  • 2020-12-20 09:20

    For Timing under 30 mins and multiple instances i've decided to use only one timer for all instances.

    Below the code onCreate of Configuration Class:

    private static long millis = 20000;
    
    SharedPreferences read = context.getSharedPreferences(PREFS_NAME, 0);
    String firstinstance = read.getString("FirstInstance", "KO");
    if (firstinstance.equals("KO")) {
        SharedPreferences.Editor write = context.getSharedPreferences(
                PREFS_NAME, 0).edit();
        write.putString("FirstInstance", "OK");
        write.commit();
        Intent intent = new Intent(ControlloWidget.MY_WIDGET_UPDATE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                Configurazione.this, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 10);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), millis, pendingIntent);
        ControlloWidget.SaveAlarmManager(alarmManager, pendingIntent);
    }
    

    revert that process onDisabled of WidgetClass:

    @Override
    public void onDisabled(Context context) {
        // TODO Auto-generated method stub
        //super.onDisabled(context);
        SharedPreferences.Editor write = context.getSharedPreferences(PREFS_NAME, 0).edit();    
        write.putString("FirstInstance", "KO" );    
        write.commit();
        myAlarmManager.cancel(myPendingIntent);
    }
    static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent){
        myAlarmManager = tAlarmManager;
        myPendingIntent = tPendingIntent;
    }
    

    Now, setting up button Action and My Own Update: Class declaration:

    public static String ACTION_WIDGET_CLICKED = "your.packagename.ACTION_WIDGET_CLICKED";
    public static String MY_WIDGET_UPDATE = "your.packagename.MY_WIDGET_UPDATE";
    

    onReceive method:

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        super.onReceive(context, intent);
        choice = false;
        // ////Toast.makeText(context, intent.getAction(),
        // ////Toast.LENGTH_LONG).show();
        // choice=false;
    
        Bundle extras = intent.getExtras();
    
        if (MY_WIDGET_UPDATE.equals(intent.getAction())) {
            choice = false;
    
            AppWidgetManager appWidgetManager = AppWidgetManager
                    .getInstance(context);
            ComponentName thisAppWidget = new ComponentName(
                    context.getPackageName(), ControlloWidget.class.getName());
            int[] appWidgetIds = appWidgetManager
                    .getAppWidgetIds(thisAppWidget);
    
            onUpdate(context, appWidgetManager, appWidgetIds);
            // ////Toast.makeText(context, "AUTOUPDATE",
            // ////Toast.LENGTH_LONG).show();
        } else
    
        if (ACTION_WIDGET_CLICKED.equals(intent.getAction())) {
            // choice =true;
            AppWidgetManager appWidgetManager = AppWidgetManager
                    .getInstance(context);
            ComponentName thisAppWidget = new ComponentName(
                    context.getPackageName(), ControlloWidget.class.getName());
            int[] appWidgetIds = appWidgetManager
                    .getAppWidgetIds(thisAppWidget);
            int appWidgetId = intent.getIntExtra(
                    AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
            // ////////
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.widget);
            remoteViews.setTextViewText(R.id.btnEsegui,
                    Configurazione.getName(context, "nome", appWidgetId));
    
            // ACTION CODE HERE
            appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
            Log.d("LOG_Esecuzione",
                    "Log Esecuzione, Widget n." + String.valueOf(appWidgetId));
    
        }
    
    }
    

    Then onUpdate and updateAppWidget Method:

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        // TODO Auto-generated method stub
        // super.onUpdate(context, appWidgetManager, appWidgetIds);
        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            int appWidgetId = appWidgetIds[i];
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }
    
    public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId){
        //TestOnClick
    
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
        Intent myIntent = new Intent(context, ControlloWidget.class);
        myIntent.setAction(ACTION_WIDGET_CLICKED);
        myIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,
                myIntent, 0);
        remoteViews.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
        remoteViews.setTextViewText(R.id.btnEsegui,Configurazione.getName(context, "nome", appWidgetId));
        //On Update Code, Requested Action when onUpdate is called (for all widget), it also refresh pending intent                     
    
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
        Log.d("LOG_UPDATE", "Log Update, Widget n."+String.valueOf(appWidgetId));
                                    }
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }
    

    For separate instances is necessary:

    On intentcreation:(on updateAppWidget)

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
    Intent myIntent = new Intent(context, ControlloWidget.class);
    myIntent.setAction(ACTION_WIDGET_CLICKED);
                //The line below is the appWidgetId Specification
    myIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,
            myIntent, 0);
    remoteViews.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
    

    On receiving broadcast: (on onReceive)

    if (ACTION_WIDGET_CLICKED.equals(intent.getAction())){
        //Commented are not used on that example
        //AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        //ComponentName thisAppWidget = new ComponentName(context.getPackageName(), ControlloWidget.class.getName());
        //int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
        int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    

    now we could call any routine everywhere passing appWidgetId and Context to function... Example:

    Action.SomeAction(context,appWidgetId);
    

    For UPDATE TIMER, is also possible (without using preferences): Like the other intent could use putExtra then on broadcast: retrieve the int on broadcast receive

    int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    

    BUT now we don't call onUpdate method but directly updateAppWidget with that alternative solution every widget has his own time refresh (maybe configurable) I've preferred to have only one timer process active at same time and get all the widget updated at first instance widget update time

    0 讨论(0)
提交回复
热议问题