解决:Android部件 - 点击动作,更新在30分钟内,不同实例 [英] SOLVED: Android Widget - Click for action, update under 30 minutes, separate instances

查看:114
本文介绍了解决:Android部件 - 点击动作,更新在30分钟内,不同实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

解决方案是在我的答案

我试图创建,在点击号召配置活动的程序的部件,在更新呼吁配置活动的另外一个程序,更新必须在30分钟,所有创建必须单独工作istance(在OnUpdate中和的onClick)。

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 minutes and all the istance created must work separately (in onUpdate and in onClick).

下面的code:单击不起作用(无法看到吐司留言等功能) 更新工作正常的第一istance但与多个部件istance它的作品不好: 如果我创建2 istances到10秒之间(和更新设置为20秒)都将更新每隔10秒......

The code below: Click doesn't work (Can't See Toast Message and other function) Update works fine for first istance but with multiple widget istance it works bad: If i create 2 istances between 10 seconds (and refresh is set to 20 seconds) all will update every 10 seconds...

这是我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="it.fraschi.controllogiardinowg"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
       android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="it.fraschi.controllogiardinowg.Configurazione"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
            </intent-filter>
        </activity>
        <receiver android:name="it.fraschi.controllogiardinowg.ControlloWidget" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <intent-filter> 
                <action android:name="it.fraschi.controllogiardinowg.ControlloWidget.ACTION_WIDGET_CLICKED"/>
            </intent-filter>
            <intent-filter>
                    <action android:name="it.fraschi.controllogiardinowg.ControlloWidget.MY_OWN_WIDGET_UPDATE" />
                </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider" />
        </receiver>
    </application>
</manifest>

这是我的配置:

package it.fraschi.controllogiardinowg;




import java.util.Calendar;
import java.util.Random;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RemoteViews;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class Configurazione extends Activity {

private static final String PREFS_NAME  = "it.fraschi.android.ControlloGiardinoWG";

    public static final String NOME  = "nome_";
    private static long millis = 60000;


    private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    private int selectedTextColor;
    private int selectedBackgroundColor;

     public Configurazione() {
            super();
        }

     @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);

            // Set the result to CANCELED.  This will cause the widget host to cancel
            // out of the widget placement if they press the back button.
            setResult(RESULT_CANCELED);

            // Set the view layout resource to use.
            setContentView(R.layout.activity_configurazione);

            // Find the widget id from the intent. 
            Intent intent = getIntent();
            Bundle extras = intent.getExtras();
            if (extras != null) {
                mAppWidgetId = extras.getInt(
                        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
            }

            // If they gave us an intent without the widget id, just bail.
            if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
                finish();
            }



            //final Spinner backgroundColorSelector = (Spinner)findViewById(R.id.backgroundColor);
            final Button    saveButton = (Button)findViewById(R.id.btnSalva);
            final Button    cancelButton = (Button)findViewById(R.id.btnCancel);
            final EditText  editNome = (EditText)findViewById(R.id.editNome);
            /*textColorSelector.setOnItemSelectedListener(new OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                    selectedTextColor = Integer.parseInt(getResources().getStringArray(R.array.textColorsValues)[textColorSelector.getSelectedItemPosition()]);
                }

                @Override
                public void onNothingSelected(AdapterView<?> parentView) {}

            });*/



            saveButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    final Context context = Configurazione.this;

                    //prepare Alarm Service to trigger Widget
                       Intent intent = new Intent(ControlloWidget.MY_WIDGET_UPDATE);
                       PendingIntent pendingIntent = PendingIntent.getBroadcast(Configurazione.this, mAppWidgetId, intent, 0);
                       AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
                       Calendar calendar = Calendar.getInstance();
                       calendar.setTimeInMillis(System.currentTimeMillis());
                       calendar.add(Calendar.SECOND, 30);
                       alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), millis, pendingIntent);
                       //ControlloWidget.SaveAlarmManager(alarmManager, pendingIntent);
                    ///


                    SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
                    prefs.putString(NOME + mAppWidgetId, editNome.getText().toString());

                    prefs.commit();

                 // Push widget update to surface with newly set prefix
                    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                    ControlloWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);

                    // Make sure we pass back the original appWidgetId
                    Intent resultValue = new Intent();
                    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
                    setResult(RESULT_OK, resultValue);
                    finish();
                }
            });

            cancelButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    finish();
                }
            });

     }
    /*@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.configurazione, menu);
        return true;
    }*/
     static String getName(Context context, String prefKey ,int appWidgetId) {
            SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
            String valuename = prefs.getString(prefKey + appWidgetId, "Non Trovato");

            return valuename;
        }
     static String getColor(Context context, String prefKey, int appWidgetId){
            ///Test
            SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
            String nome = prefs.getString(prefKey + appWidgetId, "Non Trovato");
            ///
            int number = (new Random().nextInt(100));
            String color = "DaConf"+Integer.toString(number)+nome;
            Toast.makeText(context, "ESEGUITO", Toast.LENGTH_LONG).show();
            return color;
     }


}

