private void shareComicImage() {
    Intent share = new Intent(Intent.ACTION_SEND);
    share.setType("image/*");
    Bitmap mBitmap = mComicMap.get(sFavoriteIndex).getBitmap();
    try {
      String path =
          MediaStore.Images.Media.insertImage(
              getActivity().getContentResolver(), mBitmap, "Image Description", null);
      share.putExtra(Intent.EXTRA_STREAM, Uri.parse(path));
    } catch (Exception e) {
      try {
        File cachePath = new File(getActivity().getCacheDir(), "images");
        cachePath.mkdirs(); // don't forget to make the directory
        FileOutputStream stream = new FileOutputStream(cachePath + "/image.png");
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        stream.close();

        File imagePath = new File(getActivity().getCacheDir(), "images");
        File newFile = new File(imagePath, "image.png");
        Uri contentUri =
            FileProvider.getUriForFile(
                getActivity(), "com.gadgetmonks.carntoonage.fileprovider", newFile);

        share.putExtra(Intent.EXTRA_STREAM, contentUri);
      } catch (IOException e2) {
        e.printStackTrace();
      }
    }
    if (PrefHelper.shareAlt()) {
      share.putExtra(Intent.EXTRA_TEXT, PrefHelper.getAlt(sFavorites[sFavoriteIndex]));
    }
    startActivity(Intent.createChooser(share, this.getResources().getString(R.string.share_image)));
  }
  /**
   * Converts a generic {@link HttpEntity} object into a {@link ServerResponse} object by reading
   * the content supplied in the raw server response, and creating a {@link JSONObject} that
   * contains the same data. This data is then attached as the post data of the {@link
   * ServerResponse} object returned.
   *
   * @param entity A generic {@link HttpEntity} returned as a result of a HTTP response.
   * @param statusCode An {@link Integer} value containing the HTTP response code.
   * @param tag A {@link String} value containing the tag value to be applied to the resultant
   *     {@link ServerResponse} object.
   * @param log A {@link Boolean} value indicating whether or not to log the raw content lines via
   *     the debug interface.
   * @param linkData A {@link BranchLinkData} object containing the data dictionary associated with
   *     the link subject of the original server request.
   * @return A {@link ServerResponse} object representing the {@link HttpEntity} response in Branch
   *     SDK terms.
   * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP/1.1: Status
   *     Codes</a>
   */
  private ServerResponse processEntityForJSON(
      HttpEntity entity, int statusCode, String tag, boolean log, BranchLinkData linkData) {
    ServerResponse result = new ServerResponse(tag, statusCode, linkData);
    try {
      if (entity != null) {
        InputStream instream = entity.getContent();
        BufferedReader rd = new BufferedReader(new InputStreamReader(instream));

        String line = rd.readLine();
        if (log) PrefHelper.Debug("BranchSDK", "returned " + line);

        if (line != null) {
          try {
            JSONObject jsonObj = new JSONObject(line);
            result.setPost(jsonObj);
          } catch (JSONException ex) {
            try {
              JSONArray jsonArray = new JSONArray(line);
              result.setPost(jsonArray);
            } catch (JSONException ex2) {
              if (log)
                PrefHelper.Debug(getClass().getSimpleName(), "JSON exception: " + ex2.getMessage());
            }
          }
        }
      }
    } catch (IOException ex) {
      if (log) PrefHelper.Debug(getClass().getSimpleName(), "IO exception: " + ex.getMessage());
    }
    return result;
  }
 private boolean setAltText() {
   // If the user selected the menu item for the first time, show the toast
   if (PrefHelper.showAltTip()) {
     Toast toast = Toast.makeText(getActivity(), R.string.action_alt_tip, Toast.LENGTH_LONG);
     toast.show();
     /*SharedPreferences.Editor mEditor = mSharedPreferences.edit();
     mEditor.putBoolean("alt_tip", false);
     mEditor.apply();*/
     PrefHelper.setAltTip(false);
   }
   TextView tvAlt = (TextView) mPager.getChildAt(sFavoriteIndex).findViewById(R.id.tvAlt);
   tvAlt.setText(PrefHelper.getAlt(sFavorites[sFavoriteIndex]));
   toggleVisibility(tvAlt);
   return true;
 }
