Android Open Source - Resonos-Android-Framework App






From Project

Back to project page Resonos-Android-Framework.

License

The source code is released under:

Apache License

If you think the Android project Resonos-Android-Framework 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.resonos.apps.library;
//from www.j a v  a 2  s  .c om
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.widget.Toast;

import com.flurry.android.FlurryAgent;
import com.resonos.app.library.R;
import com.resonos.apps.library.AlertFragment.AlertBuilder;
import com.resonos.apps.library.util.AppUtils;
import com.resonos.apps.library.util.ErrorReporter;
import com.resonos.apps.library.util.M;
import com.resonos.apps.library.util.NetworkClient;
import com.resonos.apps.library.util.NetworkClient.OnServerResponseListener;
import com.resonos.apps.library.util.NetworkRequest;
import com.resonos.apps.library.widget.QuickAction3D;

//----------------------------------------------------------------------

public abstract class App implements OnServerResponseListener {

  // constants
  public static boolean DEBUG, LANDSCAPE;
  public static float DENSITY;
  public static int SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_SIZE, SCREEN_XPIX, SCREEN_YPIX;
  public static String SCREEN_SIZE_STRING = "unknown";
  public static final String GLOBAL_PREFERENCES = "_global_preferences";
  public static final String STATE_OLD_VERSION = "oldVersion", STATE_NEW_VERSION = "newVersionID";
  protected static final int DIALOG_USER_RATE = -748382;
  
  // context
  private Context cx;
  private FragmentBaseActivity activity = null;
    
  // objects
  public Handler mHandler = new Handler();
  public NetworkClient mNetworkClient;
    public AppInfo mAppInfo;
    private Thread mUIThread;
    
    // static objects - these must have no activity references
  private static ExecutorService sExecutorService = null;
  private static ThreadFactory sThreadFactory = null;
  private static ErrorReporter sError = null;
  
  // local references to static objects
    public ExecutorService mExecutorService;
  public ErrorReporter mError;
  
  // state
  private boolean mOldVersion = false;
  public String mNewVersionID;
  
  // enum
  public enum NetworkActions {GET_INFO};
  
  /**
   * This class contains fields to fill in about the overriding app
   * No need to fill in fields beginning with an underscore (_)
   */
  public class AppInfo {
    // contants
    private static final int DEF_ASK_EVERY = 6;
    private static final int DEF_EX_THREAD_COUNT = 5;
    
    // these will be filled in automatically
    public String _packageName;
    public String _versionID;
    public int _versionCode;

    // info to supply
    public String appName;
    public String flurryID;
    public boolean debug = false;
    public String packageProName;
    public String contactEmailHelp;
    public String errorURL;
    public String infoURL;
    
    public int mFragmentContainerID;
    public int mRootID;

    public boolean useExecutorService = false;
    public boolean useNetworkClient = true;
    public boolean useNetworkGetInfo = true;
    
    /** set this var to 0 to never ask the user to rate the app */
    public int askUserToRateEvery = DEF_ASK_EVERY;

    public int executorServiceThreadCount = DEF_EX_THREAD_COUNT;

    
    private void prepare() {
      try {
        _packageName = cx.getPackageName();
        PackageInfo pkg = cx.getPackageManager().getPackageInfo(_packageName, 0);
        _versionID = pkg.versionName;
        _versionCode = pkg.versionCode;
      } catch (NameNotFoundException e) {
          _versionID = "Unknown";
          _versionCode = -1;
      }

    }
  }