这是我的小工具:

        import java.text.DateFormat;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        import java.util.Random;

        import android.app.AlarmManager;
        import android.app.PendingIntent;
        import android.appwidget.AppWidgetManager;
        import android.appwidget.AppWidgetProvider;
        import android.content.ComponentName;
        import android.content.Context;
        import android.content.Intent;
        import android.os.Bundle;
        import android.os.Environment;
        import android.os.StatFs;

        import android.widget.RemoteViews;
        import android.widget.Toast;

        public class ControlloWidget extends AppWidgetProvider {
            public static String ACTION_WIDGET_CLICKED = "it.fraschi.controllogiardinowg.ESEGUI";
            public static String MY_WIDGET_UPDATE = "it.fraschi.controllogiardinowg.ControlloWidget.MY_OWN_WIDGET_UPDATE";
            static String strWidgetText = "";
            public static Boolean choice = false;


                @Override

                public void onReceive(Context context, Intent intent) {
                    // TODO Auto-generated method stub
                    //super.onReceive(context, intent);
                    String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date()); 
                    if(MY_WIDGET_UPDATE.equals(intent.getAction())){
                        Bundle extras = intent.getExtras();
                           if(extras!=null) {
                            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                            ComponentName thisAppWidget = new ComponentName(context.getPackageName(),
    ControlloWidget.class.getName());
                            int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
                            choice=false;
                            onUpdate(context, appWidgetManager, appWidgetIds);
                           }
                        Toast.makeText(context, "WIDGET UPDATE" +currentDateTimeString, Toast.LENGTH_LONG).show();
                    }
                    //Test Click
                    if(ACTION_WIDGET_CLICKED.equals(intent.getAction())){
                        Bundle extras = intent.getExtras();
                           if(extras!=null) {
                            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                            ComponentName thisAppWidget = new ComponentName(context.getPackageName(),
    ControlloWidget.class.getName());
                            int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
                            choice=true;
                            onUpdate(context, appWidgetManager, appWidgetIds);
                           }
                        Toast.makeText(context, "WIDGET PREMUTO", Toast.LENGTH_LONG).show();
                    }
                    //TestClick
                }

                @Override
                public void onEnabled(Context context) {
                    // TODO Auto-generated method stub
                    //super.onEnabled(context);

                    Toast.makeText(context, "onEnabled()", Toast.LENGTH_LONG).show();
                }

                @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];
                        // Create an Intent to launch ExampleActivity
                        Intent intent = new Intent(context, ControlloWidget.class);
                        intent.setAction(ACTION_WIDGET_CLICKED);
                        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
                        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetId, intent,
                                PendingIntent.FLAG_UPDATE_CURRENT);

                        // Get the layout for the App Widget and attach an on-click listener
                        // to the button
                        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
                        views.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
                        // Tell the AppWidgetManager to perform an update on the current app widget
                        appWidgetManager.updateAppWidget(appWidgetId, views);
                        //updateAppWidget(context, appWidgetManager, appWidgetId);

                        //Toast.makeText(context, "onUpdate(): " + String.valueOf(i) + " : " +  String.valueOf(appWidgetId), Toast.LENGTH_LONG).show();
                    }
                     RemoteViews remoteWidget = new RemoteViews(context.getPackageName(),R.layout.widget);


                }



                public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId){
                        //TestOnClick
                       RemoteViews remoteWidget = new RemoteViews(context.getPackageName(),R.layout.widget);
                       ///
                       Intent esegui = new Intent(context, ControlloWidget.class);
                       esegui.setAction(ACTION_WIDGET_CLICKED);
                       //Intent esegui = new Intent(ControlloWidget.ACTION_WIDGET_CLICKED);
                       PendingIntent pendingEsegui = PendingIntent.getBroadcast(context, appWidgetId, esegui, 0);
                       remoteWidget.setOnClickPendingIntent(R.id.btnEsegui, pendingEsegui);
                    //

                        //
                        if (choice){
                            RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
                            updateViews.setTextViewText(R.id.btnEsegui, "[" + String.valueOf(appWidgetId) + "]" + strWidgetText +
    Configurazione.getColor(context, Configurazione.NOME, appWidgetId));
                            appWidgetManager.updateAppWidget(appWidgetId, updateViews);

                            Toast.makeText(context, "onClick(): " + String.valueOf(appWidgetId) + "\n" + strWidgetText,
    Toast.LENGTH_LONG).show();

                        }else{
                                int number = (new Random().nextInt(100));
                                strWidgetText = Integer.toString(number);

                                RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
                                updateViews.setTextViewText(R.id.btnEsegui, "[" + String.valueOf(appWidgetId) + "]" + strWidgetText +
    Configurazione.getName(context, Configurazione.NOME, appWidgetId));
                                appWidgetManager.updateAppWidget(appWidgetId, updateViews);

                                Toast.makeText(context, "updateAppWidget(): " + String.valueOf(appWidgetId) + "\n" + strWidgetText,
    Toast.LENGTH_LONG).show();
                            }
                }
                static AlarmManager myAlarmManager;
                static PendingIntent myPendingIntent;


                @Override
                public void onDeleted(Context context, int[] appWidgetIds) {
                    // TODO Auto-generated method stub
                    //super.onDeleted(context, appWidgetIds);
                    myAlarmManager.cancel(myPendingIntent);
                    Toast.makeText(context, "onDeleted()", Toast.LENGTH_LONG).show();
                }
                static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent){
                    myAlarmManager = tAlarmManager;
                    myPendingIntent = tPendingIntent;
                }
        }

