0

I want to know how I compare two images with extension and names and delete the duplicate file. Basically I get full video file from External and Internal Storage and I build an app where user can delete the duplicate the file from his device.

So I am successful to get the video file from device but unable to delete these files if there is same name and extension.

MainActivity.Class

    package com.deitel.duplicatefileremoverapp.VideoContent;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;

import com.deitel.duplicatefileremoverapp.R;

import java.io.File;
import java.util.ArrayList;

public class VideoMainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private VideoRecyclerViewAdapter videoRecyclerViewAdapter;
    File video_storage;
    File video_size;
    String[] allpath;
    String[] allpathsize;
    ArrayList<Videomodelclass> videomodelclassArrayList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_main);

        recyclerView = findViewById(R.id.video_recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        videoRecyclerViewAdapter = new VideoRecyclerViewAdapter(this);
        recyclerView.setAdapter(videoRecyclerViewAdapter);
        videoRecyclerViewAdapter.notifyDataSetChanged();

        //Load video data here
        allpath = VideoStorageUtil.getStorageDirectories(this);
        for (String path : allpath) {
            video_storage = new File(path);
            Log.d("videostorage1", "onCreate: "+video_storage);
            VideoMethod.load_Directory_files(video_storage);
        }
        allpathsize=VideoStorageUtil.getStorageDirectories(this);
        for (String pathsize : allpathsize)
        {
            video_size=new File(pathsize);
            VideoMethod.load_Directory_files(video_size);
            Log.d("videosize1", "onCreate: "+video_size);
        }
    }
}

VideoMethod.Class

    package com.deitel.duplicatefileremoverapp.VideoContent;

import android.content.Context;
import android.util.Log;

import java.io.File;

import static androidx.constraintlayout.widget.Constraints.TAG;

public class VideoMethod {
    static Context context;
    public static void load_Directory_files(File file) {
        File[] filelist = file.listFiles();
        if (filelist != null && filelist.length > 0) {
            for (int i = 0; i < filelist.length; i++) {
                if (filelist[i].isDirectory()) {
                    load_Directory_files(filelist[i]);
                } else {
                    String name = filelist[i].getName().toLowerCase();
                   long  size = filelist[i].length()/1024;
                    Log.d(TAG, "load_Directory_files:"+size);

                    for (String extension : VideoConstant.videoextention) {
                        // Check the type of file
                        if (name.endsWith(extension)) {
                            VideoConstant.allmedialist.add(filelist[i]);
                            //when we found file
                            break;
                        }
                    }
                    if (size==file.length())
                    {
                        VideoConstant.allmedialist.add(filelist[i]);
                        Log.d(TAG, "load_Directory_files1: "+size);
                    }
                }
            }
        }
    }
}

Video RecyclerAdapter.Class

    package com.deitel.duplicatefileremoverapp.VideoContent;

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.deitel.duplicatefileremoverapp.R;

import java.io.File;

public class VideoRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    // Constructore
    VideoRecyclerViewAdapter(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_file_list, parent, false);
        return new FileLayoutHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((FileLayoutHolder) holder).title.setText(VideoConstant.allmedialist.get(position).getName());
//        ((FileLayoutHolder) holder).size.setText((int) VideoConstant.allmedialist.get(position).getTotalSpace());
        ((FileLayoutHolder)holder).size.setText(VideoConstant.allmedialist.size());
        Uri uri = Uri.fromFile(VideoConstant.allmedialist.get(position));
        Glide.with(context).load(uri).thumbnail(0.1f).into(((FileLayoutHolder) holder).thumbnail);
    }
    @Override
    public int getItemCount() {
        return VideoConstant.allmedialist.size();
    }

    class FileLayoutHolder extends RecyclerView.ViewHolder {
        ImageView thumbnail;
        TextView title;
        TextView size;

        public FileLayoutHolder(@NonNull View itemView) {
            super(itemView);
            thumbnail = itemView.findViewById(R.id.video_thumbnail);
            title = itemView.findViewById(R.id.video_name);
            size = itemView.findViewById(R.id.video_size);
        }
    }
}

