Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update issue of an app widget using collection

I have created an app widget using collection for my app, The widget shows date and list of items on that particular date. Everything works fine and the widget is updating as required, but sometimes what happens while changing the date in the widget by clicking next and previous button, the list is not refreshed means the items are not updated on that particular date. This behavior is random and its occur sometimes only. So why this happen, anything wrong in my code.

Code that I have used:

WidgetProvider.class

public class WidgetProvider extends AppWidgetProvider 
{   
    private ThemeManager    m_ThemeManagerObject;

    private static String   WIDGET_NEXT_BUTTON = "in.test.widgetApp.WIDGET_NEXT_BUTTON";

    private static String   WIDGET_PREV_BUTTON = "in.test.widgetApp.WIDGET_PREV_BUTTON";    

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    {               
        super.onUpdate(context, appWidgetManager, appWidgetIds);

        // Set Date to current Date
        NoteManager.getSingletonObject().setWidgetToCurrentDate();

        // Code to update the widget by current date 
        updateAppWidget(context, AppWidgetManager.getInstance(context), appWidgetIds);
    }   
    
    @Override
    public void onReceive(Context context, Intent intent) 
    {           
        super.onReceive(context, intent);

        int numOfDays = 1;
        
        ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
        
        if (intent.getAction().equals(WIDGET_NEXT_BUTTON)) 
        {
            // Increase no of days by one
            // Update the widget by new date 
            NoteManager.getSingletonObject().setWidgetDate(numOfDays);          
            updateAppWidget(context, AppWidgetManager.getInstance(context), appWidgetIds);
        }   
        else if (intent.getAction().equals(WIDGET_PREV_BUTTON)) 
        {
            // Decrease no of days by one
            // Update the widget by new date 
            NoteManager.getSingletonObject().setWidgetDate(-numOfDays);         
            updateAppWidget(context, AppWidgetManager.getInstance(context), appWidgetIds);
        }                   
    }

        public void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
    // Get the folder path of all-page-view
    ContextWrapper cw = new ContextWrapper(context.getApplicationContext());
    File customDirectoryPath = cw.getDir(Utilities.CUSTOM_DIRECTORY_NAME_PREFIX, Context.MODE_PRIVATE);
    File allPageDirectoryPath = new File(customDirectoryPath.getPath() + "/" + Utilities.All_PAGE_DIRECTORY_NAME_PREFIX); 

    if (!(allPageDirectoryPath.exists()))
        allPageDirectoryPath.mkdirs();

    // Create an singleton object of ThemeManager class
    m_ThemeManagerObject = ThemeManager.getSingletonObject();
    m_ThemeManagerObject.readTheme(allPageDirectoryPath.getPath());

    // Create an instance of SimpleDateFormat class
    SimpleDateFormat dateFormater = new SimpleDateFormat("dd-MMM, EEE", Locale.US);

    /* loop through all widget instances */
    for (int widgetId : appWidgetIds) 
    { 
        // Create an instance of remote view class
        RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);       
        Intent svcIntent = new Intent(context, WidgetService.class);
        svcIntent.setData(Uri.fromParts("content", String.valueOf(widgetId), null));        
        remoteView.setRemoteAdapter(R.id.widget_list, svcIntent);   

        // Show day, month and week day inside the widget
        remoteView.setTextViewText(R.id.txt_date, dateFormater.format(NoteManager.getSingletonObject().getWidgetDate().getTime()));

        // If the list is empty. Show empty widget with juswrite-icon & empty text to the user          
        remoteView.setEmptyView(R.id.widget_list, R.id.widget_empty_text);              

        // On click of next button
        Intent nextButtonIntent = new Intent(WIDGET_NEXT_BUTTON);
        /* use widgetId as second parameter - it helped me to better address particular widget instance */
        PendingIntent nextButtonPendingIntent = PendingIntent.getBroadcast(context, widgetId, nextButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.btn_next_month, nextButtonPendingIntent);
        remoteView.setInt(R.id.btn_next_month, "setBackgroundResource", m_ThemeManagerObject.getNextButtonBgImage());

