Android Open Source - Resonos-Android-Framework Network Client






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.util;
//from  w  w  w .j av a  2 s.c o  m
import java.io.BufferedInputStream;
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.math.BigInteger;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.ByteArrayBuffer;

import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.telephony.TelephonyManager;

import com.resonos.app.library.R;
import com.resonos.apps.library.App;
import com.resonos.apps.library.util.NetworkRequest.BaseRequestBuilder;
import com.resonos.apps.library.util.NetworkRequest.BaseRequestBuilder.Method;

public class NetworkClient {
  
  // constants
  private static final int MAX_RETRIES = 2;
   
    /** Wait this many milliseconds max for the TCP connection to be established */
    private static final int CONNECTION_TIMEOUT = 60 * 1000;
 
    /** Wait this many milliseconds max for the server to send us data once the connection has been established */
    private static final int SO_TIMEOUT = 60 * 1000;
  
  public interface DownloadListener {
    public void onDownload(boolean success, NetworkRequest req,
        ByteArrayBuffer baf, File file);
  }

  // objects
    private OnServerResponseListener mListener;
    private DownloadListener mDL;
    private NetworkClientHandler mHandler = null;
    private Handler mUIThreadHandler = null;
    private ExecutorService mES;
    
    // context
    Resources mRes;
    
    // global variables
    private static HttpClient mHttpClient = null;
  
    /**
     * Create a new network client.  You MUST be in the UI thread!
     * @param listener : an object that implements {@link OnServerResponseListener}
     * @param home : the {@link App} object
     */
  public NetworkClient(OnServerResponseListener listener, App home) {
    this(listener, home, Thread.currentThread() != home.getUIThread());
    
  }
  
  public void setDownloadListener(DownloadListener dl) {
    mDL = dl;
  }
  
  public DownloadListener getDownloadListener() {
    return mDL;
  }
    
  /**
   * Create a new network client
     * @param listener : an object that implements {@link OnServerResponseListener}
     * @param home : the {@link App} object
   * @param threadSafe : if true, you do not need to be in the UI thread to create this object
   */
    private NetworkClient(OnServerResponseListener listener, App home, boolean threadSafe) {
    mListener = listener;
    mRes = home.getContext().getApplicationContext().getResources();
    mES = home.mExecutorService;
    mUIThreadHandler = home.mHandler;
    if (threadSafe)
      mHandler = new NetworkClientHandler();
    else
      mUIThreadHandler.post(new Runnable() {
        @Override
        public void run() {
          synchronized (NetworkClient.this) {
            mHandler = new NetworkClientHandler();
          }
        }
      });
  }

    /**
     * An implementation of a Handler that deals with network responses.
     */
  public class NetworkClientHandler extends Handler {
    /**
     * Called when a server response arrives.
     * @param success : boolean indicating a successful request
     * @param req : the original {@link NetworkRequest} object
     * @param resp : the raw response
     */
    public void onServerResponse(boolean success, final NetworkRequest req, String resp) {
          if (resp == null) {
            resp = " ";
            success = false;
          }
          else if (resp.equals(""))
            resp = " ";
//          if (resp.startsWith("Error:")) { // localize the error message
//            try {
//              String errorKey = resp.substring(6).trim();
//              resp = null;
//              for (int i = 0; i < NETWORK_ERROR_KEYS.length; i++) {
//                if (errorKey.equals(NETWORK_ERROR_KEYS[i])) {
//                  resp = mRes.getString(NETWORK_ERROR_VALUES[i]);
//                  break;
//                }
//              }
//            } catch (Exception ex) {
//              resp = null;
//            }
//          if (resp == null)
//            resp = mRes.getString(R.string.error_unknown);
//          }
          
          if (resp.charAt(0) == '<' && (resp.contains("502") || resp.contains("500"))) { // nginx and apache errors
            resp = mRes.getString(R.string.error_server_maintenance);
            success = false;
            req.mServerBusy = true;
            if (req.mRetries < MAX_RETRIES) {
              postDelayed(new Runnable() {
            @Override
            public void run() {
              req.mRetries++;
              doRequestToString(req);
            }
              }, 250);
            }
          }
          else
            req.mServerBusy = false;
          mListener.onServerResponse(success, req, resp.trim());
    }