VideoStorageUtil.Class

    package com.deitel.duplicatefileremoverapp.VideoContent;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Helper class for getting all storages directories in an Android device
 * <a href="https://stackoverflow.com/a/40582634/3940133">Solution of this problem</a>
 * Consider to use
 * <a href="https://developer.android.com/guide/topics/providers/document-provider">StorageAccessFramework(SAF)</>
 * if your min SDK version is 19 and your requirement is just for browse and open documents, images, and other files
 *
 * @author Dmitriy Lozenko, HendraWD
 */
public class VideoStorageUtil {

    // Primary physical SD-CARD (not emulated)
    private static final String EXTERNAL_STORAGE = System.getenv("EXTERNAL_STORAGE");

    // All Secondary SD-CARDs (all exclude primary) separated by File.pathSeparator, i.e: ":", ";"
    private static final String SECONDARY_STORAGES = System.getenv("SECONDARY_STORAGE");

    // Primary emulated SD-CARD
    private static final String EMULATED_STORAGE_TARGET = System.getenv("EMULATED_STORAGE_TARGET");

    // PhysicalPaths based on phone model
    @SuppressLint("SdCardPath")
    @SuppressWarnings("SpellCheckingInspection")
    private static final String[] KNOWN_PHYSICAL_PATHS = new String[]{
            "/storage/sdcard0",
            "/storage/sdcard1",                 //Motorola Xoom
            "/storage/extsdcard",               //Samsung SGS3
            "/storage/sdcard0/external_sdcard", //User request
            "/mnt/extsdcard",
            "/mnt/sdcard/external_sd",          //Samsung galaxy family
            "/mnt/sdcard/ext_sd",
            "/mnt/external_sd",
            "/mnt/media_rw/sdcard1",            //4.4.2 on CyanogenMod S3
            "/removable/microsd",               //Asus transformer prime
            "/mnt/emmc",
            "/storage/external_SD",             //LG
            "/storage/ext_sd",                  //HTC One Max
            "/storage/removable/sdcard1",       //Sony Xperia Z1
            "/data/sdext",
            "/data/sdext2",
            "/data/sdext3",
            "/data/sdext4",
            "/sdcard1",                         //Sony Xperia Z
            "/sdcard2",                         //HTC One M8s
            "/storage/microsd"                  //ASUS ZenFone 2
    };

    /**
     * Returns all available storages in the system (include emulated)
     * <p/>
     * Warning: Hack! Based on Android source code of version 4.3 (API 18)
     * Because there is no standard way to get it.
     *
     * @return paths to all available storages in the system (include emulated)
     */
    public static String[] getStorageDirectories(Context context) {
        // Final set of paths
        final Set<String> availableDirectoriesSet = new HashSet<>();

        if (!TextUtils.isEmpty(EMULATED_STORAGE_TARGET)) {
            // Device has an emulated storage
            availableDirectoriesSet.add(getEmulatedStorageTarget());
        } else {
            // Device doesn't have an emulated storage
            availableDirectoriesSet.addAll(getExternalStorage(context));
        }

        // Add all secondary storages
        Collections.addAll(availableDirectoriesSet, getAllSecondaryStorages());

        String[] storagesArray = new String[availableDirectoriesSet.size()];
        return availableDirectoriesSet.toArray(storagesArray);
    }

