diff --git a/app/build.gradle b/app/build.gradle
index 6d6317e..f08fdc8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -5,7 +5,7 @@ android {
buildToolsVersion "23.0.2"
defaultConfig {
- applicationId "com.csc.lesson5"
+ applicationId "ru.ppzh.filemanager"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
@@ -21,4 +21,5 @@ android {
dependencies {
compile 'com.android.support:appcompat-v7:23.2.1'
+ compile 'com.android.support:recyclerview-v7:23.2.1'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6296c85..5b2df16 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,8 @@
+ package="ru.ppzh.filemanager">
+
+
-
+
+
diff --git a/app/src/main/java/com/csc/lesson5/MainActivity.java b/app/src/main/java/com/csc/lesson5/MainActivity.java
deleted file mode 100644
index 613d372..0000000
--- a/app/src/main/java/com/csc/lesson5/MainActivity.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.csc.lesson5;
-
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-
-public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/app/src/main/java/ru/ppzh/filemanager/ImageLoader.java b/app/src/main/java/ru/ppzh/filemanager/ImageLoader.java
new file mode 100644
index 0000000..f2d7214
--- /dev/null
+++ b/app/src/main/java/ru/ppzh/filemanager/ImageLoader.java
@@ -0,0 +1,41 @@
+package ru.ppzh.filemanager;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+public class ImageLoader {
+
+ public Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {
+
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(path, options);
+
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeFile(path, options);
+ }
+
+ public int calculateInSampleSize(
+ BitmapFactory.Options options, int reqWidth, int reqHeight) {
+
+ final int height = options.outHeight;
+ final int width = options.outWidth;
+ int inSampleSize = 1;
+
+ if (height > reqHeight || width > reqWidth) {
+
+ final int halfHeight = height / 2;
+ final int halfWidth = width / 2;
+
+
+ while ((halfHeight / inSampleSize) > reqHeight
+ && (halfWidth / inSampleSize) > reqWidth) {
+ inSampleSize *= 2;
+ }
+ }
+
+ return inSampleSize;
+ }
+}
diff --git a/app/src/main/java/ru/ppzh/filemanager/ImageViewer.java b/app/src/main/java/ru/ppzh/filemanager/ImageViewer.java
new file mode 100644
index 0000000..df8ce42
--- /dev/null
+++ b/app/src/main/java/ru/ppzh/filemanager/ImageViewer.java
@@ -0,0 +1,31 @@
+package ru.ppzh.filemanager;
+
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Display;
+import android.widget.ImageView;
+
+public class ImageViewer extends AppCompatActivity {
+ private ImageView imageView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.image_viewer);
+ imageView = (ImageView) findViewById(R.id.image_viewer);
+
+ ImageLoader imageloader = new ImageLoader();
+ String imagePath = getIntent().getStringExtra(MainActivity.IMAGE_PATH);
+ Display display = getWindowManager().getDefaultDisplay();
+ Point size = new Point();
+ display.getSize(size);
+ Bitmap image = imageloader.decodeSampledBitmapFromFile(
+ imagePath,
+ size.x,
+ size.y
+ );
+ imageView.setImageBitmap(image);
+ }
+}
diff --git a/app/src/main/java/ru/ppzh/filemanager/Item.java b/app/src/main/java/ru/ppzh/filemanager/Item.java
new file mode 100644
index 0000000..67aa6a6
--- /dev/null
+++ b/app/src/main/java/ru/ppzh/filemanager/Item.java
@@ -0,0 +1,97 @@
+package ru.ppzh.filemanager;
+
+
+import android.graphics.Bitmap;
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+public class Item implements Comparable- {
+ public static final String TAG = "Item";
+
+ private String name;
+ private String date;
+ private String path;
+ private Bitmap preview;
+ private boolean isDirectory;
+
+ public Item(String name, String date, String path, Bitmap preview, boolean isDirectory) {
+ this.name = name;
+ this.date = date;
+ this.path = path;
+ this.preview = preview;
+ this.isDirectory = isDirectory;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public Bitmap getPreview() {
+ return preview;
+ }
+
+ public boolean isDirectory() {
+ return isDirectory;
+ }
+
+ public int compareTo(@NonNull Item o) {
+ if (this.name != null)
+ return this.name.toLowerCase().compareTo(o.getName().toLowerCase());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public String getExtension() {
+ int index = name.lastIndexOf('.');
+ String extension = name.substring(index);
+
+ Log.i(TAG, extension);
+
+ return extension;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Item)) return false;
+
+ Item item = (Item) o;
+
+ if (isDirectory() != item.isDirectory()) return false;
+ if (!getName().equals(item.getName())) return false;
+ if (!getDate().equals(item.getDate())) return false;
+ if (!getPath().equals(item.getPath())) return false;
+ return getPreview().equals(item.getPreview());
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getName().hashCode();
+ result = 31 * result + getDate().hashCode();
+ result = 31 * result + getPath().hashCode();
+ result = 31 * result + getPreview().hashCode();
+ result = 31 * result + (isDirectory() ? 1 : 0);
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/ppzh/filemanager/MainActivity.java b/app/src/main/java/ru/ppzh/filemanager/MainActivity.java
new file mode 100644
index 0000000..c7cd539
--- /dev/null
+++ b/app/src/main/java/ru/ppzh/filemanager/MainActivity.java
@@ -0,0 +1,346 @@
+package ru.ppzh.filemanager;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.MenuItem;
+import android.view.View;
+import android.webkit.MimeTypeMap;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+public class MainActivity extends AppCompatActivity {
+ public static final String TAG = "MainActivity";
+ public static final String IMAGE_PATH = "ru.ppzh.image_path";
+ public static final String CURRENT_FOLDER_PATH = "ru.ppzh.current_folder_path";
+ public static final int FILE_IMAGE_PREVIEW_DIMENSION = 50;
+
+ private RecyclerView mRecyclerView;
+ private RecyclerAdapter mAdapter;
+ private RecyclerView.LayoutManager mLayoutManager;
+ private File currentFolder;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main_activity);
+ mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
+ mRecyclerView.setHasFixedSize(true);
+ mLayoutManager = new LinearLayoutManager(this);
+ mRecyclerView.setLayoutManager(mLayoutManager);
+
+ //Log.i(TAG, Environment.getExternalStorageState());
+
+ // For now it works only with embedded external storage
+ // TODO add ability to explore sd card filesystem
+
+ if (isExternalStorageAccessable()) {
+ if (savedInstanceState != null) {
+ String path = savedInstanceState.getString(CURRENT_FOLDER_PATH);
+
+ //Log.i(TAG, "Restore currentFolder, path: " + path);
+
+ currentFolder = new File(path);
+ } else {
+ currentFolder = Environment.getExternalStorageDirectory();
+ }
+ } else {
+ currentFolder = new File("", getString(R.string.no_storage));
+ }
+
+ mAdapter = new RecyclerAdapter(getFiles(currentFolder), this);
+ mRecyclerView.setAdapter(mAdapter);
+
+ mRecyclerView.addOnItemTouchListener(
+ new RecyclerItemClickListener(this,
+ new RecyclerItemClickListener.OnItemClickListener() {
+ @Override
+ public void onItemClick(View view, int position) {
+ Item item = mAdapter.getItem(position);
+
+ if (item.isDirectory()) {
+ currentFolder = new File(item.getPath());
+ mAdapter.setData(getFiles(currentFolder));
+ mAdapter.notifyDataSetChanged();
+ } else {
+ open(item);
+ }
+ }
+ }
+ )
+ );
+
+ registerForContextMenu(mRecyclerView);
+ }
+
+ private void open(Item item) {
+ if (isImage(new File(item.getPath()))) {
+ openWithOwnViewer(item);
+ } else {
+ openWithExternalApp(item);
+ }
+ }
+
+ private void openWithOwnViewer(Item item) {
+ Intent intent = new Intent(this, ImageViewer.class);
+ intent.putExtra(IMAGE_PATH, item.getPath());
+ startActivity(intent);
+ }
+
+ private void openWithExternalApp(Item item) {
+ if (!openFile(item)) {
+ Toast.makeText(
+ getApplicationContext(),
+ R.string.unknown_file,
+ Toast.LENGTH_LONG
+ ).show();
+ }
+ }
+
+ public boolean isExternalStorageAccessable() {
+ String state = Environment.getExternalStorageState();
+ return Environment.MEDIA_MOUNTED.equals(state);
+ }
+
+ boolean openFile(Item item) {
+ final Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setData(Uri.fromFile(
+ new File(item.getPath())
+ ));
+
+ final ResolveInfo defaultResolution =
+ getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (defaultResolution != null) {
+ final ActivityInfo activity = defaultResolution.activityInfo;
+
+ //Log.i(TAG, "default - " + activity.name);
+
+ if (!activity.name.equals("com.android.internal.app.ResolverActivity")) {
+ intent.setClassName(activity.applicationInfo.packageName, activity.name);
+ startActivity(intent);
+ return true;
+ }
+ }
+
+ final List resolveInfoList =
+ getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (!resolveInfoList.isEmpty()) {
+
+ //Log.i(TAG, "from list - " + resolveInfoList.get(0).activityInfo.name);
+
+ intent.setClassName(resolveInfoList.get(0).activityInfo.packageName,
+ resolveInfoList.get(0).activityInfo.name);
+ startActivity(intent);
+ return true;
+ }
+ return false;
+ }
+
+ private List
- getFiles(File file) {
+ File[] files = file.listFiles();
+ List
- dirs = new ArrayList
- ();
+ List
- fls = new ArrayList
- ();
+
+ this.setTitle(file.getName());
+
+ String filename, modificationDate, path;
+ Bitmap preview;
+ ImageLoader imageLoader = new ImageLoader();
+ for (File f : files) {
+ filename = f.getName();
+ modificationDate = DateFormat.getDateTimeInstance().format(
+ new Date(f.lastModified())
+ );
+ path = f.getAbsolutePath();
+
+ preview = null;
+ if (f.isDirectory()) {
+ preview = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_folder_black_48dp);
+ dirs.add(
+ new Item(filename, modificationDate, path, preview, true)
+ );
+ } else {
+ if (isImage(f)) {
+ preview = imageLoader.decodeSampledBitmapFromFile(
+ path,
+ FILE_IMAGE_PREVIEW_DIMENSION,
+ FILE_IMAGE_PREVIEW_DIMENSION
+ );
+ }
+
+ if (preview == null) {
+ preview = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_file_black_48dp);
+ }
+
+ fls.add(
+ new Item(filename, modificationDate, path, preview, false)
+ );
+ }
+ }
+ Collections.sort(dirs);
+ Collections.sort(fls);
+ dirs.addAll(fls);
+
+ if (!(file.getAbsolutePath()
+ .equals(Environment.getExternalStorageDirectory()
+ .getAbsolutePath()))) {
+ dirs.add(0,
+ new Item("..", "",
+ file.getParentFile().getAbsolutePath(),
+ BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_folder_parent_black_48dp),
+ true)
+ );
+ }
+
+ return dirs;
+ }
+
+ private boolean isImage(File f) {
+ String mime = null;
+ String extension = MimeTypeMap.getFileExtensionFromUrl(f.toURI().toString());
+ if (extension != null) {
+ mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
+ }
+
+ //Log.i(TAG, f.getName() + " " + mime);
+
+ return mime != null && mime.split("/")[0].equals("image");
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem menuItem) {
+ int position = mAdapter.getPosition();
+ Item item = mAdapter.getItem(position);
+ switch (menuItem.getItemId()) {
+ case R.id.open:
+ open(item);
+ return true;
+ case R.id.rename:
+ openRenameDialog(item);
+ return true;
+ case R.id.delete:
+ openDeleteDialog(item);
+ return true;
+ }
+ return super.onContextItemSelected(menuItem);
+ }
+
+ private void openRenameDialog(final Item item) {
+ final EditText renamePrompt = new EditText(this);
+ String filename = item.getName();
+ String extension = item.getExtension();
+ renamePrompt.setText(filename.substring(0, filename.lastIndexOf(extension)));
+
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.rename)
+ .setMessage(R.string.rename_msg)
+ .setView(renamePrompt)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String newFilename = renamePrompt.getText().toString();
+ if (isCorrectFilename(newFilename)) {
+ String newAbsolutePath = constructNewAbsolutePath(item, newFilename);
+ File newFile = new File(newAbsolutePath);
+ renameFile(item, newFile);
+ } else {
+ Toast.makeText(
+ getApplicationContext(),
+ R.string.rename_error_msg,
+ Toast.LENGTH_LONG
+ ).show();
+ }
+ }
+ })
+ .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // nothing to do here
+ }
+ })
+ .create()
+ .show();
+ }
+
+ private boolean isCorrectFilename(String newFilename) {
+ // TODO
+ // Check if filename is correct,
+ // i.e. doesn't match others filenames
+ // or consist of forbidden characters.
+
+ // Haven't had enough time to do this.
+ return true;
+ }
+
+ private String constructNewAbsolutePath(Item item, String newFilename) {
+ String path = item.getPath();
+ return path.substring(0, path.lastIndexOf('/') + 1) + newFilename + item.getExtension();
+ }
+
+ private void renameFile(Item item, File newFile) {
+ File file = new File(item.getPath());
+ if (file.renameTo(newFile) && mAdapter.renameItem(item, newFile)) {
+ mAdapter.notifyDataSetChanged();
+ } else {
+ Toast.makeText(this, R.string.rename_error_msg, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ private void openDeleteDialog(final Item item) {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.delete)
+ .setMessage(R.string.delete_msg)
+ .setCancelable(true)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ deleteFileFromDevice(item);
+ }
+ })
+ .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // nothing to do here
+ }
+ })
+ .create()
+ .show();
+ }
+
+ private void deleteFileFromDevice(Item item) {
+ File file = new File(item.getPath());
+ if (file.delete() && mAdapter.deleteItem(item)) {
+ mAdapter.notifyDataSetChanged();
+ } else {
+ Toast.makeText(this, R.string.delete_error_msg, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putString(CURRENT_FOLDER_PATH, currentFolder.getAbsolutePath());
+ super.onSaveInstanceState(outState);
+ }
+}
diff --git a/app/src/main/java/ru/ppzh/filemanager/RecyclerAdapter.java b/app/src/main/java/ru/ppzh/filemanager/RecyclerAdapter.java
new file mode 100644
index 0000000..156fec6
--- /dev/null
+++ b/app/src/main/java/ru/ppzh/filemanager/RecyclerAdapter.java
@@ -0,0 +1,120 @@
+package ru.ppzh.filemanager;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+
+public class RecyclerAdapter extends RecyclerView.Adapter
+ implements View.OnCreateContextMenuListener {
+ private Context context;
+ private List
- files;
+ private int position;
+
+ public RecyclerAdapter(List
- files, Context context) {
+ this.files = files;
+ this.context = context;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(int position) {
+ this.position = position;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_layout, parent, false);
+ return new ViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(final ViewHolder holder, int position) {
+ holder.image.setImageBitmap(files.get(position).getPreview());
+ holder.filename.setText(files.get(position).getName());
+ holder.modified.setText(files.get(position).getDate());
+ holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ setPosition(holder.getAdapterPosition());
+ return false;
+ }
+ });
+
+ }
+
+ @Override
+ public void onViewRecycled(ViewHolder holder) {
+ holder.itemView.setOnLongClickListener(null);
+ super.onViewRecycled(holder);
+ }
+
+ @Override
+ public int getItemCount() {
+ return files.size();
+ }
+
+ public Item getItem(int position) {
+ return files.get(position);
+ }
+
+ public void setData(List
- files) {
+ this.files = files;
+ }
+
+ public boolean deleteItem(Item item) {
+ return files.remove(item);
+ }
+
+ public boolean renameItem(Item item, File newFile) {
+ if (deleteItem(item)) {
+ item.setPath(newFile.getAbsolutePath());
+ item.setName(newFile.getName());
+ item.setDate(
+ DateFormat.getDateTimeInstance().format(
+ new Date(newFile.lastModified())
+ )
+ );
+ files.add(item);
+ return true;
+ }
+ return false;
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder {
+ public ImageView image;
+ public TextView filename;
+ public TextView modified;
+
+ public ViewHolder(View v) {
+ super(v);
+ v.setOnCreateContextMenuListener(RecyclerAdapter.this);
+ image = (ImageView) v.findViewById(R.id.file_img);
+ filename = (TextView) v.findViewById(R.id.file_name);
+ modified = (TextView) v.findViewById(R.id.last_modified);
+ }
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenu.ContextMenuInfo menuInfo) {
+ if (!files.get(position).isDirectory()) {
+ menu.add(Menu.NONE, R.id.open, Menu.NONE, R.string.open);
+ menu.add(Menu.NONE, R.id.rename, Menu.NONE, R.string.rename);
+ menu.add(Menu.NONE, R.id.delete, Menu.NONE, R.string.delete);
+ }
+ }
+}
diff --git a/app/src/main/java/ru/ppzh/filemanager/RecyclerItemClickListener.java b/app/src/main/java/ru/ppzh/filemanager/RecyclerItemClickListener.java
new file mode 100644
index 0000000..70e704e
--- /dev/null
+++ b/app/src/main/java/ru/ppzh/filemanager/RecyclerItemClickListener.java
@@ -0,0 +1,45 @@
+package ru.ppzh.filemanager;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
+ private OnItemClickListener mListener;
+
+ public interface OnItemClickListener {
+ public void onItemClick(View view, int position);
+ }
+
+ GestureDetector mGestureDetector;
+
+ public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
+ mListener = listener;
+ mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ return true;
+ }
+ });
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
+ View childView = view.findChildViewUnder(e.getX(), e.getY());
+ if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
+ mListener.onItemClick(childView, view.getChildPosition(childView));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
+ }
+
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/ic_folder_black_48dp.png b/app/src/main/res/drawable-hdpi/ic_folder_black_48dp.png
new file mode 100644
index 0000000..5c4360a
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_folder_black_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_folder_black_48dp.png b/app/src/main/res/drawable-mdpi/ic_folder_black_48dp.png
new file mode 100644
index 0000000..49272b0
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_folder_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_folder_black_48dp.png b/app/src/main/res/drawable-xhdpi/ic_folder_black_48dp.png
new file mode 100644
index 0000000..073d853
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_folder_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_folder_black_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_folder_black_48dp.png
new file mode 100644
index 0000000..c7a13b4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_folder_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_folder_black_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_folder_black_48dp.png
new file mode 100644
index 0000000..27e524f
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_folder_black_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_file_black_48dp.png b/app/src/main/res/drawable/ic_file_black_48dp.png
new file mode 100644
index 0000000..84eba39
Binary files /dev/null and b/app/src/main/res/drawable/ic_file_black_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_folder_parent_black_48dp.png b/app/src/main/res/drawable/ic_folder_parent_black_48dp.png
new file mode 100644
index 0000000..ad31faf
Binary files /dev/null and b/app/src/main/res/drawable/ic_folder_parent_black_48dp.png differ
diff --git a/app/src/main/res/layout/image_viewer.xml b/app/src/main/res/layout/image_viewer.xml
new file mode 100644
index 0000000..5e033d3
--- /dev/null
+++ b/app/src/main/res/layout/image_viewer.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_layout.xml b/app/src/main/res/layout/item_layout.xml
new file mode 100644
index 0000000..081eab4
--- /dev/null
+++ b/app/src/main/res/layout/item_layout.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml
new file mode 100644
index 0000000..13c6f18
--- /dev/null
+++ b/app/src/main/res/layout/main_activity.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/rename_prompt.xml b/app/src/main/res/layout/rename_prompt.xml
new file mode 100644
index 0000000..c777ede
--- /dev/null
+++ b/app/src/main/res/layout/rename_prompt.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/context_menu.xml b/app/src/main/res/menu/context_menu.xml
new file mode 100644
index 0000000..5fb2246
--- /dev/null
+++ b/app/src/main/res/menu/context_menu.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e2827ac..f81f972 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,14 @@
- lesson5
+ File manager
+ No storage found
+ File image
+ No application for this type of files.
+
+ Open
+ Delete
+ Rename
+ Are you sure you want to delete this file?
+ Can\'t delete this file.
+ Enter new name
+ Can\'t rename this file.