Android Open Source - no-cloud-share Share Fragment






From Project

Back to project page no-cloud-share.

License

The source code is released under:

GNU General Public License

If you think the Android project no-cloud-share 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 de.ub0r.android.nocloudshare;
/*from  www . j a v  a 2 s.c o  m*/
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;

import org.jetbrains.annotations.NotNull;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ShareActionProvider;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import de.ub0r.android.logg0r.Log;
import de.ub0r.android.nocloudshare.http.BitmapLruCache;
import de.ub0r.android.nocloudshare.model.ShareItem;
import de.ub0r.android.nocloudshare.model.ShareItemContainer;
import de.ub0r.android.nocloudshare.views.MeasuringRelativeLayout;

/**
 * @author flx
 */
public class ShareFragment extends Fragment {

    private static final String TAG = "ShareFragment";

    // TODO customize width
    public static final String BARCODE_URL
            = "https://chart.googleapis.com/chart?cht=qr&chs=400x400&chl=";

    private RequestQueue mQueue;

    private BitmapLruCache mCache;

    private ImageLoader mLoader;

    private DateFormat mFormat;

    private boolean mViewOnly;

    private ShareItemContainer mContainer;

    private ShareItem mItem;

    private String mBaseUrl;

    private Intent mOpenIntent;

    private boolean mState;

    private Intent mIntent;

    @InjectView(R.id.url)
    TextView mUrlTextView;

    @InjectView(R.id.url_barcode)
    NetworkImageView mUrlImageView;

    @InjectView(R.id.item_creation)
    TextView mCreationTextView;

    @InjectView(R.id.item_expiration)
    TextView mExpirationTextView;

    @InjectView(R.id.shade)
    View mShadeView;

    public static ShareFragment getInstance(final Intent intent) {
        Bundle args = new Bundle();
        args.putParcelable("intent", intent);
        ShareFragment f = new ShareFragment();
        f.setArguments(args);
        return f;
    }

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mIntent = getArguments().getParcelable("intent");
        Log.d(TAG, "intent: ", mIntent);
        mViewOnly = Intent.ACTION_VIEW.equals(mIntent.getAction());
        mBaseUrl = HttpService.getBaseUrl(getActivity());
        mState = savedInstanceState != null && savedInstanceState.getBoolean("mState");

