Java tutorial
/******************************************************************************* * [y] hybris Platform * * Copyright (c) 2000-2013 hybris AG * All rights reserved. * * This software is the confidential and proprietary information of hybris * ("Confidential Information"). You shall not disclose such Confidential * Information and shall use it only in accordance with the terms of the * license agreement you entered into with hybris. ******************************************************************************/ package com.hybris.mobile.activity; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Arrays; import java.util.Hashtable; import org.apache.commons.lang3.StringUtils; import android.app.DialogFragment; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.Ndef; import android.os.Bundle; import android.os.Handler; import android.text.Html; import android.text.Spannable; import android.text.method.LinkMovementMethod; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.Gallery; import android.widget.RatingBar; import android.widget.ShareActionProvider; import android.widget.TextView; import android.widget.Toast; import com.hybris.mobile.DataConstants; import com.hybris.mobile.Hybris; import com.hybris.mobile.InternalConstants; import com.hybris.mobile.R; import com.hybris.mobile.WebserviceMethodEnums; import com.hybris.mobile.adapter.GalleryAdapter; import com.hybris.mobile.fragment.ClassificationListFragment; import com.hybris.mobile.fragment.QuantityDialogFragment; import com.hybris.mobile.fragment.QuantityDialogFragment.QuantityDialogListener; import com.hybris.mobile.fragment.ReviewDialogFragment; import com.hybris.mobile.fragment.TextDialogFragment; import com.hybris.mobile.loader.RESTLoader; import com.hybris.mobile.loader.RESTLoaderObserver; import com.hybris.mobile.loader.RESTLoaderResponse; import com.hybris.mobile.logging.LoggingUtils; import com.hybris.mobile.model.product.Product; import com.hybris.mobile.model.product.ProductStockLevelStatus; import com.hybris.mobile.nfc.NFCUtil; import com.hybris.mobile.query.QueryCart; import com.hybris.mobile.query.QuerySingleProduct; import com.hybris.mobile.utility.JsonUtils; import com.hybris.mobile.utility.MenuUtil; import com.hybris.mobile.utility.RegexUtil; import com.hybris.mobile.utility.StringUtil; public abstract class AbstractProductDetailActivity extends HybrisActivity implements QuantityDialogListener, RESTLoaderObserver { private static final String LOG_TAG = AbstractProductDetailActivity.class.getSimpleName(); private int quantityToAddToCart = 1; protected final Handler mHandler = new Handler(); protected Product mProduct; protected ShareActionProvider mShareActionProvider; // Required for Action menu handling @Override public boolean onOptionsItemSelected(MenuItem item) { boolean handled = super.onOptionsItemSelected(item); if (!handled) { // Put custom menu items handlers here switch (item.getItemId()) { // NFC writing is for debug use only case R.id.write_tag: if (NFCUtil.canNFC(this)) { Intent writeIntent = new Intent(this, NFCWriteActivity.class); NdefMessage msg = getNDEF(mProduct.getCode()); writeIntent.putExtra(NFCWriteActivity.NDEF_MESSAGE, msg); startActivity(writeIntent); } else { Toast.makeText(this, R.string.error_nfc_not_supported, Toast.LENGTH_LONG).show(); } return true; case R.id.share: try { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, mProduct.getName() + " - " + getString(R.string.nfc_url, URLEncoder.encode(mProduct.getCode(), "UTF-8"))); sendIntent.setType("text/plain"); startActivity(Intent.createChooser(sendIntent, getString(R.string.share_dialog_title))); } catch (UnsupportedEncodingException e) { LoggingUtils.e(LOG_TAG, "Error trying to encode product code to UTF-8. " + e.getLocalizedMessage(), Hybris.getAppContext()); } return true; default: return false; } } return handled; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate menu MenuUtil.onCreateProductDetailsOptionsMenu(menu, this); menu.removeItem(R.id.search); if (!getResources().getBoolean(R.bool.nfc_write_enabled)) { menu.removeItem(R.id.write_tag); } // Locate MenuItem with ShareActionProvider MenuItem item = menu.findItem(R.id.share); // Fetch and store ShareActionProvider setShareActionProvider((ShareActionProvider) item.getActionProvider()); return true; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.product_detail); // Allow links in promotions label TextView promotionsTextView = (TextView) findViewById(R.id.textViewPromotion); promotionsTextView.setMovementMethod(LinkMovementMethod.getInstance()); } /** * Handle incoming intents. Do not load a product if we already have one. */ @Override protected void onResume() { super.onResume(); String[] options = { InternalConstants.PRODUCT_OPTION_BASIC, InternalConstants.PRODUCT_OPTION_CATEGORIES, InternalConstants.PRODUCT_OPTION_CLASSIFICATION, InternalConstants.PRODUCT_OPTION_DESCRIPTION, InternalConstants.PRODUCT_OPTION_GALLERY, InternalConstants.PRODUCT_OPTION_PRICE, InternalConstants.PRODUCT_OPTION_PROMOTIONS, InternalConstants.PRODUCT_OPTION_REVIEW, InternalConstants.PRODUCT_OPTION_STOCK, InternalConstants.PRODUCT_OPTION_VARIANT }; String productCode = null; Intent intent = getIntent(); // Direct Call if (intent.hasExtra(DataConstants.PRODUCT_CODE)) //direct call from search list for example { productCode = intent.getStringExtra(DataConstants.PRODUCT_CODE); } // NFC Call else if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) //NFC { Tag tag = getIntent().getExtras().getParcelable(NfcAdapter.EXTRA_TAG); Ndef ndef = Ndef.get(tag); NdefMessage message = ndef.getCachedNdefMessage(); NdefRecord record = message.getRecords()[0]; if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(record.getType(), NdefRecord.RTD_URI)) { productCode = RegexUtil .getProductCode(new String(record.getPayload(), 1, record.getPayload().length - 1)); } } // Call from another application (QR Code) else if (StringUtils.equals(intent.getAction(), Intent.ACTION_VIEW)) { productCode = RegexUtil.getProductCode(intent.getDataString()); } if (StringUtils.isNotEmpty(productCode)) { this.enableAndroidBeam(productCode); } // Only load if we don't have a product already if (mProduct == null) { populateProduct(productCode, options); } invalidateOptionsMenu(); } /** * Enables Android Beam based NFC Sharing for the specified product code * * @param id */ private void enableAndroidBeam(String productCode) { if (NFCUtil.canNFC(this)) { NdefMessage msg = getNDEF(productCode); NfcAdapter.getDefaultAdapter(this).setNdefPushMessage(msg, this); } } /** * Get the NDEF for a product code * * @param productCode * @return */ private NdefMessage getNDEF(String productCode) { NdefMessage msg = null; try { NdefRecord uriRecord; uriRecord = NdefRecord.createUri(getString(R.string.nfc_url, URLEncoder.encode(productCode, "UTF-8"))); NdefRecord appRecord = NdefRecord.createApplicationRecord(getPackageName()); msg = new NdefMessage(new NdefRecord[] { uriRecord, appRecord }); } catch (UnsupportedEncodingException e) { LoggingUtils.e(LOG_TAG, "Error trying to encode product code to UTF-8. " + e.getLocalizedMessage(), Hybris.getAppContext()); } return msg; } /** * Populates the mProduct with the options given, replacing the current mProduct object * * @param productCode * @param options * @param startTimeOrZero * if != 0, it will be used to display the progress dialog for a minimum time (1s) */ private void populateProduct(String productCode, String[] options) { showLoadingDialog(true); QuerySingleProduct query = new QuerySingleProduct(); query.setProductCode(productCode); query.setOptions(options); RESTLoader.execute(this, WebserviceMethodEnums.METHOD_GET_PRODUCT_WITH_CODE, query, this, true, false); } /** * Show an image in a new activity * * @param position * the index of the image */ private void viewImage(int position) { Intent viewImage = new Intent(this, ImageZoomActivity.class); Hashtable<String, String> urls = mProduct.getGalleryImageURLs().get(position); viewImage.putExtra("url", urls.get("zoom")); startActivity(viewImage); } /** * Refresh the UI with data from the product */ public void updateUI() { // Title this.setTitle(mProduct.getName()); // Images if (mProduct.getGalleryImageURLs() != null) { GalleryAdapter adapter = new GalleryAdapter(this, mProduct.getGalleryImageURLs()); Gallery gallery = (Gallery) findViewById(R.id.galleryImages); gallery.setAdapter(adapter); // Set the onClick listener for the gallery gallery.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) { viewImage(position); } }); } // Reviews TextView reviewTextView = (TextView) findViewById(R.id.textViewReviews); reviewTextView.setText(this.getResources().getString(R.string.show_reviews, mProduct.getReviews().size())); // Rating (stars) RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBarRating); if (mProduct.getAverageRating() != null) { ratingBar.setRating(mProduct.getAverageRating().floatValue()); } // Promotions TextView promotionsTextView = (TextView) findViewById(R.id.textViewPromotion); if (mProduct.getPotentialPromotions().size() == 0) { promotionsTextView.setVisibility(View.GONE); } else { if (mProduct.getPotentialPromotions() != null && !mProduct.getPotentialPromotions().isEmpty()) { promotionsTextView.setText( Html.fromHtml(Product.generatePromotionString(mProduct.getPotentialPromotions().get(0)))); StringUtil.removeUnderlines((Spannable) promotionsTextView.getText()); } } TextView priceTextView = (TextView) findViewById(R.id.textViewPrice); priceTextView.setText(mProduct.getPrice().getFormattedValue()); // Description TextView descriptionTextView = (TextView) findViewById(R.id.textViewDescription); descriptionTextView.setText(mProduct.getDescription()); // Stock level TextView stockLevelTextView = (TextView) findViewById(R.id.textViewStockLevel); String stockLevelText = mProduct.getStockLevelText(Hybris.getAppContext()); if (mProduct.getStock().getStockLevel() > 0) { stockLevelText = mProduct.getStock().getStockLevel() + " " + mProduct.getStockLevelText(Hybris.getAppContext()).toLowerCase(); } stockLevelTextView.setText(stockLevelText); // Disable / Enable the add to cart button Button addToCartButton = (Button) findViewById(R.id.buttonAddToCart); Button quantityButton = (Button) findViewById(R.id.quantityButton); quantityButton.setText(getString(R.string.quantity_button, quantityToAddToCart)); try { if (mProduct.getStock().getStockLevelStatus() != null && StringUtils.equalsIgnoreCase(mProduct.getStock().getStockLevelStatus().getCode(), ProductStockLevelStatus.CODE_OUT_OF_STOCK)) { addToCartButton.setEnabled(false); quantityButton.setEnabled(false); quantityButton.setText(R.string.quantity); } else { addToCartButton.setEnabled(true); quantityButton.setEnabled(true); } } catch (Exception e) { } invalidateOptionsMenu(); } /** * Show the reviews in a new activity * * @param view */ public void showReviews(View view) { DialogFragment fragment = ReviewDialogFragment.newInstance(mProduct, this); fragment.show(getFragmentManager(), "review_fragment"); } /** * Add the product to the cart and reload to refresh data (e.g. promotions may change) * * @param view */ public void addToCart(final View view) { QueryCart queryCart = new QueryCart(); queryCart.setProductCode(mProduct.getCode()); queryCart.setQuantity(quantityToAddToCart); showLoadingDialog(true); RESTLoader.execute(this, WebserviceMethodEnums.METHOD_ADD_PRODUCT_TO_CART, queryCart, this, true, false); } /** * Show the description in a dialog * * @param view */ public void showDescription(View view) { DialogFragment fragment = TextDialogFragment.newInstance(getString(R.string.generic_title_description), mProduct.getDescription(), this); fragment.show(getFragmentManager(), "text_fragment"); } /** * Show more information in a dialog * * @param view */ public void showMoreInformation(View view) { DialogFragment fragment = ClassificationListFragment.newInstance(getString(R.string.more_information_label), mProduct.getClassifications(), this); fragment.show(getFragmentManager(), "classification_fragment"); } /** * Show delivery information in a dialog * * @param view */ public void showDeliveryInformation(View view) { DialogFragment fragment = TextDialogFragment.newInstance(getString(R.string.delivery_information_label), "", this); fragment.show(getFragmentManager(), "text_fragment"); } /** * Show a number picker in a dialog * * @param view */ public void showQuantityPicker(View view) { // Get the quantity if (mProduct.getStock().getStockLevel() > 0) { // Create and show the picker DialogFragment fragment = QuantityDialogFragment.newInstance(quantityToAddToCart, mProduct.getStock().getStockLevel(), this); fragment.show(getFragmentManager(), "quantity_fragment"); } } /** * Callback from quantity picker dialog */ @Override public void onFinishDialog(int quantity) { quantityToAddToCart = quantity; Button quantityButton = (Button) findViewById(R.id.quantityButton); quantityButton.setText(getString(R.string.quantity_button, quantity)); } public ShareActionProvider getShareActionProvider() { return mShareActionProvider; } public void setShareActionProvider(ShareActionProvider mShareActionProvider) { this.mShareActionProvider = mShareActionProvider; } @Override public void onReceiveResult(RESTLoaderResponse restLoaderResponse, WebserviceMethodEnums webserviceEnumMethod) { if (restLoaderResponse.getCode() == RESTLoaderResponse.SUCCESS) { String jsonResult = restLoaderResponse.getData(); switch (webserviceEnumMethod) { case METHOD_ADD_PRODUCT_TO_CART: ProductStockLevelStatus productStockLevelStatus = JsonUtils.fromJson(jsonResult, ProductStockLevelStatus.class); String errMsgToShow = null; if (StringUtils.equals(productStockLevelStatus.getStatusCode(), "success")) { // Repopulate the product String[] options = { InternalConstants.PRODUCT_OPTION_PROMOTIONS }; populateProduct(mProduct.getCode(), options); MenuUtil.setCartEmpty(false); } else { showLoadingDialog(false); errMsgToShow = getString(R.string.productDetails_couldNotAddToCart); if (StringUtils.endsWithIgnoreCase(productStockLevelStatus.getStatusCode(), "noStock")) { errMsgToShow += " (" + getString(R.string.stock_details_out_of_stock) + ")"; } else { errMsgToShow += " (" + productStockLevelStatus.getStatusCode() + ")"; } Toast.makeText(getApplicationContext(), errMsgToShow, Toast.LENGTH_SHORT).show(); invalidateOptionsMenu(); } break; case METHOD_GET_PRODUCT_WITH_CODE: showLoadingDialog(false); Product product = JsonUtils.fromJson(jsonResult, Product.class); product.populate(); if (mProduct == null) { mProduct = product; } else { mProduct.addDetails(product); } updateUI(); default: break; } } else if (restLoaderResponse.getCode() == RESTLoaderResponse.ERROR) { switch (webserviceEnumMethod) { case METHOD_GET_PRODUCT_WITH_CODE: showLoadingDialog(false); Toast.makeText(getApplicationContext(), R.string.error_product_not_found, Toast.LENGTH_LONG).show(); break; default: break; } } } }