uk.org.downiesoft.slideshow.SlideShowActivity.java Source code

Java tutorial

Introduction

Here is the source code for uk.org.downiesoft.slideshow.SlideShowActivity.java

Source

/* 
 Copyright 2014-2016 Alan G. Downie
    
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
    
 http://www.apache.org/licenses/LICENSE-2.0
    
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
package uk.org.downiesoft.slideshow;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import android.view.Window;
import android.view.WindowManager;

public class SlideShowActivity extends Activity {

    public static final String TAG = SlideShowActivity.class.getName();
    public static final String ACTION_STOP_WALLPAPER = TAG + ".stopWallpaper";
    public static final int REQUEST_BROWSER = 1024;
    public static final int REQUEST_FAVOURITES = 1025;
    public static final int REQUEST_SLIDESHOW = 1026;

    private static final int PERMISSION_ACCESS_EXTERNAL_STORAGE = 1;

    public static final Executor THREAD_POOL_EXECUTOR = Executors.newCachedThreadPool();

    public static int sDebug;

    private SharedPreferences mSlideshowSettings;
    private ThumbnailCacheManager mCacheManager;
    private GridViewFragment mGridViewFragment;
    private PreviewFragment mPreviewFragment;
    private ImageView mPreviewButton;
    private GestureDetector mGestureDetector;
    private FrameLayout mPreviewView;
    private boolean mPreviewVisible;
    /** UIHider to manage immersive view changes. */
    private UiHider mUiHider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window win = getWindow();
        win.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        win.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        win.requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
        mUiHider = new UiHider(this);
        getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(mUiHider);
        mCacheManager = ThumbnailCacheManager.getInstance(this);
        SlideShowActivity.debug(1, TAG, "onCreate: %s",
                savedInstanceState == null ? "null" : savedInstanceState.toString());
        setContentView(R.layout.activity_slide_show);
        PreferenceManager.setDefaultValues(this, R.xml.view_preferences, false);
        PreferenceManager.setDefaultValues(this, R.xml.slideshow_preferences, false);
        PreferenceManager.setDefaultValues(this, R.xml.cache_preferences, false);
        PreferenceManager.setDefaultValues(this, R.xml.wallpaper_preferences, false);
        PreferenceManager.setDefaultValues(this, R.xml.other_preferences, false);
        mSlideshowSettings = PreferenceManager.getDefaultSharedPreferences(this);
        int thumbSize = Integer.parseInt(mSlideshowSettings.getString(getString(R.string.PREFS_THUMBSIZE), "1"));
        // Hack to convert old hard-coded thumbsize settings to platform dependent sizes
        if (thumbSize > 2) {
            thumbSize = thumbSize / 90;
            SharedPreferences.Editor editor = mSlideshowSettings.edit();
            editor.putString(getString(R.string.PREFS_THUMBSIZE), Integer.toString(thumbSize));
            editor.apply();
        }
        FragmentManager fm = getFragmentManager();
        int cacheLimit = Integer
                .parseInt(mSlideshowSettings.getString(getString(R.string.PREFS_CACHE_LIMIT), "10"));
        mPreviewButton = (ImageView) findViewById(R.id.slideShowImageButton);
        mPreviewView = (FrameLayout) findViewById(R.id.previewContainer);
        RelativeLayout divider = (RelativeLayout) findViewById(R.id.frameDivider);
        if (divider != null) {
            divider.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent event) {
                    return mGestureDetector.onTouchEvent(event) || view.onTouchEvent(event);
                }
            });
        }
        mPreviewFragment = (PreviewFragment) fm.findFragmentByTag(PreviewFragment.TAG);
        if (mPreviewView != null && mPreviewFragment == null) {
            mPreviewFragment = new PreviewFragment();
            fm.beginTransaction().replace(R.id.previewContainer, mPreviewFragment, PreviewFragment.TAG).commit();
        }
        mGridViewFragment = (GridViewFragment) fm.findFragmentByTag(GridViewFragment.TAG);
        if (mGridViewFragment == null) {
            mGridViewFragment = new GridViewFragment();
            FragmentTransaction ft = fm.beginTransaction();
            ft.replace(R.id.fragmentContainer, mGridViewFragment, GridViewFragment.TAG);
            ft.commit();
        }
        mGestureDetector = new GestureDetector(this, new DividerGestureListener());
        // restart/stop service as required
        Intent intent = getIntent();
        if (intent != null && intent.getAction() != null && intent.getAction().equals(ACTION_STOP_WALLPAPER)
                && isServiceRunning()) {
            stopWallpaperService();
            finish();
        } else {
            if (!mSlideshowSettings.getBoolean(getString(R.string.PREFS_WALLPAPER_ENABLE), false)) {
                if (isServiceRunning()) {
                    stopWallpaperService();
                }
            } else {
                if (!isServiceRunning()) {
                    Intent startIntent = new Intent(SlideShowActivity.this, WallpaperService.class);
                    startService(startIntent);
                    invalidateOptionsMenu();
                }
            }
        }
        mCacheManager.tidyCache(cacheLimit);
        BitmapManager.setDisplayMetrics(getResources().getDisplayMetrics());
    }

    @Override
    public void onNewIntent(Intent intent) {
        if (intent != null && intent.getAction() != null && intent.getAction().equals(ACTION_STOP_WALLPAPER)
                && isServiceRunning()) {
            BitmapManager.setWallpaper(this, null);
            stopWallpaperService();
        }

    }

    @Override
    public void onStart() {
        SlideShowActivity.debug(1, TAG, "onStart");
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mPreviewVisible = mSlideshowSettings.getBoolean(getString(R.string.PREFS_SHOW_PREVIEW), true);
        sDebug = Integer.parseInt(mSlideshowSettings.getString(getString(R.string.PREFS_DEBUG_LEVEL), "0"));
        showPreview(mPreviewVisible);
        mUiHider.showUi(true);
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        String[] permissions = new String[] { Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE };
        ArrayList<String> notGranted = new ArrayList<>(2);
        for (String p : permissions) {
            if (ContextCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED) {
                notGranted.add(p);
            }
        }
        if (notGranted.size() > 0) {
            final String[] required = notGranted.toArray(permissions);
            boolean explain = false;
            for (String r : required) {
                explain |= ActivityCompat.shouldShowRequestPermissionRationale(this, r);
            }
            if (explain) {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Access External Storage");
                builder.setMessage("Needed to access photo albums and favourite lists on SD card");
                builder.setPositiveButton(R.string.text_ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(SlideShowActivity.this, required,
                                PERMISSION_ACCESS_EXTERNAL_STORAGE);
                    }
                });
            } else {
                ActivityCompat.requestPermissions(SlideShowActivity.this, required,
                        PERMISSION_ACCESS_EXTERNAL_STORAGE);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
            @NonNull int[] grantResults) {
        switch (requestCode) {
        case PERMISSION_ACCESS_EXTERNAL_STORAGE: {
            if (grantResults.length < 0) {
                boolean granted = true;
                for (int result : grantResults) {
                    granted &= result != PackageManager.PERMISSION_GRANTED;
                }
                if (!granted) {
                    Toast.makeText(this, R.string.text_exit_app, Toast.LENGTH_LONG).show();
                    finish();
                }
            }
        }
        }
    }

    @Override
    public void onStop() {
        SlideShowActivity.debug(1, TAG, "onStop");
        super.onStop();
    }

    @Override
    public void onDestroy() {
        SlideShowActivity.debug(1, TAG, "onDestroy");
        super.onDestroy();
        if (mCacheManager != null) {
            mCacheManager.close();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.slideshow_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_settings: {
            Intent intent = new Intent(this, SettingsActivity.class);
            this.startActivity(intent);
            return true;
        }
        case R.id.action_clear_wallpaper:
            BitmapManager.setWallpaper(this, null);
            Toast.makeText(this, R.string.text_wallpaper_cleared, Toast.LENGTH_SHORT).show();
            if (isServiceRunning()) {
                stopWallpaperService();
            }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        debug(1, TAG, "onBackPressed");
        mUiHider.showUi(true);
        if (mGridViewFragment != null) {
            if (mGridViewFragment.offerBackKeyEvent()) {
                return;
            }
        }
        invalidateOptionsMenu();
        if (mSlideshowSettings.getBoolean(getString(R.string.PREFS_WALLPAPER_CLEAR_ON_EXIT), true)) {
            if (isServiceRunning()) {
                stopWallpaperService();
            }
        }
        super.onBackPressed();
    }

    public void showPreview(boolean aIsVisible) {
        if (mPreviewFragment != null) {
            mPreviewFragment.addGlobalLayoutListener();
            Drawable button;
            if (aIsVisible) {
                mPreviewView.setVisibility(View.VISIBLE);
                button = ContextCompat.getDrawable(this, R.drawable.ic_action_collapse);
            } else {
                mPreviewView.setVisibility(View.GONE);
                button = ContextCompat.getDrawable(this, R.drawable.ic_action_expand);
            }
            if (button != null && mPreviewButton != null) {
                mPreviewButton.setImageDrawable(button);
            }
            mPreviewView.requestLayout();
            if (mGridViewFragment != null) {
                mGridViewFragment.setGridChoiceMode();
            }
            SharedPreferences.Editor editor = mSlideshowSettings.edit();
            editor.putBoolean(getString(R.string.PREFS_SHOW_PREVIEW), aIsVisible);
            editor.apply();
        }
    }

    public boolean isServiceRunning() {
        return WallpaperService.isServiceRunning(this);
    }

    public void stopWallpaperService() {
        if (isServiceRunning()) {
            WallpaperService.stopWallpaperService(this);
            invalidateOptionsMenu();
            Toast.makeText(this, R.string.text_service_stopped, Toast.LENGTH_SHORT).show();
        }
        finish();
    }

    /**
     * Gesture listener to handle fling and tap gestures on the divider bar between preview and grid views
     */
    private class DividerGestureListener extends SimpleOnGestureListener {

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            float dx = e2.getX() - e1.getX();
            float dy = e2.getY() - e1.getY();
            int orientation = getResources().getConfiguration().orientation;
            switch (orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                if (Math.abs(dx) > 2 * Math.abs(dy)) {
                    if (mPreviewVisible && dx < 0 || !mPreviewVisible && dx > 0) {
                        showPreview(mPreviewVisible = !mPreviewVisible);
                    }
                    return true;
                }
                return false;
            case Configuration.ORIENTATION_PORTRAIT:
                if (Math.abs(dy) > 2 * Math.abs(dx)) {
                    if (mPreviewVisible && dy < 0 || !mPreviewVisible && dy > 0) {
                        showPreview(mPreviewVisible = !mPreviewVisible);
                    }
                    return true;
                }
                return false;
            default:
                return false;
            }
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            showPreview(mPreviewVisible = !mPreviewVisible);
            return true;
        }

    }

    public static void debug(int aLevel, String tag, String format, Object... params) {
        if (aLevel <= sDebug) {
            Log.d(tag, String.format(format, params));
        }
    }

}