上面是工具类,下面是MainActivity,在logcat里面看结果
package com.qycx.jiance.util;

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

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

/**
 * 终端安装目录检测工具类
 * 用于检索整个安装目录文件,排查关键性文件是否存在,防止安装包缺少文件的问题
 */
public class DirectoryChecker {

    private static final String TAG = "DirectoryChecker";
    private Context mContext;

    public DirectoryChecker(Context context) {
        this.mContext = context;
    }

    /**
     * 执行完整的目录检测
     * @return 检测结果汇总
     */
    public CheckResult checkInstallationDirectory() {
        CheckResult result = new CheckResult();
        
        // 检查应用程序的基本目录
        checkAppDirectories(result);
        
        // 检查关键文件
        checkKeyFiles(result);
        
        return result;
    }

    /**
     * 检查应用程序的基本目录
     */
    private void checkAppDirectories(CheckResult result) {
        // 应用程序的数据目录
        File dataDir = mContext.getDataDir();
        checkPath(dataDir, "应用数据目录", result);
        
        // 应用程序的缓存目录
        File cacheDir = mContext.getCacheDir();
        checkPath(cacheDir, "缓存目录", result);
        
        // 应用程序的文件目录
        File filesDir = mContext.getFilesDir();
        checkPath(filesDir, "文件目录", result);
        
        // 外部存储的私有目录
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            File externalFilesDir = mContext.getExternalFilesDir(null);
            checkPath(externalFilesDir, "外部存储文件目录", result);
            
            File externalCacheDir = mContext.getExternalCacheDir();
            checkPath(externalCacheDir, "外部存储缓存目录", result);
        }
    }

    /**
     * 检查关键文件
     */
    private void checkKeyFiles(CheckResult result) {
        // 检查APK文件是否存在
        String apkPath = mContext.getPackageCodePath();
        checkPath(new File(apkPath), "APK文件", result);
        
        // 检查lib目录是否存在及包含必要文件
        File libDir = new File(mContext.getApplicationInfo().nativeLibraryDir);
        checkPath(libDir, "原生库目录", result);
        
        // 如果有数据库,检查数据库文件
        File databaseDir = new File(String.valueOf(mContext.getDatabasePath("dummy.db").getParentFile()));
        checkPath(databaseDir, "数据库目录", result);
        
        // 可以根据应用的具体需求添加更多关键文件的检查
    }

    /**
     * 检查指定路径是否存在
     */
    private void checkPath(File path, String description, CheckResult result) {
        if (path != null && path.exists()) {
            result.addSuccess(description + " 存在: " + path.getAbsolutePath());
            Log.d(TAG, description + " 存在: " + path.getAbsolutePath());
        } else {
            String pathStr = (path != null) ? path.getAbsolutePath() : "(null)";
            result.addFailure(description + " 不存在: " + pathStr);
            Log.e(TAG, description + " 不存在: " + pathStr);
        }
    }

    /**
     * 递归检查整个目录结构
     */
    public CheckResult checkDirectoryStructure(File directory, int maxDepth) {
        CheckResult result = new CheckResult();
        checkDirectoryRecursive(directory, "", result, maxDepth, 0);
        return result;
    }

    /**
     * 递归检查目录
     */
    private void checkDirectoryRecursive(File directory, String prefix, CheckResult result, int maxDepth, int currentDepth) {
        if (currentDepth > maxDepth) {
            return;
        }
        
        if (directory == null || !directory.exists() || !directory.isDirectory()) {
            result.addFailure(prefix + directory + " 不是有效目录");
            return;
        }
        
        result.addSuccess(prefix + directory.getName() + "/");
        
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    checkDirectoryRecursive(file, prefix + "  ", result, maxDepth, currentDepth + 1);
                } else {
                    result.addSuccess(prefix + "  " + file.getName() + " (" + file.length() + " bytes)");
                }
            }
        }
    }

    /**
     * 检测结果类,用于存储检测过程中的成功和失败信息
     */
    public static class CheckResult {
        private List<String> successList;
        private List<String> failureList;
        private long startTime;
        private long endTime;
        
        public CheckResult() {
            successList = new ArrayList<>();
            failureList = new ArrayList<>();
            startTime = System.currentTimeMillis();
        }
        
        public void addSuccess(String message) {
            successList.add(message);
        }
        
        public void addFailure(String message) {
            failureList.add(message);
        }
        
        public List<String> getSuccessList() {
            return successList;
        }
        
        public List<String> getFailureList() {
            return failureList;
        }
        
        public boolean isAllSuccess() {
            return failureList.isEmpty();
        }
        
        public void finish() {
            endTime = System.currentTimeMillis();
        }
        
        public long getExecutionTime() {
            return endTime - startTime;
        }
        
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("===== 目录检测结果 =====\n");
            sb.append("成功项 (").append(successList.size()).append("):\n");
            for (String success : successList) {
                sb.append("✓ ").append(success).append("\n");
            }
            
            sb.append("\n失败项 (").append(failureList.size()).append("):\n");
            if (failureList.isEmpty()) {
                sb.append("无\n");
            } else {
                for (String failure : failureList) {
                    sb.append("✗ ").append(failure).append("\n");
                }
            }
            
            sb.append("\n执行时间: ").append(getExecutionTime()).append("ms\n");
            sb.append("======================");
            
            return sb.toString();
        }
    }
}




package com.qycx.jiance;

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

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.qycx.jiance.util.DirectoryChecker;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "DirectoryChecker";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 执行目录检测
        performDirectoryCheck();
    }

    private void performDirectoryCheck() {
        // 创建目录检查器实例
        DirectoryChecker checker = new DirectoryChecker(this);
        
        // 执行安装目录检测
        DirectoryChecker.CheckResult result = checker.checkInstallationDirectory();
        result.finish();
        
        // 输出检测结果到日志
        Log.d(TAG, "安装目录检测结果:\n" + result.toString());

    }
}

在Android应用中,原生库目录(lib目录)通常包含使用C/C++编写的原生代码库(.so文件)。如果应用是纯Java/Kotlin开发的,没有使用任何原生代码,那么这个目录不存在是完全正常的。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