    private static Set<String> getExternalStorage(Context context) {
        final Set<String> availableDirectoriesSet = new HashSet<>();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Solution of empty raw emulated storage for android version >= marshmallow
            // because the EXTERNAL_STORAGE become something like: "/Storage/A5F9-15F4",
            // so we can't access it directly
            File[] files = getExternalFilesDirs(context, null);
            for (File file : files) {
                if (file != null) {
                    String applicationSpecificAbsolutePath = file.getAbsolutePath();
                    String rootPath = applicationSpecificAbsolutePath.substring(
                            0,
                            applicationSpecificAbsolutePath.indexOf("Android/data")
                    );
                    availableDirectoriesSet.add(rootPath);
                }
            }
        } else {
            if (TextUtils.isEmpty(EXTERNAL_STORAGE)) {
                availableDirectoriesSet.addAll(getAvailablePhysicalPaths());
            } else {
                // Device has physical external storage; use plain paths.
                availableDirectoriesSet.add(EXTERNAL_STORAGE);
            }
        }
        return availableDirectoriesSet;
    }

    private static String getEmulatedStorageTarget() {
        String rawStorageId = "";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            // External storage paths should have storageId in the last segment
            // i.e: "/storage/emulated/storageId" where storageId is 0, 1, 2, ...
            final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            final String[] folders = path.split(File.separator);
            final String lastSegment = folders[folders.length - 1];
            if (!TextUtils.isEmpty(lastSegment) && TextUtils.isDigitsOnly(lastSegment)) {
                rawStorageId = lastSegment;
            }
        }

        if (TextUtils.isEmpty(rawStorageId)) {
            return EMULATED_STORAGE_TARGET;
        } else {
            return EMULATED_STORAGE_TARGET + File.separator + rawStorageId;
        }
    }

    private static String[] getAllSecondaryStorages() {
        if (!TextUtils.isEmpty(SECONDARY_STORAGES)) {
            // All Secondary SD-CARDs split into array
            return SECONDARY_STORAGES.split(File.pathSeparator);
        }
        return new String[0];
    }

    /**
     * Filter available physical paths from known physical paths
     *
     * @return List of available physical paths from current device
     */
    private static List<String> getAvailablePhysicalPaths() {
        List<String> availablePhysicalPaths = new ArrayList<>();
        for (String physicalPath : KNOWN_PHYSICAL_PATHS) {
            File file = new File(physicalPath);
            if (file.exists()) {
                availablePhysicalPaths.add(physicalPath);
            }
        }
        return availablePhysicalPaths;
    }

    /**
     * Returns absolute paths to application-specific directories on all
     * external storage devices where the application can place persistent files
     * it owns. These files are internal to the application, and not typically
     * visible to the user as media.
     * <p>
     * This is like {@link Context#getFilesDir()} in that these files will be
     * deleted when the application is uninstalled, however there are some
     * important differences:
     * <ul>
     * <li>External files are not always available: they will disappear if the
     * user mounts the external storage on a computer or removes it.
     * <li>There is no security enforced with these files.
     * </ul>
     * <p>
     * External storage devices returned here are considered a permanent part of
     * the device, including both emulated external storage and physical media
     * slots, such as SD cards in a battery compartment. The returned paths do
     * not include transient devices, such as USB flash drives.
     * <p>
     * An application may store data on any or all of the returned devices. For
     * example, an app may choose to store large files on the device with the
     * most available space, as measured by {@link android.os.StatFs}.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
     * are required to write to the returned paths; they're always accessible to
     * the calling app. Before then,
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
     * write. Write access outside of these paths on secondary external storage
     * devices is not available. To request external storage access in a
     * backwards compatible way, consider using {@code android:maxSdkVersion}
     * like this:
     *
     * <pre class="prettyprint">&lt;uses-permission
     *     android:name="android.permission.WRITE_EXTERNAL_STORAGE"
     *     android:maxSdkVersion="18" /&gt;</pre>
     * <p>
     * The first path returned is the same as
     * {@link Context#getExternalFilesDir(String)}. Returned paths may be
     * {@code null} if a storage device is unavailable.
     *
     * @see Context#getExternalFilesDir(String)
     */
    private static File[] getExternalFilesDirs(Context context, String type) {
        if (Build.VERSION.SDK_INT >= 19) {
            return context.getExternalFilesDirs(type);
        } else {
            return new File[]{context.getExternalFilesDir(type)};
        }
    }

}

VideoConstant.Class

    package com.deitel.duplicatefileremoverapp.VideoContent;

import java.io.File;
import java.util.ArrayList;

public class VideoConstant {
    public static String[] videoextention = {".mp4", ".ts", ".mlv", ".mov",
            ".3gp", ".mn2", ".m4v", ".webm", ".mpeg1", ".mts", ".ogm",
            ".bup", ".dv", ".flv", "mlv", ".m2ts", ".mpeg4", ".vlc", "3g2",
            ".avi", ".mpeg", ".mpg", ".wmv", ".asf"};

    //all loaded file will be here
    public static ArrayList<File> allmedialist = new ArrayList<>();
}

halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

0

If I understand you correctly, all the video files from your phone will be in

 public static ArrayList<File> allmedialist = new ArrayList<>();

If yes, then this is a rather easy task, you just have to look for duplicates in that exact list and delete them or put the objects into new list with checking if that objects is not already there. To check the specific object you have to call the name and extension of it by using allmedialist[index].name or allmedialist[index].nameWithoutExtension

qki
  • 1,769
  • 11
  • 25