AndroidDev
AndroidDev

Reputation: 4559

Widget Data Lost on run of heavy application

I have created a widget for my app. All works fine and all the data shown in the widget is displaying correctly. But sometimes what happen whenever I run some other application like a camera and start shooting video for a couple of seconds and stop the video and close the camera then suddenly all the data that are displaying in my widget is lost and it shows nothing in the widget. I don't know whether the problem arises before when I run my app in Android 2.3.3 but as I updated my phone to Android 4.0 this problem shows.

The lost data appear again as the widget updated according to the time interval set by me. So my question is why this data loss occurs, is something I have to do in my code. Please help me to solve this out.

The code I have used

Widget_app_provider.xml file

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_layout"
    android:minHeight="56dp"
    android:minWidth="56dp"
    android:updatePeriodMillis="2100000" />

WidgetLayout.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/appwidget_bg_clickable" >

    <ImageView
        android:id="@+id/backgroundImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:contentDescription="@string/tracking_status_faq_imageview_text"
        android:scaleType="fitXY" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center_horizontal|center_vertical" >

        <TextView
            android:id="@+id/txt_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#5f5f5f"
            android:textSize="14dp" >
        </TextView>
    </LinearLayout>

</RelativeLayout>

Widget.java file

public class Widget extends AppWidgetProvider implements Utilities
    {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    {      
        // Read data from register before  updating the widget
        CycleManager.getSingletonObject().readHistoryDateFromFile(context);
        CycleManager.getSingletonObject().ComputeAverages();
        
        // To prevent any ANR timeouts, we perform the update in a service
        context.startService(new Intent(context, UpdateService.class));
    }

    public static class UpdateService extends Service 
    {
        @Override
        public void onStart(Intent intent, int startId) 
        {
            // Build the widget update for today
            RemoteViews updateViews = getValueFromCycleManager(this);

            // Push update for this widget to the home screen
            ComponentName thisWidget = new ComponentName(this, Widget.class);
            AppWidgetManager manager = AppWidgetManager.getInstance(this);
            manager.updateAppWidget(thisWidget, updateViews);
        }

        @Override
        public IBinder onBind(Intent arg0){
            // TODO Auto-generated method stub
            return null;
        }
        public RemoteViews getValueFromCycleManager(Context context) 
        {
            RemoteViews remoteViews = null;
            remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
                        
            Date currentDate = calInstance.getTime();
            
            // set No of days remaining for next cycle start to the widgets 
            Date dtStart = CycleManager.getSingletonObject().getStartDate();
            int iAvgCycleLength = CycleManager.getSingletonObject().getAvgCycleTime();
            
            calInstance.setTime(dtStart);
            calInstance.add(Calendar.DATE, iAvgCycleLength);            
            Date dtNextCycleDate = calInstance.getTime();   
            
            Long noOfDaysLeft = dtNextCycleDate.getTime()- currentDate.getTime();
            noOfDaysLeft = ((noOfDaysLeft / (1000 * 60 * 60)) + 1) / 24;
            
            remoteViews.setTextViewText(R.id.txt_date, Long.toString(noOfDaysLeft));        
        }
    }
}

Upvotes: 4

Views: 668

Answers (1)

zapl
zapl

Reputation: 63955

Try implementing an IntentService which should handle being killed better. You need to do the work in onHandleIntent which is called with the intent you specify in context.startService(new Intent(context, UpdateService.class));.

public static class UpdateService extends IntentService 
{

    public UpdateService() 
    {
        super("UpdateService");
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {
        // Build the widget update for today
        RemoteViews updateViews = getValueFromCycleManager(this);

        // Push update for this widget to the home screen
        ComponentName thisWidget = new ComponentName(this, Widget.class);
        AppWidgetManager manager = AppWidgetManager.getInstance(this);
        manager.updateAppWidget(thisWidget, updateViews);
    }

    public RemoteViews getValueFromCycleManager(Context context) 
    {
        RemoteViews remoteViews = null;
        remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

        Date currentDate = calInstance.getTime();

        // set No of days remaining for next cycle start to the widgets 
        Date dtStart = CycleManager.getSingletonObject().getStartDate();
        int iAvgCycleLength = CycleManager.getSingletonObject().getAvgCycleTime();

        calInstance.setTime(dtStart);
        calInstance.add(Calendar.DATE, iAvgCycleLength);            
        Date dtNextCycleDate = calInstance.getTime();   

        Long noOfDaysLeft = dtNextCycleDate.getTime()- currentDate.getTime();
        noOfDaysLeft = ((noOfDaysLeft / (1000 * 60 * 60)) + 1) / 24;

        remoteViews.setTextViewText(R.id.txt_date, Long.toString(noOfDaysLeft));        
    }
}

Upvotes: 1

Related Questions