diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2016-03-30 17:50:36 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-03-31 13:00:41 +0200 |
commit | f8b35b0fe546c9f34626155f19dafe16a8f82829 (patch) | |
tree | ceb16a90ea3dcdb5a3adad6da58c11fb8e54f522 /platform/android/example/app/src/main/java | |
parent | d68576c3785572c1f5d41f83015b8fe6bbcbe9e8 (diff) | |
download | mupdf-f8b35b0fe546c9f34626155f19dafe16a8f82829.tar.xz |
android: Add new example viewer.
Thanks to Fred Ross-Perry.
Diffstat (limited to 'platform/android/example/app/src/main/java')
5 files changed, 446 insertions, 0 deletions
diff --git a/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocActivity.java b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocActivity.java new file mode 100644 index 00000000..3fcb3064 --- /dev/null +++ b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocActivity.java @@ -0,0 +1,228 @@ +package com.artifex.mupdf.example; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.Resources; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.FileObserver; +import android.os.Handler; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; + +import java.io.File; +import java.io.FileFilter; +import java.util.Arrays; +import java.util.Comparator; + +public class ChooseDocActivity + extends Activity +{ + private ListView mListView; + private ChooseDocAdapter adapter; + static private File mDirectory; + static private File mStartingDirectory; + private File mParent; + private File[] mDirs; + private File[] mFiles; + private Handler mHandler; + private Runnable mUpdateFiles; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + setContentView(R.layout.choose_doc); + + mHandler = new Handler(); + + String storageState = Environment.getExternalStorageState(); + if (!Environment.MEDIA_MOUNTED.equals(storageState) && + !Environment.MEDIA_MOUNTED_READ_ONLY.equals(storageState)) + { + showMessage(getResources().getString(R.string.no_media_warning), + getResources().getString(R.string.no_media_hint), + getResources().getString(R.string.dismiss)); + + return; + } + + if (mDirectory == null) { + mDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + mStartingDirectory = mDirectory; // remember where we started + } + + // Create the list... + mListView = (ListView)findViewById(R.id.fileListView); + mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + onListItemClick(mListView, view, position, id); + } + }); + + // Create a list adapter... + adapter = new ChooseDocAdapter(getLayoutInflater()); + mListView.setAdapter(adapter); + + // ...that is updated dynamically when files are scanned + mUpdateFiles = new Runnable() { + public void run() { + Resources res = getResources(); + String appName = res.getString(R.string.app_name); + String version = res.getString(R.string.version); + String title = res.getString(R.string.picker_title_App_Ver_Dir); + setTitle(String.format(title, appName, version, mDirectory)); + + mParent = mDirectory.getParentFile(); + + mDirs = mDirectory.listFiles(new FileFilter() { + + public boolean accept(File file) { + return file.isDirectory(); + } + }); + if (mDirs == null) + mDirs = new File[0]; + + mFiles = mDirectory.listFiles(new FileFilter() { + + public boolean accept(File file) { + if (file.isDirectory()) + return false; + + String fname = file.getName().toLowerCase(); + + if (fname.endsWith(".pdf")) + return true; + if (fname.endsWith(".xps")) + return true; + if (fname.endsWith(".cbz")) + return true; + if (fname.endsWith(".epub")) + return true; + if (fname.endsWith(".png")) + return true; + if (fname.endsWith(".jpe")) + return true; + if (fname.endsWith(".jpeg")) + return true; + if (fname.endsWith(".jpg")) + return true; + if (fname.endsWith(".jfif")) + return true; + if (fname.endsWith(".jfif-tbnl")) + return true; + if (fname.endsWith(".tif")) + return true; + if (fname.endsWith(".tiff")) + return true; + + return false; + } + }); + if (mFiles == null) + mFiles = new File[0]; + + Arrays.sort(mFiles, new Comparator<File>() { + public int compare(File arg0, File arg1) { + return arg0.getName().compareToIgnoreCase(arg1.getName()); + } + }); + + Arrays.sort(mDirs, new Comparator<File>() { + public int compare(File arg0, File arg1) { + return arg0.getName().compareToIgnoreCase(arg1.getName()); + } + }); + + adapter.clear(); + + // add a button for going up one level + if (mParent != null) + if (!mDirectory.getAbsolutePath().equals(mStartingDirectory.getAbsolutePath())) + adapter.add(new ChooseDocItem(ChooseDocItem.Type.PARENT, getString(R.string.parent_directory), mParent.getAbsolutePath())); + + for (File f : mDirs) + adapter.add(new ChooseDocItem(ChooseDocItem.Type.DIR, f.getName(), f.getAbsolutePath())); + for (File f : mFiles) + adapter.add(new ChooseDocItem(ChooseDocItem.Type.DOC, f.getName(), f.getAbsolutePath())); + } + }; + + // Start initial file scan... + mHandler.post(mUpdateFiles); + + // ...and observe the directory and scan files upon changes. + FileObserver observer = new FileObserver(mDirectory.getPath(), FileObserver.CREATE | FileObserver.DELETE) { + public void onEvent(int event, String path) { + mHandler.post(mUpdateFiles); + } + }; + observer.startWatching(); + } + + private void onListItemClick(ListView l, View v, int position, long id) + { + ChooseDocItem item = (ChooseDocItem) v.getTag(); + File f = new File(item.path); + if (item.type== ChooseDocItem.Type.PARENT || item.type== ChooseDocItem.Type.DIR) + { + mDirectory = f; + mHandler.post(mUpdateFiles); + return; + } + + // start a viewing activity + Uri uri = Uri.parse(f.getAbsolutePath()); + Intent intent; + intent = new Intent(this, DocViewActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(uri); + startActivity(intent); + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + + // do another file scan to pick up changes to files since we were away + mHandler.post(mUpdateFiles); + } + + // this hides the activity + @Override + public void onBackPressed() { + moveTaskToBack (true); + } + + private void showMessage(final String title, final String body, final String okLabel) + { + final Activity activity = this; + runOnUiThread(new Runnable() { + @Override + public void run() { + new AlertDialog.Builder(activity) + .setTitle(title) + .setMessage(body) + .setCancelable(false) + .setPositiveButton(okLabel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } + }); + } +} diff --git a/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocAdapter.java b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocAdapter.java new file mode 100644 index 00000000..4b889a06 --- /dev/null +++ b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocAdapter.java @@ -0,0 +1,76 @@ +package com.artifex.mupdf.example; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.LinkedList; + +public class ChooseDocAdapter extends BaseAdapter { + private final LinkedList<ChooseDocItem> mItems; + private final LayoutInflater mInflater; + + public ChooseDocAdapter(LayoutInflater inflater) { + mInflater = inflater; + mItems = new LinkedList<ChooseDocItem>(); + } + + public void clear() { + mItems.clear(); + } + + public void add(ChooseDocItem item) { + mItems.add(item); + notifyDataSetChanged(); + } + + public int getCount() { + return mItems.size(); + } + + public Object getItem(int i) { + return null; + } + + public long getItemId(int arg0) { + return 0; + } + + private int iconForType(ChooseDocItem.Type type, String docName) + { + switch (type) + { + case PARENT: + return R.drawable.ic_explorer_up; + + case DIR: + return R.drawable.ic_explorer_fldr; + + case DOC: + return R.drawable.ic_explorer_any; + + default: + return 0; + } + } + + public View getView(int position, View convertView, ViewGroup parent) { + View v; + if (convertView == null) { + v = mInflater.inflate(R.layout.picker_entry, null); + } else { + v = convertView; + } + ChooseDocItem item = mItems.get(position); + ((TextView)v.findViewById(R.id.name)).setText(item.name); + ((ImageView)v.findViewById(R.id.icon)).setImageResource(iconForType(item.type, item.name)); + + v.setTag(item); + + return v; + } + +} diff --git a/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocItem.java b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocItem.java new file mode 100644 index 00000000..194db0f3 --- /dev/null +++ b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/ChooseDocItem.java @@ -0,0 +1,17 @@ +package com.artifex.mupdf.example; + +public class ChooseDocItem { + public enum Type { + PARENT, DIR, DOC + } + + final public Type type; + final public String name; + final public String path; + + public ChooseDocItem(Type t, String n, String p) { + type = t; + name = n; + path = p; + } +} diff --git a/platform/android/example/app/src/main/java/com/artifex/mupdf/example/DocViewActivity.java b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/DocViewActivity.java new file mode 100644 index 00000000..a0e989ff --- /dev/null +++ b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/DocViewActivity.java @@ -0,0 +1,105 @@ +package com.artifex.mupdf.example; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.artifex.mupdf.fitz.ColorSpace; +import com.artifex.mupdf.fitz.Document; +import com.artifex.mupdf.fitz.Matrix; +import com.artifex.mupdf.fitz.Page; +import com.artifex.mupdf.fitz.Pixmap; + +public class DocViewActivity extends Activity +{ + private int mPageCount; + private int mCurrentPage; + + Document mDocument; + Page mPage; + Bitmap mBitmap = null; + + ImageView mImageView; + TextView mTextView; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_doc_view); + + mImageView = (ImageView)findViewById(R.id.image_view); + mTextView = (TextView)findViewById(R.id.page_text); + + // load the doc + Uri uri = getIntent().getData(); + String path = Uri.decode(uri.getEncodedPath()); + mDocument = new Document(path); + mPageCount = mDocument.countPages(); + + // show the first page + mCurrentPage = 0; + displayCurrentPage(); + } + + public void onFirstPageButton(final View v) + { + mCurrentPage = 0; + displayCurrentPage(); + } + + public void onPreviousPageButton(final View v) + { + if (mCurrentPage > 0) + { + mCurrentPage--; + displayCurrentPage(); + } + } + + public void onNextPageButton(final View v) + { + if (mCurrentPage < mPageCount-1) + { + mCurrentPage++; + displayCurrentPage(); + } + } + + public void onLastPageButton(final View v) + { + mCurrentPage = mPageCount-1; + displayCurrentPage(); + } + + private void displayCurrentPage() + { + // report the page number + mTextView.setText(String.format("page %d of %d",mCurrentPage+1,mPageCount)); + + // get the page + mPage = mDocument.loadPage(mCurrentPage); + + // create a matrix that renders at 300 DPI + Matrix m = new Matrix(); + m.scale(300.0f/72.0f); + + // create a new bitmap for the page + Bitmap old = mBitmap; + Pixmap pixmap = mPage.toPixmap(m, ColorSpace.DeviceBGR); + mBitmap = Bitmap.createBitmap(pixmap.getWidth(), pixmap.getHeight(), Bitmap.Config.ARGB_8888); + int [] pixels = pixmap.getPixels(); + mBitmap.setPixels(pixels, 0, pixmap.getWidth(), 0, 0, pixmap.getWidth(), pixmap.getHeight()); + + // set the bitmap in the UI + mImageView.setImageBitmap(mBitmap); + + // recycle the old bitmap + if (old!=null) + old.recycle(); + } +} diff --git a/platform/android/example/app/src/main/java/com/artifex/mupdf/example/MainActivity.java b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/MainActivity.java new file mode 100644 index 00000000..b7aa39ca --- /dev/null +++ b/platform/android/example/app/src/main/java/com/artifex/mupdf/example/MainActivity.java @@ -0,0 +1,20 @@ +package com.artifex.mupdf.example; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +public class MainActivity extends Activity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + // just show the document chooser activity + Intent intent = new Intent(this, ChooseDocActivity.class); + startActivity(intent); + finish(); + } + +} |