        mCache = BitmapLruCache.getDefaultBitmapLruCache(getActivity());
        mQueue = Volley.newRequestQueue(getActivity());
        mLoader = new ImageLoader(mQueue, mCache);
        mFormat = android.text.format.DateFormat.getTimeFormat(getActivity());
        mContainer = ShareItemContainer.getInstance(getActivity());
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
            final Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_share, container, false);
        ButterKnife.inject(this, v);

        // get list of shared items from intent
        // it's mostly only one item
        List<ShareItem> list = handleIntent(mIntent);
        if (list == null) {
            return v;
        }

        // create thumbnails
        createThumbnails(list);

        mItem = list.get(0);
        if (!mViewOnly) {
            mContainer.persist(getActivity());
            invalidateData(false);
        }

        if (getActivity() instanceof ShareActivity) {
            //noinspection ConstantConditions
            getActivity().getActionBar().setSubtitle(mItem.getName());
        }

        // trigger updateViews after measure layout again
        ((MeasuringRelativeLayout) mUrlImageView.getParent())
                .registerOnMeasureListener(new Runnable() {
                    @Override
                    public void run() {
                        updateViews();
                    }
                });

        setHasOptionsMenu(true);

        return v;
    }

    private List<ShareItem> handleIntent(final Intent i) {
        String action = i.getAction();
        String mimeType = i.getType();

        ArrayList<ShareItem> list = new ArrayList<ShareItem>();
        long expirationPeriod = SettingsActivity
                .getExpirationPeriod(PreferenceManager.getDefaultSharedPreferences(getActivity()));

        if (mViewOnly) {
            list.add(mContainer.find(i.getStringExtra(ShareActivity.EXTRA_HASH)));
        } else if (i.getStringExtra(Intent.EXTRA_HTML_TEXT) != null) {
            String name = i.getStringExtra(Intent.EXTRA_SUBJECT);
            if (name == null) {
                name = "text.html";
            } else {
                name = name.replace(" ", "_"); // fixme
            }
            @SuppressLint("InlinedApi")
            ShareItem item = new ShareItem(name, i.getStringExtra(Intent.EXTRA_HTML_TEXT),
                    "text/html");
            item.setExpireIn(expirationPeriod);
            mContainer.add(item);
            list.add(item);
        } else if (i.getStringExtra(Intent.EXTRA_TEXT) != null) {
            String name = i.getStringExtra(Intent.EXTRA_SUBJECT);
            if (name == null) {
                name = "text.txt";
            } else {
                name = name.replace(" ", "_"); // fixme
            }
            ShareItem item = new ShareItem(name, i.getStringExtra(Intent.EXTRA_TEXT), mimeType);
            item.setExpireIn(expirationPeriod);
            mContainer.add(item);
            list.add(item);
        } else if (i.getData() != null) {
            ShareItem item = mContainer.add(i.getData(), mimeType);
            item.setExpireIn(expirationPeriod);
            list.add(item);
        } else if (Intent.ACTION_SEND.equals(action)) {
            Uri u = i.getParcelableExtra(Intent.EXTRA_STREAM);
            if (u != null) {
                ShareItem item = mContainer.add(u, mimeType);
                item.setInfos(getActivity());
                item.setExpireIn(expirationPeriod);
                list.add(item);
            }
        } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) {
            List<Uri> uris = i.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
            if (uris != null) {
                for (Uri u : uris) {
                    ShareItem item = mContainer.add(u, mimeType);
                    item.setInfos(getActivity());
                    item.setExpireIn(expirationPeriod);
                    list.add(item);
                }
            }
        }

        if (list.size() == 0) {
            Log.e(TAG, "#list: 0, intent: ", mIntent);
            Toast.makeText(getActivity(), R.string.error_unknown, Toast.LENGTH_LONG).show();
            finishOrInvalidate();
            return null;
        }

        if (list.size() > 1) {
            // add index for collection
            ShareItem item = new ShareItem("index.html",
                    ShareItemContainer.buildIndex(getActivity(), list, mBaseUrl), "text/html");
            item.setExpireIn(expirationPeriod);
            list.add(0, item);
            mContainer.add(1 + mContainer.size() - list.size(), item);
        }
        return list;
    }

    private void createThumbnails(final List<ShareItem> list) {
        Log.d(TAG, "createThumbnails(#", list.size(), ")");
        for (ShareItem item : list) {
            String thumb = item.getThumbnailName();
            if (thumb == null) {
                Log.d(TAG, "thumb == null");
                continue;
            }
            if (mCache.contains(thumb)) {
                Log.d(TAG, "thumbnail already present: ", thumb);
                continue;
            }
            createThumbnail(item, thumb);
        }
    }

    private void createThumbnail(final ShareItem item, final String thumb) {
        Log.d(TAG, "createThumbnail(", item, ", ", thumb, ")");
        try {
            // get orig image size
            InputStream is = getActivity().getContentResolver().openInputStream(item.getUri());
            if (is == null) {
                return;
            }
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(is, null, o);

            // calculate scale
            int scale = 1;
            if (o.outHeight > ShareItem.THUMBNAIL_SIZE
                    || o.outWidth > ShareItem.THUMBNAIL_SIZE) {
                scale = (int) Math.pow(2, (int) Math.round(Math.log(ShareItem.THUMBNAIL_SIZE
                        / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
            }
            is.close();

            // decode image with scale
            is = getActivity().getContentResolver().openInputStream(item.getUri());
            o = new BitmapFactory.Options();
            o.inSampleSize = scale;
            Bitmap b = BitmapFactory.decodeStream(is, null, o);
            is.close();

            // put image into cache
            mCache.putBitmap(thumb, b);
        } catch (IOException e) {
            Log.e(TAG, "unable to create thumbnail", e);
        }
    }

    @Override
    public void onSaveInstanceState(@NotNull final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("mState", mState);
    }

    private void updateViews() {
        String url = mBaseUrl + mItem.getExternalPath();
        Log.i(TAG, "share url: ", url);
        String bcUrl = BARCODE_URL + Uri.encode(url);

        mUrlTextView.setText(url);
        mUrlImageView.setImageUrl(bcUrl, mLoader);

        Date creation = new Date(mItem.getCreation());
        mCreationTextView.setText(this.getString(R.string.creation_ts,
                mFormat.format(creation)));
        Date expiration = new Date(mItem.getExpiration());
        mExpirationTextView.setText(
                this.getString(R.string.expiration_ts, mFormat.format(expiration)));
        mExpirationTextView.setTextColor(this.getResources()
                .getColor(mItem.isExpired() ? R.color.expired : R.color.not_expired));

        // start with desired animation state
        if (mState) {
            float scale = getImageScale();
            mUrlImageView.setScaleX(scale);
            mUrlImageView.setScaleY(scale);
            mShadeView.setAlpha(1f);
        } else {
            mUrlImageView.setScaleX(1f);
            mUrlImageView.setScaleY(1f);
            mShadeView.setAlpha(0f);
        }
    }

    @Override
    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.activity_share, menu);
        // update remove/expire
        if (mItem == null) {
            menu.removeItem(R.id.action_expire);
            menu.removeItem(R.id.action_remove);
            return;
        }
        if (mItem.isExpired()) {
            menu.removeItem(R.id.action_expire);
        } else {
            menu.removeItem(R.id.action_remove);
        }

        // update open
        if (mItem.getUri() != null) {
            Intent intent = new Intent(Intent.ACTION_VIEW, mItem.getUri());
            if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
                mOpenIntent = intent;
            } else {
                mOpenIntent = null;
                menu.removeItem(R.id.action_open);
            }
        } else {
            mOpenIntent = null;
            menu.removeItem(R.id.action_open);
        }

        // update share
        MenuItem item = menu.findItem(R.id.action_share);
        assert item != null;
        ShareActionProvider sap = (ShareActionProvider) item.getActionProvider();
        assert sap != null;
        Intent intent = new Intent(Intent.ACTION_SEND);
        String url = mBaseUrl + mItem.getExternalPath();
        intent.putExtra(Intent.EXTRA_TEXT, url);
        intent.setType("text/plain");
        sap.setShareIntent(intent);
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                if (getActivity() instanceof ShareActivity) {
                    Intent i = new Intent(getActivity(), ShareListActivity.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(i);
                    finishOrInvalidate();
                    return true;
                } else {
                    return false;
                }
            case R.id.action_open:
                startActivity(mOpenIntent);
                return true;
            case R.id.action_extend:
                mItem.extend();
                mContainer.persist(getActivity());
                invalidateData(true);
                Toast.makeText(getActivity(), R.string.extended, Toast.LENGTH_LONG).show();
                return true;
            case R.id.action_expire:
                mItem.expire();
                mContainer.persist(getActivity());
                invalidateData(true);
                Toast.makeText(getActivity(), R.string.expired, Toast.LENGTH_LONG).show();
                return true;
            case R.id.action_remove:
                mContainer.remove(mItem);
                mContainer.persist(getActivity());
                Toast.makeText(getActivity(), R.string.removed, Toast.LENGTH_LONG).show();
                finishOrInvalidate();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @OnClick(R.id.url)
    void onUrlClick() {
        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
                Context.CLIPBOARD_SERVICE);
        cm.setPrimaryClip(
                ClipData.newPlainText(mItem.getName(), mBaseUrl + mItem.getExternalPath()));
        Toast.makeText(getActivity(), R.string.copied_to_clipboard, Toast.LENGTH_LONG).show();
    }

    @OnClick(R.id.url_barcode)
    void onBarcodeClick() {
        AnimatorSet set = new AnimatorSet();
        if (mState) {
            // animate close view
            set.playTogether(
                    ObjectAnimator.ofFloat(mShadeView, View.ALPHA, 0f),
                    ObjectAnimator.ofFloat(mUrlImageView, View.SCALE_X, 1f),
                    ObjectAnimator.ofFloat(mUrlImageView, View.SCALE_Y, 1f)
            );
        } else {
            // animate open view
            float scale = getImageScale();
            set.playTogether(
                    ObjectAnimator.ofFloat(mShadeView, View.ALPHA, 1f),
                    ObjectAnimator.ofFloat(mUrlImageView, View.SCALE_X, scale),
                    ObjectAnimator.ofFloat(mUrlImageView, View.SCALE_Y, scale)
            );
        }
        set.start();
        mState ^= true;
    }

    private float getImageScale() {
        float origSize = getResources().getDimensionPixelSize(R.dimen.share_barcode_size);
        int maxWidth;
        int maxHeight;
        MeasuringRelativeLayout parentView = (MeasuringRelativeLayout) mUrlImageView.getParent();
        maxWidth = parentView.getMeasuredWidth();
        maxHeight = parentView.getMeasuredHeight();
        if (maxWidth < origSize || maxHeight < origSize) {
            return 1f;
        }

        return Math.min(
                Math.min(maxWidth / origSize, maxHeight / origSize),
                3);
    }

    private void finishOrInvalidate() {
        if (getActivity() instanceof ShareActivity) {
            getActivity().finish();
        } else if (getActivity() instanceof ShareListActivity) {
            ((ShareListActivity) getActivity()).invalidateData();
        } else {
            throw new IllegalStateException("unknown activity: " + getActivity().getClass());
        }
    }

    private void invalidateData(final boolean updateViews) {
        if (updateViews) {
            updateViews();
        }
        if (getActivity() instanceof ShareActivity) {
            getActivity().invalidateOptionsMenu();
            HttpService.startService(getActivity());
        } else if (getActivity() instanceof ShareListActivity) {
            ((ShareListActivity) getActivity()).invalidateData();
        } else {
            throw new IllegalStateException("unknown activity: " + getActivity().getClass());
        }
    }

    public String getHash() {
        return mItem == null ? null : mItem.getHash();
    }
}




Java Source Code List

de.ub0r.android.nocloudshare.AboutActivity.java
de.ub0r.android.nocloudshare.HttpService.java
de.ub0r.android.nocloudshare.IntroActivity.java
de.ub0r.android.nocloudshare.SettingsActivity.java
de.ub0r.android.nocloudshare.ShareActivity.java
de.ub0r.android.nocloudshare.ShareFragment.java
de.ub0r.android.nocloudshare.ShareListActivity.java
de.ub0r.android.nocloudshare.http.BitmapLruCache.java
de.ub0r.android.nocloudshare.http.Httpd.java
de.ub0r.android.nocloudshare.model.GsonFactory.java
de.ub0r.android.nocloudshare.model.ShareItemContainer.java
de.ub0r.android.nocloudshare.model.ShareItem.java
de.ub0r.android.nocloudshare.views.CheckableRelativeLayout.java
de.ub0r.android.nocloudshare.views.MeasuringRelativeLayout.java
fi.iki.elonen.NanoHTTPD.java