  /**
   * Create a new App, corresponds to the onCreate of the root activity or service
   * @param context, activity or service
   * @param appInfo, a filled out data structure
   * @param any additional parameter
   */
  public App(Bundle savedInstanceState, Context context) {
    // separate out context and activity to allow for services, etc
    cx = context;
    if (cx instanceof FragmentBaseActivity)
      activity = (FragmentBaseActivity)cx;
    mUIThread = Thread.currentThread();
    
    boolean firstRun = (savedInstanceState == null);
    
    // fill in the rest of the app info
    mAppInfo = new AppInfo();
    getAppParameters(mAppInfo);
    mAppInfo.prepare();
    
    // set some global vars
    DEBUG = mAppInfo.debug;
    
    readScreenConfiguration();
    
    // set up exception handler
    if (sError == null)
      sError = new ErrorReporter(this);
    mError = sError;

    if (mAppInfo.useExecutorService || mAppInfo.useNetworkClient) {
      if (sThreadFactory == null)
        sThreadFactory = new ThreadFactory() {
            private static final String THREAD_FACTORY_TAG = "R Thread #";
              private final AtomicInteger mCount = new AtomicInteger(1);
  
              public Thread newThread(Runnable r) {
                  Thread t = new Thread(r, THREAD_FACTORY_TAG + mCount.getAndIncrement());
                  t.setUncaughtExceptionHandler(mError.getExceptionHandler());
                  return t;
              }
          };
      if (sExecutorService == null)
        sExecutorService = Executors.newFixedThreadPool(mAppInfo.executorServiceThreadCount, sThreadFactory);
      mExecutorService = sExecutorService;
    }

    // load online data
    if (mAppInfo.useNetworkClient)
      mNetworkClient = createNetworkClient();
    
    if (firstRun) {
      if (mAppInfo.useNetworkGetInfo && mAppInfo.infoURL != null)
        mNetworkClient.getRawAsString(NetworkActions.GET_INFO, mAppInfo.infoURL);
      
      if (AppUtils.checkNewVersionFirstLoad(this))
        onNewVersionFirstLoad();
      
        // check if we should ask user to rate
      if (mAppInfo.askUserToRateEvery > 0 && activity != null)
        if (AppUtils.checkDisplayLoadMsg(cx, mAppInfo.askUserToRateEvery))
          onShowUserRateDialog(activity);
    } else {
      mOldVersion = savedInstanceState.getBoolean(STATE_OLD_VERSION, false);
      mNewVersionID = savedInstanceState.getString(STATE_NEW_VERSION);
    }
  }
  
  /**
   * Saves the state of this App to be reloaded after configuration changes.
   * @return a Bundle with the saved information
   */
  public Bundle onSaveInstanceState() {
    Bundle outState = new Bundle();
    outState.putBoolean(STATE_OLD_VERSION, mOldVersion);
    outState.putString(STATE_NEW_VERSION, mNewVersionID);
    return outState;
  }

  /**
   * Update our global static vars with the current screen configuration.
   */
  public void readScreenConfiguration() {
    readScreenConfiguration(-1, -1);
  }
  
  /**
   * Update our global static vars with the current screen configuration.
   * We override the retrieved app width and height sometimes because it cannot
   *  be fully accurately retrieved without just measuring the framelayout everything
   *  is put in.  It is in that class, {@link FragmentBaseActivity.SizeFrameLayout},
   *   when we know that the size is even valid to measure.
   * @param w : override the app width, or -1 to retrieve it as normal
   * @param h : override the app height, or -1 to retrieve it as normal
   */
  public void readScreenConfiguration(int w, int h) {
    DisplayMetrics dm = cx.getResources().getDisplayMetrics();
    SCREEN_WIDTH = SCREEN_XPIX = (w == -1) ? dm.widthPixels : w;
    SCREEN_HEIGHT = SCREEN_YPIX = (h == -1) ? dm.heightPixels : h;
    if (activity != null && w != -1 && h != -1) {
      Window win = activity.getWindow();
      View v = win.findViewById(Window.ID_ANDROID_CONTENT);
      if (v != null) {
        if (v.getHeight() > 0) {
          SCREEN_WIDTH = v.getWidth();
          SCREEN_HEIGHT = v.getHeight();
        }
      }
    }
    DENSITY = dm.density;
    LANDSCAPE = cx.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
    SCREEN_SIZE = cx.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
    switch (SCREEN_SIZE) {
    case Configuration.SCREENLAYOUT_SIZE_XLARGE:
      SCREEN_SIZE_STRING = "xlarge";
      M.log("App", "Screen size is: XLARGE, density is "+DENSITY + ", resolution is "+SCREEN_WIDTH+"x"+SCREEN_HEIGHT);
      break;
    case Configuration.SCREENLAYOUT_SIZE_LARGE:
      SCREEN_SIZE_STRING = "large";
      M.log("App", "Screen size is: LARGE, density is "+DENSITY + ", resolution is "+SCREEN_WIDTH+"x"+SCREEN_HEIGHT);
      break;
    case Configuration.SCREENLAYOUT_SIZE_NORMAL:
      SCREEN_SIZE_STRING = "normal";
      M.log("App", "Screen size is: NORMAL, density is "+DENSITY + ", resolution is "+SCREEN_WIDTH+"x"+SCREEN_HEIGHT);
      break;
    case Configuration.SCREENLAYOUT_SIZE_SMALL:
      SCREEN_SIZE_STRING = "small";
      M.log("App", "Screen size is: SMALL, density is "+DENSITY + ", resolution is "+SCREEN_WIDTH+"x"+SCREEN_HEIGHT);
      break;
    default:
      SCREEN_SIZE_STRING = "unknown";
      M.log("App", "Screen size is: unknown, density is "+DENSITY + ", resolution is "+SCREEN_WIDTH+"x"+SCREEN_HEIGHT);
      break;
    }
  }