*

推荐答案

有关在30分钟时间,多istances我已经决定只用一个定时器对所有istances。

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

下面配置类的code的onCreate:

Below the code onCreate of Configuration Class:

private static long millis = 20000;

SharedPreferences read = context.getSharedPreferences(PREFS_NAME, 0);
String firstistance = read.getString("FirstIstance", "KO");
if (firstistance.equals("KO")) {
    SharedPreferences.Editor write = context.getSharedPreferences(
            PREFS_NAME, 0).edit();
    write.putString("FirstIstance", "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);
}

恢复的过程onDisabled WidgetClass的:

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("FirstIstance", "KO" ); 
    write.commit();
    myAlarmManager.cancel(myPendingIntent);
}
static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent){
    myAlarmManager = tAlarmManager;
    myPendingIntent = tPendingIntent;
}

现在,设置按钮动作和我自己的更新: 类dichiaration:

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

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

的onReceive方法:

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

    }

}

随后的onupdate和updateAppWidget方法:

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);
}

有关独立istances是必要的:

For separate istances is necessary:

在intentcreation:(上updateAppWidget)

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

在接收广播:(上的onReceive)

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

现在,我们可以调用任何常规到处传递appWidgetId和上下文的功能... 例如:

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

Action.SomeAction(context,appWidgetId);

有关更新计时器,也有可能(不使用preferences): 像其他意图 可以使用 putExtra 然后广播: 检索广播INT接收

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

但现在我们不叫的onupdate 的方法,而是直接 updateAppWidget 与替代解决方案的每个部件都有自己的时间刷新(也许配置) 我已经pferred $ P $只生一个定时器过程中活跃的同时,并让所有的小工具在第一istance窗口更新时间更新

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 istance widget update time

这篇关于解决:Android部件 - 点击动作,更新在30分钟内,不同实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