        // On click of previous button
        Intent prevButtonIntent = new Intent(WIDGET_PREV_BUTTON);
        /* use widgetId as second parameter - same as above */
        PendingIntent prevButtonPendingIntent = PendingIntent.getBroadcast(context, widgetId, prevButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.btn_prev_month, prevButtonPendingIntent);
        remoteView.setInt(R.id.btn_prev_month, "setBackgroundResource", m_ThemeManagerObject.getPrevButtonBgImage());

        // Open application on click of app widget
        Intent clickIntent = new Intent(context, AllPageViewActivity.class);
        PendingIntent clickPI = PendingIntent.getActivity(context, 0,clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.widget_empty_text, clickPI);
        remoteView.setOnClickPendingIntent(R.id.txt_date, clickPI);
        
        /* update one widget instance at a time*/
        appWidgetManager.updateAppWidget(widgetId, remoteView);
    }
}
}

WidgetService.class

public class WidgetService extends RemoteViewsService 
{
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) 
    {
        return(new WidgetDisplay(this.getApplicationContext(), intent));
    }
}

WidgetDisplay.class

public class WidgetDisplay implements RemoteViewsService.RemoteViewsFactory
{
    private File m_CustomDirectoryPath, m_AllPageDirectoryPath;
    
    private NoteManager m_NoteManagerObject;
    
    private ThemeManager m_ThemeManagerObject;
    
    private ArrayList<String>   m_AlarmItemNameArrayList;
    
    private ArrayList<Integer>  m_ItemIndexArray;
    
    private Context ctxt=null;
    
    int appWidgetId;
    
    Bitmap canvasBackground;

    public WidgetDisplay(Context ctxt, Intent intent) 
    {
        this.ctxt=ctxt;
        
        appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
        
        setImageInView(this.ctxt);

    }
    
    private void setImageInView(Context context) 
    {
        ContextWrapper cw = new ContextWrapper(ctxt.getApplicationContext());
        m_CustomDirectoryPath = cw.getDir(Utilities.CUSTOM_DIRECTORY_NAME_PREFIX, Context.MODE_PRIVATE);
        m_AllPageDirectoryPath = new File(m_CustomDirectoryPath.getPath() + "/" + Utilities.All_PAGE_DIRECTORY_NAME_PREFIX); 

        m_NoteManagerObject = NoteManager.getSingletonObject();
        m_ThemeManagerObject = ThemeManager.getSingletonObject();
        
        m_NoteManagerObject.readSettings(m_AllPageDirectoryPath.getPath());
        m_NoteManagerObject.readAllPageChangesFromFile(m_AllPageDirectoryPath.getPath());
        m_NoteManagerObject.readAlarmFromFile(m_AllPageDirectoryPath.getPath());
        m_ThemeManagerObject.readTheme(m_AllPageDirectoryPath.getPath());

        m_AlarmItemNameArrayList = new ArrayList<String>(m_NoteManagerObject.getAlarmCount());
        m_ItemIndexArray = new ArrayList<Integer>(m_NoteManagerObject.getAlarmCount());

        SimpleDateFormat sdFormatter = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);      
        String selectedDate = sdFormatter.format(m_NoteManagerObject.getWidgetDate());
        