  /**
   * Convert DP to pixels. Named inDP to signify providing a measurement "in DP"
   * @param dp : measurement in density pixels
   * @return measurement in pixels
   */
  public static int inDP(int dp) {
    return (int)(dp * DENSITY + 0.5f);
  }
  
  /**
   * Convert pixels to DP
   * @param px : measurement in pixels
   * @return measurement in density pixels
   */
  public static int toDP(int px) {
    return (int)((float)px / DENSITY + 0.5f);
  }
  
  /** 
   * Use this method to supply information about your app
   * @param appInfo: fill in this structure with information
   */
  protected abstract void getAppParameters(AppInfo appInfo);
  
  /**
   * Creates the object that manages loading information from the internet
   * Override this method to use your custon NetworkClient subclass
   * @return
   */
  protected NetworkClient createNetworkClient() {
    return new NetworkClient(this, this);
  }
  
  /**
   * Shows the user the default dialog asking for a rating in the Google Play Market.
   * Override this to have a custom behavior. The default behavior should be suitable for most apps.
   * For a positive response, call AppUtils.launchMarketThisApp(App.this);
   * For a later response, call AppUtils.remindMeLater(cx);
   * For a never response, no action is sufficient.
   */
  protected void onShowUserRateDialog(FragmentBaseActivity a) {
    new AlertBuilder(cx)
      .setTitle(getAppName())
        .setMessage(cx.getString(R.string.txt_ask_rate, getAppName()))
        .setPositiveButton(cx.getString(R.string.btn_rate_market))
        .setNeutralButton(cx.getString(R.string.btn_remind_later))
        .setNegativeButton(cx.getString(R.string.btn_never_again))
        .show(a, DIALOG_USER_RATE);
  }
  
  /**
   * Called when the generic info fetcher from server has completed
   * Override this method to supply some actions.
   * @param success: whether the operation was successful
   * @param response: the raw response
   * @param oldVersion: true if this app is outdated
   * @param info: an attempt to decode the raw response in a param:value style map
   */
  protected void onGetInfo(boolean success, String response,
      boolean oldVersion, Map<String, String> info) {
    //
  }
  
  /**
   * Called when the user has used this app before, but this is the first time the current version has been loaded.
   * Override this to supply some actions.
   */
  protected void onNewVersionFirstLoad() {
    //
  }
  
  @Override
  public void onServerResponse(boolean success, NetworkRequest req, String response) {
    if (req.mID == NetworkActions.GET_INFO) {
      String version = getVersionID();
      Map<String,String> info = null;
      if (success) {
        try {
          info = NetworkClient.createResponseMap(response);
          version = info.get("version");
        } catch (Exception ex) {
          //
        }
      }
      if (version != null && !version.equals(getVersionID())) {
        mOldVersion = true;
        mNewVersionID = version;
      }
      onGetInfo(success, response, mOldVersion, info);
    }
  }
  
  /**
   * @return returns true if this is not the most recent version of the application
   */
  public boolean isOldVersion() {
    return mOldVersion;
  }
  
  /**
   * Gets the UI Thread
   * @return the thread object
   */
  public Thread getUIThread() {
    return mUIThread;
  }

  /**
   * Corresponds to root service/activity onStart
   */
  public void onStart() {
    if (mAppInfo.flurryID != null)
      FlurryAgent.onStartSession(cx, mAppInfo.flurryID);
  }

  /**
   * Corresponds to root service/activity onStop
   */
  public void onStop() {
    if (mAppInfo.flurryID != null)
      FlurryAgent.onEndSession(cx);
  }
    