Example #4
0
  private View createCheckBox(ViewGroup parent, MethodInfo methodInfo) {
    final Method method = methodInfo.getMethod();
    final Object instance = methodInfo.getInstance();
    final Context context = parent.getContext();

    View view = inflater.inflate(R.layout.item_settings_checkbox, parent, false);
    ((TextView) view.findViewById(R.id.title)).setText(methodInfo.getTitle());
    CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
    checkBox.setOnCheckedChangeListener(
        new CompoundButton.OnCheckedChangeListener() {
          @Override
          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            try {
              method.invoke(instance, isChecked);
            } catch (Exception e) {
              Log.e("Bee", e.getMessage());
            }

            PrefHelper.setBoolean(context, method.getName(), isChecked);
          }
        });
    checkBox.setChecked(PrefHelper.getBoolean(context, method.getName()));

    return view;
  }
  private void shareComicUrl() {
    Intent share = new Intent(android.content.Intent.ACTION_SEND);
    share.setType("text/plain");

    // share.putExtra(Intent.EXTRA_SUBJECT, mSharedPreferences.getString(("title" +
    // String.valueOf(sFavorites[sFavoriteIndex])), ""));
    share.putExtra(Intent.EXTRA_SUBJECT, PrefHelper.getTitle(sFavorites[sFavoriteIndex]));
    if (PrefHelper.shareMobile()) {
      share.putExtra(
          Intent.EXTRA_TEXT, "http://m.xkcd.com/" + String.valueOf(sFavorites[sFavoriteIndex]));
    } else {
      share.putExtra(
          Intent.EXTRA_TEXT, "http://xkcd.com/" + String.valueOf(sFavorites[sFavoriteIndex]));
    }
    startActivity(Intent.createChooser(share, this.getResources().getString(R.string.share_url)));
  }
  private boolean shareComic() {

    if (PrefHelper.shareImage()) {
      shareComicImage();
      return true;
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setItems(
        R.array.share_dialog,
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            switch (which) {
              case 0:
                shareComicImage();
                break;
              case 1:
                shareComicUrl();
                break;
            }
          }
        });
    AlertDialog alert = builder.create();
    alert.show();
    return true;
  }
  private boolean modifyFavorites() {
    final int mRemoved = sFavorites[sFavoriteIndex];
    final Bitmap mRemovedBitmap = mComicMap.get(sFavoriteIndex).getBitmap();
    // final String mAlt = mSharedPreferences.getString(("alt" +
    // String.valueOf(sFavorites[sFavoriteIndex])), "");
    // final String mTitle = mSharedPreferences.getString(("title" +
    // String.valueOf(sFavorites[sFavoriteIndex])), "");

    final String mAlt = PrefHelper.getAlt(sFavorites[sFavoriteIndex]);
    final String mTitle = PrefHelper.getTitle(sFavorites[sFavoriteIndex]);

    new DeleteImageTask().execute(mRemoved);

    View.OnClickListener oc =
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            Favorites.addFavoriteItem(getActivity(), String.valueOf(mRemoved));
            try {
              FileOutputStream fos =
                  getActivity().openFileOutput(String.valueOf(mRemoved), Context.MODE_PRIVATE);
              mRemovedBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
              fos.close();
            } catch (Exception e) {
              e.printStackTrace();
            }
            /*SharedPreferences sharedPreferences = getActivity().getPreferences(Activity.MODE_PRIVATE);
            SharedPreferences.Editor mEditor = sharedPreferences.edit();

            mEditor.putString(("title" + String.valueOf(mRemoved)), mTitle);
            mEditor.putString(("alt" + String.valueOf(mRemoved)), mAlt);
            mEditor.apply();*/

            PrefHelper.addTitle(mTitle, mRemoved);
            PrefHelper.addAlt(mAlt, mRemoved);

            refresh();
          }
        };

    FloatingActionButton fab = (FloatingActionButton) getActivity().findViewById(R.id.fab);
    Snackbar.make(fab, R.string.snackbar_remove, Snackbar.LENGTH_LONG)
        .setAction(R.string.snackbar_undo, oc)
        .show();
    return true;
  }
  private boolean addCommonParams(JSONObject post, int retryNumber) {
    try {
      String branch_key = prefHelper_.getBranchKey();
      String app_key = prefHelper_.getAppKey();

      post.put("sdk", "android" + SDK_VERSION);
      post.put("retryNumber", retryNumber);
      if (!branch_key.equals(PrefHelper.NO_STRING_VALUE)) {
        post.put(BRANCH_KEY, prefHelper_.getBranchKey());
        return true;
      } else if (!app_key.equals(PrefHelper.NO_STRING_VALUE)) {
        post.put("app_id", prefHelper_.getAppKey());
        return true;
      }
    } catch (JSONException ignore) {
    }
    return false;
  }
  /**
   * The main RESTful GET method; the other one ({@link #make_restful_get(String, String, int)})
   * calls this one with a pre-populated logging parameter.
   *
   * @param baseUrl A {@link String} URL to request from.
   * @param tag A {@link String} tag for logging/analytics purposes.
   * @param timeout An {@link Integer} value containing the number of milliseconds to wait before
   *     considering a server request to have timed out.
   * @param log A {@link Boolean} value that specifies whether debug logging should be enabled for
   *     this request or not.
   * @return A {@link ServerResponse} object containing the result of the RESTful request.
   */
  private ServerResponse make_restful_get(
      String baseUrl, String tag, int timeout, int retryNumber, boolean log) {
    String modifiedUrl = baseUrl;
    JSONObject getParameters = new JSONObject();
    HttpsURLConnection connection = null;
    if (timeout <= 0) {
      timeout = DEFAULT_TIMEOUT;
    }
    if (addCommonParams(getParameters, retryNumber)) {
      modifiedUrl += this.convertJSONtoString(getParameters);
    } else {
      return new ServerResponse(tag, NO_BRANCH_KEY_STATUS);
    }

    try {
      if (log) PrefHelper.Debug("BranchSDK", "getting " + modifiedUrl);
      URL urlObject = new URL(modifiedUrl);
      connection = (HttpsURLConnection) urlObject.openConnection();
      connection.setConnectTimeout(timeout);
      connection.setReadTimeout(timeout);

      if (connection.getResponseCode() >= 500 && retryNumber < prefHelper_.getRetryCount()) {
        try {
          Thread.sleep(prefHelper_.getRetryInterval());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        retryNumber++;
        return make_restful_get(baseUrl, tag, timeout, retryNumber, log);
      } else {
        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK
            && connection.getErrorStream() != null) {
          return processEntityForJSON(
              connection.getErrorStream(), connection.getResponseCode(), tag, log, null);
        } else {
          return processEntityForJSON(
              connection.getInputStream(), connection.getResponseCode(), tag, log, null);
        }
      }
    } catch (SocketException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (UnknownHostException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (IOException ex) {
      if (log) PrefHelper.Debug(getClass().getSimpleName(), "IO exception: " + ex.getMessage());
      return new ServerResponse(tag, 500);
    } finally {
      if (connection != null) {
        connection.disconnect();
      }
    }
  }
  /**
   * The main RESTful GET method; the other one ({@link #make_restful_get(String, String, int)})
   * calls this one with a pre-populated logging parameter.
   *
   * @param baseUrl A {@link String} URL to request from.
   * @param tag A {@link String} tag for logging/analytics purposes.
   * @param timeout An {@link Integer} value containing the number of milliseconds to wait before
   *     considering a server request to have timed out.
   * @param log A {@link Boolean} value that specifies whether debug logging should be enabled for
   *     this request or not.
   * @return A {@link ServerResponse} object containing the result of the RESTful request.
   */
  private ServerResponse make_restful_get(
      String baseUrl, String tag, int timeout, int retryNumber, boolean log) {
    String modifiedUrl = baseUrl;
    JSONObject getParameters = new JSONObject();
    if (addCommonParams(getParameters, retryNumber)) {
      modifiedUrl += this.convertJSONtoString(getParameters);
    } else {
      return new ServerResponse(tag, NO_BRANCH_KEY_STATUS);
    }

    try {
      if (log) PrefHelper.Debug("BranchSDK", "getting " + modifiedUrl);
      HttpGet request = new HttpGet(modifiedUrl);
      HttpResponse response = getGenericHttpClient(timeout).execute(request);
      if (response.getStatusLine().getStatusCode() >= 500
          && retryNumber < prefHelper_.getRetryCount()) {
        try {
          Thread.sleep(prefHelper_.getRetryInterval());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        retryNumber++;
        return make_restful_get(baseUrl, tag, timeout, retryNumber, log);
      } else {
        return processEntityForJSON(
            response.getEntity(), response.getStatusLine().getStatusCode(), tag, log, null);
      }

    } catch (ClientProtocolException ex) {
      if (log)
        PrefHelper.Debug(
            getClass().getSimpleName(), "Client protocol exception: " + ex.getMessage());
    } catch (SocketException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (UnknownHostException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (IOException ex) {
      if (log) PrefHelper.Debug(getClass().getSimpleName(), "IO exception: " + ex.getMessage());
      return new ServerResponse(tag, 500);
    }
    return null;
  }
    @Override
    protected void onPostExecute(Void v) {
      mPager.setAdapter(mPagerAdapter);
      mPagerAdapter.notifyDataSetChanged();
      mPager.setCurrentItem(sFavoriteIndex);

      if (PrefHelper.subtitleEnabled() && MainActivity.sCurrentFragment == R.id.nav_favorites) {
        mActionBar.setSubtitle(String.valueOf(sFavorites[sFavoriteIndex]));
      }

      Toolbar toolbar = ((MainActivity) getActivity()).toolbar;
      if (toolbar.getAlpha() == 0) {
        toolbar.setTranslationY(-300);
        toolbar.animate().setDuration(300).translationY(0).alpha(1);
        View view;
        for (int i = 0; i < toolbar.getChildCount(); i++) {
          view = toolbar.getChildAt(i);
          view.setTranslationY(-300);
          view.animate().setStartDelay(50 * (i + 1)).setDuration(70 * (i + 1)).translationY(0);
        }
      }
    }
Example #12
0
  private View createSpinner(ViewGroup parent, MethodInfo methodInfo) {

    final Method method = methodInfo.getMethod();
    final Object instance = methodInfo.getInstance();
    final Context context = parent.getContext();

    View view = inflater.inflate(R.layout.item_settings_spinner, parent, false);
    ((TextView) view.findViewById(R.id.title)).setText(methodInfo.getTitle());

    String[] dataList = (String[]) methodInfo.getData();
    ArrayAdapter<String> adapter =
        new ArrayAdapter<>(parent.getContext(), R.layout.simple_spinner_item, dataList);

    Spinner spinner = (Spinner) view.findViewById(R.id.spinner);
    spinner.setAdapter(adapter);
    spinner.setOnItemSelectedListener(
        new AdapterView.OnItemSelectedListener() {
          @Override
          public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String value = (String) parent.getItemAtPosition(position);

            try {
              method.invoke(instance, value);
            } catch (Exception e) {
              Log.e("Bee", e.getMessage());
            }

            PrefHelper.setInt(context, method.getName(), position);
          }

          @Override
          public void onNothingSelected(AdapterView<?> parent) {}
        });
    spinner.setSelection(PrefHelper.getInt(context, method.getName()));
    return view;
  }
  /**
   * The main RESTful POST method. The others call this one with pre-populated parameters.
   *
   * @param body A {@link JSONObject} containing the main data body/payload of the request.
   * @param url A {@link String} URL to request from.
   * @param tag A {@link String} tag for logging/analytics purposes.
   * @param timeout An {@link Integer} value containing the number of milliseconds to wait before
   *     considering a server request to have timed out.
   * @param log A {@link Boolean} value that specifies whether debug logging should be enabled for
   *     this request or not.
   * @param linkData A {@link BranchLinkData} object containing the data dictionary associated with
   *     the link subject of the original server request.
   * @return A {@link ServerResponse} object representing the {@link HttpEntity} response in Branch
   *     SDK terms.
   */
  private ServerResponse make_restful_post(
      JSONObject body,
      String url,
      String tag,
      int timeout,
      int retryNumber,
      boolean log,
      BranchLinkData linkData) {
    try {
      JSONObject bodyCopy = new JSONObject();
      Iterator<?> keys = body.keys();
      while (keys.hasNext()) {
        String key = (String) keys.next();
        try {
          bodyCopy.put(key, body.get(key));
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }

      if (!addCommonParams(bodyCopy, retryNumber)) {
        return new ServerResponse(tag, NO_BRANCH_KEY_STATUS);
      }
      if (log) {
        PrefHelper.Debug("BranchSDK", "posting to " + url);
        PrefHelper.Debug("BranchSDK", "Post value = " + bodyCopy.toString(4));
      }
      HttpPost request = new HttpPost(url);
      request.setEntity(new ByteArrayEntity(bodyCopy.toString().getBytes("UTF8")));
      request.setHeader("Content-type", "application/json");
      HttpResponse response = getGenericHttpClient(timeout).execute(request);
      if (response.getStatusLine().getStatusCode() >= 500
          && retryNumber < prefHelper_.getRetryCount()) {
        try {
          Thread.sleep(prefHelper_.getRetryInterval());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        retryNumber++;
        return make_restful_post(bodyCopy, url, tag, timeout, retryNumber, log, linkData);
      } else {
        ServerResponse serverResponse =
            processEntityForJSON(
                response.getEntity(), response.getStatusLine().getStatusCode(), tag, log, linkData);
        serverResponse.setRequestObject(body);
        return serverResponse;
      }
    } catch (SocketException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (UnknownHostException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (Exception ex) {
      if (log) PrefHelper.Debug(getClass().getSimpleName(), "Exception: " + ex.getMessage());
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
        if (ex instanceof NetworkOnMainThreadException)
          Log.i(
              "BranchSDK",
              "Branch Error: Don't call our synchronous methods on the main thread!!!");
      }
      return new ServerResponse(tag, 500);
    }
  }
 @Override
 public void onCreate() {
   super.onCreate();
   PrefHelper.setup(getApplicationContext());
 }
 /**
  * Creates an instance of ServerRequest.
  *
  * @param requestPath Path to server for this request.
  * @param post A {@link JSONObject} containing the post data supplied with the current request as
  *     key-value pairs.
  * @param context Application context.
  */
 protected ServerRequest(String requestPath, JSONObject post, Context context) {
   requestPath_ = requestPath;
   post_ = post;
   prefHelper_ = PrefHelper.getInstance(context);
 }
 /**
  * Creates an instance of ServerRequest.
  *
  * @param context Application context.
  * @param requestPath Path to server for this request.
  */
 public ServerRequest(Context context, String requestPath) {
   requestPath_ = requestPath;
   prefHelper_ = PrefHelper.getInstance(context);
 }
 /**
  * Creates an instance of ServerRequest.
  *
  * @param context Application context.
  * @param requestPath Path to server for this request.
  */
 public ServerRequest(Context context, String requestPath) {
   requestPath_ = requestPath;
   prefHelper_ = PrefHelper.getInstance(context);
   params_ = new JSONObject();
 }
    @Override
    public Object instantiateItem(ViewGroup container, final int position) {

      View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false);
      final PhotoView pvComic = (PhotoView) itemView.findViewById(R.id.ivComic);
      itemView.setTag(position);

      final TextView tvAlt = (TextView) itemView.findViewById(R.id.tvAlt);

      if (PrefHelper.altByDefault()) {
        tvAlt.setVisibility(View.VISIBLE);
      }
      tvAlt.setText(PrefHelper.getAlt(sFavorites[position]));

      // fix for issue #2
      pvComic.setOnDoubleTapListener(
          new GestureDetector.OnDoubleTapListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
              if (pvComic.getScale() < 0.5f * pvComic.getMaximumScale()) {
                pvComic.setScale(0.5f * pvComic.getMaximumScale(), true);
              } else if (pvComic.getScale() < pvComic.getMaximumScale()) {
                pvComic.setScale(pvComic.getMaximumScale(), true);
              } else {
                pvComic.setScale(1.0f, true);
              }
              return true;
            }

            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
              if (!PrefHelper.altLongTap()) {
                if (PrefHelper.classicAltStyle()) {
                  toggleVisibility(tvAlt);
                } else {
                  android.support.v7.app.AlertDialog.Builder mDialog =
                      new android.support.v7.app.AlertDialog.Builder(getActivity());
                  mDialog.setMessage(tvAlt.getText());
                  mDialog.show();
                }
              }
              return false;
            }

            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
              if (e.getAction() == MotionEvent.ACTION_UP) {
                fingerLifted = true;
              }
              if (e.getAction() == MotionEvent.ACTION_DOWN) {
                fingerLifted = false;
              }
              return false;
            }
          });

      // Setup alt text and LongClickListener
      pvComic.setOnLongClickListener(
          new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
              if (fingerLifted && PrefHelper.altLongTap()) {
                if (PrefHelper.altVibration()) {
                  Vibrator vi =
                      (Vibrator) getActivity().getSystemService(MainActivity.VIBRATOR_SERVICE);
                  vi.vibrate(10);
                }
                // tvAlt.setText(PrefHelper.getAlt(sFavorites[sFavoriteIndex]));
                if (PrefHelper.classicAltStyle()) {
                  toggleVisibility(tvAlt);
                } else {
                  android.support.v7.app.AlertDialog.Builder mDialog =
                      new android.support.v7.app.AlertDialog.Builder(getActivity());
                  mDialog.setMessage(tvAlt.getText());
                  mDialog.show();
                }
              }
              return true;
            }
          });
      // setup the title text view
      TextView tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
      tvTitle.setText(PrefHelper.getTitle(sFavorites[position]));

      if (PrefHelper.invertColors()) {
        float[] colorMatrix_Negative = {
          -1.0f,
          0,
          0,
          0,
          255, // red
          0,
          -1.0f,
          0,
          0,
          255, // green
          0,
          0,
          -1.0f,
          0,
          255, // blue
          0,
          0,
          0,
          1.0f,
          0 // alpha
        };
        ColorFilter cf = new ColorMatrixColorFilter(colorMatrix_Negative);
        pvComic.setColorFilter(cf);
      }

      // load the image
      pvComic.setImageBitmap(mComicMap.get(position).getBitmap());
      if (Arrays.binarySearch(
              mContext.getResources().getIntArray(R.array.large_comics), sFavorites[sFavoriteIndex])
          >= 0) {
        pvComic.setMaximumScale(7.0f);
      }
      // Disable ViewPager scrolling when the user zooms into an image
      pvComic.setOnMatrixChangeListener(
          new PhotoViewAttacher.OnMatrixChangedListener() {
            @Override
            public void onMatrixChanged(RectF rectF) {
              if (pvComic.getScale() > 1.4) {
                mPager.setLocked(true);
              } else {
                mPager.setLocked(false);
              }
            }
          });

      container.addView(itemView);
      return itemView;
    }
 public RemoteInterface(Context context) {
   prefHelper_ = PrefHelper.getInstance(context);
 }
  /**
   * The main RESTful POST method. The others call this one with pre-populated parameters.
   *
   * @param body A {@link JSONObject} containing the main data body/payload of the request.
   * @param url A {@link String} URL to request from.
   * @param tag A {@link String} tag for logging/analytics purposes.
   * @param timeout An {@link Integer} value containing the number of milliseconds to wait before
   *     considering a server request to have timed out.
   * @param log A {@link Boolean} value that specifies whether debug logging should be enabled for
   *     this request or not.
   * @param linkData A {@link BranchLinkData} object containing the data dictionary associated with
   *     the link subject of the original server request.
   * @return A {@link ServerResponse} object representing the {@link HttpURLConnection} response in
   *     Branch SDK terms.
   */
  private ServerResponse make_restful_post(
      JSONObject body,
      String url,
      String tag,
      int timeout,
      int retryNumber,
      boolean log,
      BranchLinkData linkData) {
    HttpURLConnection connection = null;
    if (timeout <= 0) {
      timeout = DEFAULT_TIMEOUT;
    }
    try {
      JSONObject bodyCopy = new JSONObject();
      Iterator<?> keys = body.keys();
      while (keys.hasNext()) {
        String key = (String) keys.next();
        try {
          bodyCopy.put(key, body.get(key));
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }

      if (!addCommonParams(bodyCopy, retryNumber)) {
        return new ServerResponse(tag, NO_BRANCH_KEY_STATUS);
      }
      if (log) {
        PrefHelper.Debug("BranchSDK", "posting to " + url);
        PrefHelper.Debug("BranchSDK", "Post value = " + bodyCopy.toString(4));
      }
      URL urlObject = new URL(url);
      connection = (HttpURLConnection) urlObject.openConnection();
      connection.setConnectTimeout(timeout);
      connection.setReadTimeout(timeout);
      connection.setDoInput(true);
      connection.setDoOutput(true);
      connection.setRequestProperty("Content-Type", "application/json");
      connection.setRequestProperty("Accept", "application/json");
      connection.setRequestMethod("POST");

      OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream());
      outputStreamWriter.write(bodyCopy.toString());
      outputStreamWriter.flush();

      if (connection.getResponseCode() >= HttpURLConnection.HTTP_INTERNAL_ERROR
          && retryNumber < prefHelper_.getRetryCount()) {
        try {
          Thread.sleep(prefHelper_.getRetryInterval());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        retryNumber++;
        return make_restful_post(bodyCopy, url, tag, timeout, retryNumber, log, linkData);
      } else {
        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK
            && connection.getErrorStream() != null) {
          return processEntityForJSON(
              connection.getErrorStream(), connection.getResponseCode(), tag, log, linkData);
        } else {
          return processEntityForJSON(
              connection.getInputStream(), connection.getResponseCode(), tag, log, linkData);
        }
      }

    } catch (SocketException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (UnknownHostException ex) {
      if (log)
        PrefHelper.Debug(getClass().getSimpleName(), "Http connect exception: " + ex.getMessage());
      return new ServerResponse(tag, NO_CONNECTIVITY_STATUS);
    } catch (Exception ex) {
      if (log) PrefHelper.Debug(getClass().getSimpleName(), "Exception: " + ex.getMessage());
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
        if (ex instanceof NetworkOnMainThreadException)
          Log.i(
              "BranchSDK",
              "Branch Error: Don't call our synchronous methods on the main thread!!!");
      }
      return new ServerResponse(tag, 500);
    } finally {
      if (connection != null) {
        connection.disconnect();
      }
    }
  }
 /**
  * Provides the complete url for executing this request. URl consist of API base url and request
  * path. Child class need to extend this method if they need to add specific items to the url
  *
  * @return A url for executing this request against the server.
  */
 public String getRequestUrl() {
   return prefHelper_.getAPIBaseUrl() + requestPath_;
 }