        for(int i=0; i<m_NoteManagerObject.getAlarmCount(); i++)
        {
            String ArrayDate = sdFormatter.format(m_NoteManagerObject.getAlarmTime(i));         
            if(selectedDate.equals(ArrayDate))
            {
                File noteDirectoryPath = new File(m_CustomDirectoryPath.getPath() + "/" + m_NoteManagerObject.getAlarmFolder(i));
                m_AlarmItemNameArrayList.add(noteDirectoryPath.getPath() + "/" + m_NoteManagerObject.getAlarmItem(i));

                m_ItemIndexArray.add(i);
            }
        }
    }

    @Override
    public int getCount() 
    {
        return(m_AlarmItemNameArrayList.size());
    }
    
    @Override
    public RemoteViews getViewAt(int position) 
    {       
        new ImageLoaderTask(position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

        // Set combine image to the image view using remote view instance
        RemoteViews remoteView = new RemoteViews(ctxt.getPackageName(), R.layout.widget_list_item);
        remoteView.setImageViewBitmap(R.id.image_view, canvasBackground);
        
        // Set time text view using remote view instance
        SimpleDateFormat timeFormater;
        
        if(m_NoteManagerObject.get24HourFormat())
        {
            timeFormater = new SimpleDateFormat("HH:mm", Locale.US);
        }
        else
        {
            timeFormater = new SimpleDateFormat("hh:mm a", Locale.US );
        }
        
        // Show time on the top of each image view
        String time = timeFormater.format(m_NoteManagerObject.getAlarmTime(m_ItemIndexArray.get(position)));            
        remoteView.setTextViewText(R.id.text_alarm_time,  time);        
                
        Intent clickIntent = new Intent(ctxt, AllPageViewActivity.class);
        PendingIntent clickPI=PendingIntent.getActivity(ctxt, 0,clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.image_view, clickPI);

        return(remoteView);
    }

    class ImageLoaderTask extends AsyncTask<URL, Integer, Long>
    {
        private int position;
        
        ImageLoaderTask(int position)
        {
            this.position = position;
        }

        @Override
        protected void onPreExecute()
        {
            // Get foreground and background image
            Bitmap bitmapImage = BitmapFactory.decodeFile(m_AlarmItemNameArrayList.get(position)).copy(Bitmap.Config.ARGB_8888, true);
            canvasBackground = BitmapFactory.decodeResource(ctxt.getResources(), m_ThemeManagerObject.getWidgetListItemBgImage(m_ItemIndexArray.get(position), bitmapImage)).copy(Bitmap.Config.ARGB_8888, true);
            
            // Scaled foreground image and combine with the background image
            bitmapImage = Bitmap.createScaledBitmap(bitmapImage, 380, bitmapImage.getHeight() / 2, true);               
            Canvas comboImage = new Canvas(canvasBackground);
            comboImage.drawBitmap(bitmapImage, 0f, 0f, null);
        }

        @Override
        protected Long doInBackground(URL... urls)
        {
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... progress)
        {

        }

        @Override
        protected void onPostExecute(Long result)
        {

        }
    }
    
    @Override
    public void onCreate(){ 
    }

    @Override
    public void onDestroy(){
    }
    
    @Override
    public RemoteViews getLoadingView()
    {
        return(null);
    }

    @Override
    public int getViewTypeCount(){
        return(1);
    }

    @Override
    public long getItemId(int position){
        return(position);
    }

    @Override
    public boolean hasStableIds(){
        return(true);
    }

    @Override
    public void onDataSetChanged(){
    }
}
like image 324
AndroidDev Avatar asked Apr 05 '13 08:04

AndroidDev


People also ask

How do you update an app widget?

Full update: Call AppWidgetManager. updateAppWidget(int, android. widget. RemoteViews) to fully update the widget.

What is a widget collection?

Collection widgets specialize in displaying many elements of the same type, such as a collection of pictures from a gallery app, a collection of articles from a news app or a collection of messages from a communication app.

What are application widgets?

App widgets are miniature application views that can be embedded in other applications (such as the home screen) and receive periodic updates. These views are referred to as widgets in the user interface, and you can publish one with an app widget provider (or widget provider).


1 Answers

WidgetProvider.class

public class WidgetProvider extends AppWidgetProvider 
{   
    private NoteManager         m_NoteManagerObject;

    private ThemeManager        m_ThemeManagerObject;

    private SimpleDateFormat    m_DateFormater;

    private static String       WIDGET_NEXT_BUTTON = "in.test.widgetApp.WIDGET_NEXT_BUTTON";

    private static String       WIDGET_PREV_BUTTON = "in.test.widgetApp.WIDGET_PREV_BUTTON";    