    /**
     * Shortcut for toasting
     * @param String message
     * @param true for long, false for short
     */
    public void toast(String msg, boolean longToast) {
    CharSequence text = (CharSequence)msg;
    Toast toast = Toast.makeText(cx, text,
        longToast ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
    toast.show();
    }
    
    /**
     * Shortcut for toasting
     * @param String resource message
     * @param true for long, false for short
     */
    public void toast(int msg, boolean longToast) {
    CharSequence text = (CharSequence)cx.getString(msg);
    Toast toast = Toast.makeText(cx, text,
        longToast ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
    toast.show();
    }

    
    /**
     * Creates a tooltip toast where the screen must be tapped to remove it
     * @param String resource message
     */
  public void tooltipToast(final int msg) {
    mHandler.post(new Runnable() {
      public void run() {
          QuickAction3D qa = new QuickAction3D(cx);
          qa.addInfo(0, msg, null);
          qa.showCentered(getRootView(), false);
      }
    });
  }

    
    /**
     * Creates a tooltip toast where the screen must be tapped to remove it
     * @param String message
     */
  public void tooltipToast(final String msg) {
    mHandler.post(new Runnable() {
      public void run() {
          QuickAction3D qa = new QuickAction3D(cx);
          qa.addInfo(0, msg, null);
          qa.showCentered(getRootView(), false);
      }
    });
  }

  /**
   * Fires a flurry custom event with 1 parameter
   * @param event name
   * @param param 1 name
   * @param value 1
   */
    public static void fireTrackerEvent(String event, String param, String value) {
      HashMap<String, String> parameters = new HashMap<String, String>();
      parameters.put(param, value);
      FlurryAgent.onEvent(event, parameters);
      M.log("Home", "Flurry: onEvent "+event + " - " + param + " : " + value);
    }

  /**
   * Fires a flurry custom event with 2 parameters
   * @param event name
   * @param param 1 name
   * @param value 1
   * @param param 2 name
   * @param value 2
   */
  public static void fireTrackerEvent(String event, String param1, String value1,
      String param2, String value2) {
      HashMap<String, String> parameters = new HashMap<String, String>();
      parameters.put(param1, value1);
      parameters.put(param2, value2);
      FlurryAgent.onEvent(event, parameters);
      M.log("Home", "Flurry: onEvent "+event + " - " + param1+ " : " + value1 + " - " + param2+ " : " + value2);
  }

  /**
   * @return The App activity, if it exists
   */
  public Activity getActivity() {
    return activity;
  }

  /**
   * @return The App context
   */
  public Context getContext() {
    return cx;
  }

  /**
   * @return The App name
   */
  public String getAppName() {
    return mAppInfo.appName;
  }

  /**
   * @return The App version name
   */
  public String getVersionID() {
    return mAppInfo._versionID;
  }

  /**
   * @return If we are in debug mode
   */
  public boolean isDebugging() {
    return mAppInfo.debug;
  }

  /**
   * @return the main fragment container view
   */
  public View getContainerView() {
    return activity.findViewById(mAppInfo.mFragmentContainerID);
  }

  /**
   * @return The root of our app's view tree
   */
  public View getRootView() {
    return activity.findViewById(mAppInfo.mRootID);
  }
}




Java Source Code List

com.resonos.apps.library.Action.java
com.resonos.apps.library.AlertFragment.java
com.resonos.apps.library.App.java
com.resonos.apps.library.BaseFragment.java
com.resonos.apps.library.FragmentBaseActivity.java
com.resonos.apps.library.file.AltAndroidFileHandle.java
com.resonos.apps.library.file.AltAndroidFiles.java
com.resonos.apps.library.file.AltFileHandle.java
com.resonos.apps.library.file.FileCache.java
com.resonos.apps.library.media.AudioVisualizer.java
com.resonos.apps.library.media.BitmapMemoryCache.java
com.resonos.apps.library.media.HueColorFilter.java
com.resonos.apps.library.media.ImageLoader.java
com.resonos.apps.library.media.MediaScannerNotifier.java
com.resonos.apps.library.model.Coord.java
com.resonos.apps.library.model.ImmutableCoord.java
com.resonos.apps.library.tabviewpager.CustomViewPager.java
com.resonos.apps.library.tabviewpager.PageIndicator.java
com.resonos.apps.library.tabviewpager.TabPageIndicator.java
com.resonos.apps.library.tabviewpager.TabViewPagerAdapter.java
com.resonos.apps.library.tabviewpager.TabViewPagerFragment.java
com.resonos.apps.library.tabviewpager.TitleProvider.java
com.resonos.apps.library.util.AppUtils.java
com.resonos.apps.library.util.ErrorReporter.java
com.resonos.apps.library.util.LifecycleTaskQueue.java
com.resonos.apps.library.util.M.java
com.resonos.apps.library.util.NetworkClient.java
com.resonos.apps.library.util.NetworkRequest.java
com.resonos.apps.library.util.ParameterList.java
com.resonos.apps.library.util.SensorReader.java
com.resonos.apps.library.util.TouchViewWorker.java
com.resonos.apps.library.util.ViewServer.java
com.resonos.apps.library.widget.DashboardLayout.java
com.resonos.apps.library.widget.FormBuilder.java
com.resonos.apps.library.widget.FormElement.java
com.resonos.apps.library.widget.ListFormBuilder.java
com.resonos.apps.library.widget.PopupWindows3D.java
com.resonos.apps.library.widget.QuickAction3D.java
com.resonos.apps.library.widget.RangeSeekBar.java
com.resonos.apps.library.widget.SeekBar.java
com.resonos.apps.library.widget.ToolBarButton.java
com.resonos.apps.library.widget.ToolBar.java