    public void onDownloadResponse(boolean success, NetworkRequest req,
        ByteArrayBuffer baf, File file) {
      if (mDL != null)
        mDL.onDownload(success, req, baf, file);
    }
    };
  
  /**
   * Download a raw page
   * @param tag : Enum to tag this request
   * @param URL : the URL to download
   * @return the {@link NetworkRequest} object representing the request
   */
  public NetworkRequest getRawAsString(Enum<?> tag, String URL) {
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
    return performRequest(tag, new BaseRequestBuilder(URL), nameValuePairs);
  }
  
  /**
   * Download a raw file
   * @param tag : Enum to tag this request
   * @param URL : the URL to download
   * @param file : the optional file to save to
   * @param r : the option runnable to use to process the file off the UI thread
   * @return the {@link NetworkRequest} object representing the request
   */
  public NetworkRequest getRawAsByteArray(Enum<?> tag, String URL, File file, Runnable r) {
    NetworkRequest req = createRequest(tag, new BaseRequestBuilder(URL), null);
    doDownloadToByteArray(req, file, r);
    return req;
  }
  
  /**
   * Download a raw file
   * @param req : a pre-formed {@link NetworkRequest} object
   * @param file : the optional file to save to
   * @param r : the option runnable to use to process the file off the UI thread
   * @return the {@link NetworkRequest} object representing the request
   */
  public NetworkRequest performRequestByteArray(NetworkRequest req, File file, Runnable r) {
    doDownloadToByteArray(req, file, r);
    return req;
  }

  /**
   * Perform a network request
   * @param tag : Enum to tag this request
   * @param type : an object extending {@link BaseRequestBuilder} instructing how to build the URL and the request method
   * @param params : any parameters
   * @return The network request for chaining
   */
  public NetworkRequest performRequest(Enum<?> tag, BaseRequestBuilder type,  List<NameValuePair> params) {
    NetworkRequest req = createRequest(tag, type, params);
    doRequestToString(req);
    return req;
  }

  public NetworkRequest performRequest(NetworkRequest req) {
    doRequestToString(req);
    return req;
  }
  
  /** Create a NetworkRequest object from an enum, a url, a request type, and a list of name-value pairs */
  public static NetworkRequest createRequest(Enum<?> tag, BaseRequestBuilder type, List<NameValuePair> params) {
    return new NetworkRequest(tag, type, params);
  }

