Android Open Source - droid-talks Conference Widget






From Project

Back to project page droid-talks.

License

The source code is released under:

GNU General Public License

If you think the Android project droid-talks listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.gareth.assignment.conferencewidget;
/*from   w w  w. j  a  va 2s .c o m*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

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.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;


public class ConferenceWidget extends AppWidgetProvider {

    public static final String NEXT_BUTTON = "com.gareth.assignment.conferencewidget.NEXT_BUTTON";
    public static final String PREVIOUS_BUTTON = "com.gareth.assignment.conferencewidget.PREVIOUS_BUTTON";

  private static final String LOG_TAG = "ConferenceWidget";
  private static final String TITLE_PREFIX = "Day: ";
  private static final String FILE_NAME = "day_id_file";
  // Assumes first conference day will always be ID 1
  private static final int DEFAULT_DAY = 1;
  
  private static DBAccess db;
  private static long[] dayIds;
  private static long currentDayId;
  private File dayIdFile;
  
  
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
      int[] appWidgetIds) {
    
    Log.i(LOG_TAG, "In onUpdate. currentDayId: " + currentDayId);
    
    db = new DBAccess(context.getContentResolver());
    dayIds = db.getListOfDayIds();
    
    dayIdFile = new File(context.getFilesDir(), FILE_NAME);
    boolean fileEmpty = readData();
    if (fileEmpty)
      currentDayId = dayIds[0];
    
    Log.i(LOG_TAG, "onEnabled currentDayId: " + currentDayId);
    
    // Make sure currentDayId is set to a default, if outside the appropriate range
    if (currentDayId < dayIds[0] || currentDayId > dayIds.length)
      currentDayId = DEFAULT_DAY;
    Log.i(LOG_TAG, "In onUpdate. currentDayId NOW: " + currentDayId);
    
    String currentDay = db.getDayForDayId(currentDayId);
    Log.i(LOG_TAG, "In onUpdate. Days ID 0: " + dayIds[0]);
    
    // Start the network request in a new thread of execution
    new AsyncServerQuery(context, appWidgetIds).execute();
    
    // update each of the app widgets with the remote adapter
      for (int i = 0; i < appWidgetIds.length; ++i) {
          
          // Set up the intent that starts the ConferenceWidgetService, 
        // which provides the views for the collection.
          Intent intent = new Intent(context, ConferenceWidgetService.class);
          intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
          intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
          
          // Instantiate the RemoteViews object for the overall widget layout.
          RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.main);
          
          // Set up the RemoteViews object to use a RemoteViews adapter. 
          rv.setRemoteAdapter(R.id.day_list, intent);
          
          // The empty view is displayed if the collection has no items.
          rv.setEmptyView(R.id.day_list, R.id.empty_view);

          // Set widget title
          rv.setTextViewText(R.id.title_text, TITLE_PREFIX + currentDay + 
              " (" + currentDayId + "/" + dayIds.length + ")");
          
          // Set up pending intents for the two buttons
            Intent nextButtonIntent = new Intent(context, ConferenceWidget.class);
            nextButtonIntent.setAction(ConferenceWidget.NEXT_BUTTON);
            PendingIntent nextButtonPendingIntent = PendingIntent.getBroadcast(context, 0,
                nextButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            rv.setOnClickPendingIntent(R.id.image_button_next, nextButtonPendingIntent);

            Intent prevButtonIntent = new Intent(context, ConferenceWidget.class);
            prevButtonIntent.setAction(ConferenceWidget.PREVIOUS_BUTTON);
            PendingIntent prevButtonPendingIntent = PendingIntent.getBroadcast(context, 0,
                prevButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            rv.setOnClickPendingIntent(R.id.image_button_prev, prevButtonPendingIntent);
          
            // Update each widget to display the current title etc.
          appWidgetManager.updateAppWidget(appWidgetIds[i], rv);   
      }

    super.onUpdate(context, appWidgetManager, appWidgetIds);
  }
  

  @Override
    public void onReceive(Context context, Intent intent) {
    Log.i(LOG_TAG, "In onReceive. Intent action: " + intent.getAction());
        
        if (intent.getAction().equals(NEXT_BUTTON)) {
          // Ensure day wraps around
          if (++currentDayId > dayIds.length)
            currentDayId = dayIds[0];
          
          buttonAction(context);
        }
        else if (intent.getAction().equals(PREVIOUS_BUTTON)) {
          // Ensure day wraps around
          if (--currentDayId < dayIds[0])
            currentDayId = dayIds[dayIds.length - 1];
          
          buttonAction(context);
        }
        Log.i(LOG_TAG, "In onReceive. currentDayId: " + currentDayId);

        super.onReceive(context, intent);
    }
  
  
  @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
    }

  
  /**
   * When a widget is disabled (removed from home screen), write the currentDayId
   * to file so it can be recalled when the widget is re-enabled.
   */
    @Override
    public void onDisabled(Context context) {
      Log.i(LOG_TAG, "In onDisabled");
      
    writeData(context);
        super.onDisabled(context);
    }

    
    @Override
    public void onEnabled(Context context) {
      Log.i(LOG_TAG, "In onEnabled");
      
        super.onEnabled(context);
    }
    
    
    /**
     * Handle button presses in the widget, and notify 
     * the widget that a change has occurred.
     * 
     * @param context
     * @param intent
     */
    private void buttonAction(Context context) {
      
        ComponentName cn = new ComponentName(context, ConferenceWidget.class);
        AppWidgetManager mgr = AppWidgetManager.getInstance(context);
        String day = db.getDayForDayId(currentDayId);
        Log.i(LOG_TAG, day);
        int[] appWidgetIds = mgr.getAppWidgetIds(cn);
        Toast.makeText(context, day, Toast.LENGTH_SHORT).show();
        
        mgr.notifyAppWidgetViewDataChanged(mgr.getAppWidgetIds(cn), R.id.day_list);
        
        // Update each widget title
        for (int i = 0; i < appWidgetIds.length; ++i) {
          RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.main);
            rv.setTextViewText(R.id.title_text, TITLE_PREFIX + day + 
              " (" + currentDayId + "/" + dayIds.length + ")");
            
            mgr.updateAppWidget(appWidgetIds[i], rv);
        }
    }
    
    
    /**
     * Read currentDayId data from file. If the file is empty, currentDayId
     * should be set to the default value in the calling method.
     * 
     * @return boolean fileEmpty
     */
    private boolean readData() {
      Log.i(LOG_TAG, "In readData. dayIdFile length: " + dayIdFile.length());
    boolean fileEmpty = true;
    try {
      if (dayIdFile.length() == 0)
        fileEmpty = true;
      else 
        fileEmpty = false;
      // if the file is not empty, read the contents
      if (fileEmpty) {
        Log.i(LOG_TAG, "file empty");
        Scanner scanLine = new Scanner(dayIdFile);
        currentDayId = scanLine.nextLong();
        scanLine.close();
      }
    } catch (IOException ex) {
      
    }
    if (!fileEmpty)
      Log.i(LOG_TAG, "File currentDayId: " + currentDayId);
    
    return fileEmpty;
  }
    
    
    /**
     * Write currentDayId data to file.
     */
    private void writeData(Context context) {
      try {
      FileOutputStream out = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
      OutputStreamWriter writer = new OutputStreamWriter(out);
      Log.i(LOG_TAG, "onDisabled currentDayId: " + (int)currentDayId);
      writer.write((int)currentDayId);
      writer.close();
    } catch (IOException ex) {
      Log.e(LOG_TAG, "Problem writing file: " + FILE_NAME);
    }
    }
    
    
    //// STATIC METHODS ////
    public static DBAccess getDBAccessInstance() {
      return db;
    }
    
    
    public static long getCurrentDayId() {
      return currentDayId;
    }
    
    
    /**
     * Private inner class to handle network requests
     * 
     * @author Gareth Williams
     */
    private class AsyncServerQuery extends AsyncTask<Void, Void, String> {

      private static final String LOG_TAG = "AsyncServerQuery";
      private Context context;
      private int appWidgetIds[];
      
      
      // Pass in the context and the widget ID array, to enable each 
      // of the displayed widgets to be updated from this class 
      public AsyncServerQuery(Context ctx, int widgetIds[]) {
        context = ctx;
        appWidgetIds = widgetIds;
      }
      
      
      @Override
      protected String doInBackground(Void...voids) {
        String serverMsg = "";
        try {
              HttpClient httpClient = new DefaultHttpClient();
              HttpGet httpGet = new HttpGet("http://users.aber.ac.uk/aos/android/message.php");
              try {
                HttpResponse response = httpClient.execute(httpGet);
                if (response != null) {
                  InputStream input = response.getEntity().getContent();
                  StringBuilder builder = new StringBuilder();
                  BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                  try {
                    while((serverMsg = reader.readLine()) != null)
                      builder.append(serverMsg);
                  } catch (Exception ex) {
                    Log.i(LOG_TAG, "Error reading stream");
                  }
                  serverMsg = builder.toString();
                  Log.i(LOG_TAG, "HTTP GET Response serverMsg: " + serverMsg);
                }
                else {
                  Log.i(LOG_TAG, "Unable to complete request");
                }
              } catch (Exception ex) {
                Log.i(LOG_TAG, "Exception");
                ex.printStackTrace();
              }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        return serverMsg;
      }
      
      
      @Override
      protected void onPostExecute(String currentMessage) {
        Log.i(LOG_TAG, "onPostExecute result: " + currentMessage);
        AppWidgetManager mgr = AppWidgetManager.getInstance(context);
        
        // Update the current message of each widget
            for (int i = 0; i < appWidgetIds.length; ++i) {
              RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.main);
                rv.setTextViewText(R.id.updates_text, currentMessage);
                
                mgr.updateAppWidget(appWidgetIds[i], rv);
            }
      }

    }
  
}




Java Source Code List

com.gareth.assignment.conferencewidget.ConferenceWidgetService.java
com.gareth.assignment.conferencewidget.ConferenceWidget.java
com.gareth.assignment.conferencewidget.DBAccess.java
com.gareth.assignment.conferencewidget.WidgetCollectionItem.java