    public WidgetProvider()
    {
        // Create an singleton object of NoteManager class
        m_NoteManagerObject = NoteManager.getSingletonObject();
        // Create an singleton object of ThemeManager class
        m_ThemeManagerObject = ThemeManager.getSingletonObject();
        // Create an instance of SimpleDateFormat class
        m_DateFormater = new SimpleDateFormat("dd-MMM, EEE", Locale.US);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    {               
        super.onUpdate(context, appWidgetManager, appWidgetIds);

        // Set Date to current Date
        m_NoteManagerObject.setWidgetToCurrentDate();

        // Get the folder path of all-page-view
        ContextWrapper cw = new ContextWrapper(context.getApplicationContext());
        File customDirectoryPath = cw.getDir(Utilities.CUSTOM_DIRECTORY_NAME_PREFIX, Context.MODE_PRIVATE);
        File allPageDirectoryPath = new File(customDirectoryPath.getPath() + "/" + Utilities.All_PAGE_DIRECTORY_NAME_PREFIX); 

        if (!(allPageDirectoryPath.exists()))
            allPageDirectoryPath.mkdirs();

        m_ThemeManagerObject.readTheme(allPageDirectoryPath.getPath());     

        // Set up the intent that starts the WidgetService, which will
        // provide the views for this collection.   
        // When intents are compared, the extras are ignored, so we need to embed the extras
        // into the data so that the extras will not be ignored.
        Intent intent  = new Intent(context, WidgetService.class);
        intent.setData(Uri.fromParts("content", String.valueOf(appWidgetIds), null));

        // Instantiate the RemoteViews object for the App Widget layout.
        // Set up the RemoteViews object to use a RemoteViews adapter. 
        // This adapter connects to a RemoteViewsService  through the specified intent.
        // This is how you populate the data.
        RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);           
        remoteView.setRemoteAdapter(R.id.widget_list, intent);  

        // Show day, month and week day inside the widget
        remoteView.setTextViewText(R.id.txt_date, m_DateFormater.format(m_NoteManagerObject.getWidgetDate().getTime()));

        // The empty view is displayed when the collection has no items.        
        remoteView.setEmptyView(R.id.widget_list, R.id.widget_empty_text);              

        // On click of next button
        // This section makes it possible for items to have individualized behavior.
        // Set the action for the intent.
        // When the user touches a particular view, it will have the effect of
        // broadcasting ACTION.
        Intent nextButtonIntent = new Intent(context, WidgetProvider.class);            
        nextButtonIntent.setAction(WIDGET_NEXT_BUTTON);
        PendingIntent nextButtonPendingIntent = PendingIntent.getBroadcast(context, 0, nextButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.btn_next_month, nextButtonPendingIntent);
        remoteView.setInt(R.id.btn_next_month, "setBackgroundResource", m_ThemeManagerObject.getNextButtonBgImage());

        // On click of previous button
        // This section makes it possible for items to have individualized behavior.
        // Set the action for the intent.
        // When the user touches a particular view, it will have the effect of
        // broadcasting ACTION.
        Intent prevButtonIntent = new Intent(context, WidgetProvider.class);
        prevButtonIntent.setAction(WIDGET_PREV_BUTTON);
        PendingIntent prevButtonPendingIntent = PendingIntent.getBroadcast(context, 0, prevButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.btn_prev_month, prevButtonPendingIntent);
        remoteView.setInt(R.id.btn_prev_month, "setBackgroundResource", m_ThemeManagerObject.getPrevButtonBgImage());

        // Open application on click of app widget
        Intent clickIntent = new Intent(context, AllPageViewActivity.class);
        PendingIntent clickPI = PendingIntent.getActivity(context, 0,clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setOnClickPendingIntent(R.id.widget_empty_text, clickPI);
        remoteView.setOnClickPendingIntent(R.id.txt_date, clickPI); 

        appWidgetManager.updateAppWidget(appWidgetIds, remoteView); 
    }   

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

        int numOfDays = 1;

        ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

        if (intent.getAction().equals(WIDGET_NEXT_BUTTON)) 
        {
            // Increase no of days by one
            m_NoteManagerObject.setWidgetDate(numOfDays);

            // Update remote view
            RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);               
            remoteView.setTextViewText(R.id.txt_date, m_DateFormater.format(m_NoteManagerObject.getWidgetDate().getTime()));
            appWidgetManager.updateAppWidget(appWidgetIds, remoteView); 

            // Update list content of the widget
           // This will call onDataSetChanged() method of WidgetDisplay class
            appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
        }   
        else if (intent.getAction().equals(WIDGET_PREV_BUTTON)) 
        {
            // Decrease no of days by one
            m_NoteManagerObject.setWidgetDate(-numOfDays);  

            // Update remote view
            RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_list);               
            remoteView.setTextViewText(R.id.txt_date, m_DateFormater.format(m_NoteManagerObject.getWidgetDate().getTime()));
            appWidgetManager.updateAppWidget(appWidgetIds, remoteView); 

            // Update list content of the widget
              // This will call onDataSetChanged() method of WidgetDisplay class
            appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
        }                   
    }
}
like image 58
AndroidDev Avatar answered Nov 14 '22 05:11

AndroidDev