  /**
   * Uses the executor service to perform a network download request
   * @param req : only uses the URL portion
   * @param file : the optional file to save to
   * @param r : the option runnable to use to process the file off the UI thread
   */
  private void doDownloadToByteArray(final NetworkRequest req, final File file, final Runnable r) {
    final Runnable task = new Runnable() {
      @Override
      public void run() {
        ByteArrayBuffer baf;
        try {
          // contact server
          URL url = new URL(req.mType.getFullPath());
          URLConnection ucon = url.openConnection();
          
          // load data from web
          InputStream is = ucon.getInputStream();
          BufferedInputStream bis = new BufferedInputStream(is);
          baf = new ByteArrayBuffer(50);
          int current = 0;
          while ((current = bis.read()) != -1) {
            baf.append((byte) current);
          }
          bis.close();
          
          if (file != null) {
            // write data to file
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baf.toByteArray());
            fos.close();
            
            if (r != null) {
              r.run();
            }
          }
        } catch (Exception ex) {
          baf = null;
//          ErrorReporter.getInstance().report("NetworkClient.doDownloadToByteArray", ex);
        }

            final boolean success = baf != null;
            final ByteArrayBuffer fbaf = baf;
            mHandler.post(new Runnable() {
          @Override
          public void run() {
            mHandler.onDownloadResponse(success, req, fbaf, file);
          }
            });
      }
    };
    synchronized (this) {
      if (mHandler == null) {
        mUIThreadHandler.post(new Runnable() {
          @Override
          public void run() {
            mES.execute(task);
          }
        });
      }
      else
        mES.execute(task);
    }
  }

  /**
   * Uses the executor service to perform a network request
   * @param req
   */
  private void doRequestToString(final NetworkRequest req) {
    final Runnable task = new Runnable() {
      @Override
      public void run() {
        String text;
            try {
              text = openHttpConnection(req);
            }
            catch (Exception ex) {
              text = null;
            }

            final String resp;
            final boolean success;
        if (text == null) {
                  resp = "Error:network";
            success = false;
        }
        else {
          M.log("NetworkClient: Response", text);
                  resp = text;
            success = true;
        }
            mHandler.post(new Runnable() {
          @Override
          public void run() {
            mHandler.onServerResponse(success, req, resp);
          }
            });
      }
    };
    synchronized (this) {
      if (mHandler == null) {
        mUIThreadHandler.post(new Runnable() {
          @Override
          public void run() {
            mES.execute(task);
          }
        });
      }
      else
        mES.execute(task);
    }
  }
  
  /** Turns an HttpResponse object int a String */
  public static String getResponseText(HttpResponse res) {
        String result = "";
        try {
            InputStream in = res.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in), 512);
            StringBuilder str = new StringBuilder();
            String line = null;
            while((line = reader.readLine()) != null){
                str.append(line + "\n");
            }
            in.close();
            result = str.toString();
            reader.close();
        } catch (Exception ex) {
            result = null;
        }
        return result;
    }

  /** Opens an HTTP connection based on a NetworkRequest object.
   * Only use this function if you've created a separate thread for it to run in. */
  public static String openHttpConnection(NetworkRequest req) {
    HttpClient httpclient = getHttpClient();
    HttpRequestBase httpReq;

    try {
      String urlStr = req.mType.getFullPath();
      if (req.mType.getMethod() == Method.POST) {
        HttpPost httpPost = new HttpPost(urlStr);
        httpPost.setEntity(new UrlEncodedFormEntity(req.mParams));
        httpReq = httpPost;
      } else { //if (req.mType.getMethod() == Method.GET) {
        String query = (req.mParams.size() > 0)
            ? URLEncodedUtils.format(req.mParams, "utf-8") : null;
        HttpGet httpGet = new HttpGet(urlStr + (query != null
            ? ((urlStr.contains("?") ? "&" : "?") + query) : ""));
        httpReq = httpGet;
      }
      
      try {
        HttpResponse response = httpclient.execute(httpReq);
        return getResponseText(response); 
      } catch (ClientProtocolException e) {
        e.printStackTrace();
        return null;
      } catch (IOException e) {
        e.printStackTrace();
        return null;
      }
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
  
  /**
   * Decodes a primitive json format that looks like:
   * name1:value1|name2:value2|etc...
   * @param resp : the input text
   * @return A HashMap representing the decoded information
   */
  public static Map<String,String> createResponseMap(String resp) {
    Map<String,String> values = new HashMap<String,String>();
    String[] data = resp.split("\\|");
    for (String s : data) {
      String[] parts = s.split("\\:");
      try {
        values.put(parts[0], parts[1].trim());
      }
      catch (ArrayIndexOutOfBoundsException ex) {
        values.put(s, "");
      }
    }
    return values;
  }

  /**
   * Returns the MD5 hash of an input text that is compatible with the PHP method.
   * @param input : the input text
   * @return the MD5 hash
   */
  public static String md5(String input) {
    try {
          String result = input;
          if(input != null) {
              MessageDigest md = MessageDigest.getInstance("MD5"); //or "SHA-1"
              md.update(input.getBytes());
              BigInteger hash = new BigInteger(1, md.digest());
              result = hash.toString(16);
              if ((result.length() % 2) != 0) {
                  result = "0" + result;
              }
          }
          return result;
    }
    catch (NoSuchAlgorithmException ex) {
      return "";
    }
    }

  /**
   * Returns the SHA1 hash of an input text that is compatible with the PHP method.
   * @param input : the input text
   * @return the SHA1 hash
   */
  public static String sha1(String input) {
    try {
          String result = input;
          if(input != null) {
              MessageDigest md = MessageDigest.getInstance("SHA-1");
              md.update(input.getBytes());
              BigInteger hash = new BigInteger(1, md.digest());
              result = hash.toString(16);
              if ((result.length() % 2) != 0) {
                  result = "0" + result;
              }
          }
          return result;
    }
    catch (NoSuchAlgorithmException ex) {
      return "";
    }
    }

  /**
   * Safely returns the IMEI of the device.
   * Requires the READ_PHONE_STATE permission.
   * @param cx : Context object
   * @return The IMEI as a String, or "noID" if there is no IMEI or it was unable to be retrieved.
   */
  public static String getSafeIMEI(Context cx) {
    try {
        TelephonyManager telephonyManager = (TelephonyManager)cx.getSystemService(Context.TELEPHONY_SERVICE);
      String id = telephonyManager.getDeviceId();
      return (id == null) ? "noID" : id;
    } catch (Exception ex) {
      return "noID";
    }
  }


  /**
   * Safely returns the MAC address of the device.
   * Requires the ACCESS_WIFI_STATE permission.
   * @param cx : Context object
   * @return The MAC address as a String, or "noID" if there is no MAC or it was unable to be retrieved.
   */
  public static String getSafeMAC(Context cx) {
    WifiManager wm = (WifiManager)cx.getSystemService(Context.WIFI_SERVICE);
    String deviceID = wm.getConnectionInfo().getMacAddress();
    if (deviceID == null)
      deviceID = "noID";
    else if (deviceID.equals(""))
      deviceID = "noID";
    return deviceID;
  }
  
  /**
   * Safely returns the IP address of the device
   * @return The IP address as a string, or an empty String if it was unable to be retrieved
   */
  public static String getSafeIP() {
      try {
          for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
              NetworkInterface intf = en.nextElement();
              for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                  InetAddress inetAddress = enumIpAddr.nextElement();
                  if (!inetAddress.isLoopbackAddress()) {
                      return inetAddress.getHostAddress().toString();
                  }
              }
          }
      } catch (SocketException ex) {
          return "";
      }
      return "";
  }
  
  /**
   * Determines whether the user is online.
   * @param cx : app context
   * @return true if the user is connected or connecting
   */
  public static boolean isOnline(Context cx) {
      ConnectivityManager cm = (ConnectivityManager)cx.getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo netInfo = cm.getActiveNetworkInfo();
      if (netInfo != null)
        if (netInfo.isConnectedOrConnecting())
          return true;
      return false;
  }

  /**
   * An interface that listens for the responses to {@link NetworkRequest}s
   */
  public interface OnServerResponseListener {
    /**
     * Called when the response to a request arrives
     * @param success : true if the request was successful
     * @param req : the NetworkRequest object
     * @param response : the raw response
     */
    public void onServerResponse(boolean success, NetworkRequest req, String response);
  }
  
  public static final String[] NETWORK_ERROR_KEYS = {
    "network"
//    "account_validate",
//    "account_exists",
//    "account_username_invalid",
//    "account_username_missing",
//    "account_password_invalid",
//    "account_password_match",
//    "account_username_wrong",
//    "account_password_wrong",
//    "account_userpass_missing",
//    "account_data_missing"
  };
  
  public static final int[] NETWORK_ERROR_VALUES = {
    R.string.error_network
//    R.string.error_account_validate,
//    R.string.error_account_exists,
//    R.string.error_account_username_invalid,
//    R.string.error_account_username_missing,
//    R.string.error_account_password_invalid,
//    R.string.error_account_password_match,
//    R.string.error_account_username_wrong,
//    R.string.error_account_password_wrong,
//    R.string.error_account_userpass_missing,
//    R.string.error_account_data_missing
  };
 
  /**
   * Get the global HTTP client for this app. Using this should improve network performance.
   * @return the global HttpClient object
   */
    public static HttpClient getHttpClient() {
      if (mHttpClient == null) {
          mHttpClient = new DefaultHttpClient(){
              @Override
              protected ClientConnectionManager createClientConnectionManager() {
                  SchemeRegistry registry = new SchemeRegistry();
                  registry.register(
                          new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
                  HttpParams params = getParams();
                  HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
                  HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT);
                  return new ThreadSafeClientConnManager(params, registry);
              }
          };
      }
        return mHttpClient;
    }
}




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