09 August 2016

I googled how to get root directory on Android with Cocos2d-x but I could not get any related or helpful results. Thus this is how I have extended Cocos2d-x(v3.10) to get it.

Open up %PROJECT_DIR%/cocos2d/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxHelper.java

import android.os.Build;
import android.os.IBinder;
import android.os.Vibrator;
import android.os.Environment; // <- ADD THIS
// ===========================================================
// Fields
// ===========================================================
private static String sRootDirectory; // <- ADD THIS

private static Cocos2dxMusic sCocos2dMusic;
private static Cocos2dxSound sCocos2dSound;
private static AssetManager sAssetManager;
private static Cocos2dxAccelerometer sCocos2dxAccelerometer;
private static boolean sAccelerometerEnabled;
private static boolean sActivityVisible;
private static String sPackageName;
private static String sFileDirectory;
public static void init(final Activity activity) {
    sActivity = activity;
    Cocos2dxHelper.sCocos2dxHelperListener = (Cocos2dxHelperListener)activity;
    if (!sInited) {
        final ApplicationInfo applicationInfo = activity.getApplicationInfo();
                
        Cocos2dxHelper.sPackageName = applicationInfo.packageName;
        if (CocosPlayClient.isEnabled() && !CocosPlayClient.isDemo()) {
            Cocos2dxHelper.sFileDirectory = CocosPlayClient.getGameRoot();
        }
        else {
            Cocos2dxHelper.sFileDirectory = activity.getFilesDir().getAbsolutePath();
        }

        Cocos2dxHelper.sRootDirectory = Environment.getExternalStorageDirectory().getAbsolutePath(); // <- ADD THIS
public static String getCocos2dxWritablePath() {
    return Cocos2dxHelper.sFileDirectory;
}

public static String getCocos2dxRootPath() { // <- ADD THIS METHOD
    return Cocos2dxHelper.sRootDirectory;
}

public static String getCurrentLanguage() {
    return Locale.getDefault().getLanguage();
}

Open up %PROJECT_DIR%/cocos2d/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h

extern std::string getCurrentLanguageJNI();
extern std::string getPackageNameJNI();
extern std::string getFileDirectoryJNI();
extern std::string getRootDirectoryJNI(); // <- ADD THIS

Open up %PROJECT_DIR%/cocos2d/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.cpp

std::string getRootDirectoryJNI() { // <- ADD THIS FUNCTION
    JniMethodInfo t;
    std::string ret("");

    if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getCocos2dxRootPath", "()Ljava/lang/String;")) {
        jstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
        t.env->DeleteLocalRef(t.classID);
        ret = JniHelper::jstring2string(str);
        t.env->DeleteLocalRef(str);
    }
    
    return ret;
}

Open up %PROJECT_DIR%/cocos2d/cocos/platform/android/CCFileUtils-android.h

virtual std::string getWritablePath() const;
virtual std::string getRootPath() const; // <- ADD THIS
virtual bool isAbsolutePath(const std::string& strPath) const;

Open up %PROJECT_DIR%/cocos2d/cocos/platform/android/CCFileUtils-android.cpp

string FileUtilsAndroid::getRootPath() const // <- ADD THIS METHOD
{
    string dir("");
    string tmp = getRootDirectoryJNI();

    if (tmp.length() > 0)
    {
        dir.append(tmp).append("/");

        return dir;
    }
    else
    {
        return "";
    }
}

Open up %PROJECT_DIR%/cocos2d/cocos/platform/CCFileUtils.h

virtual std::string getRootPath() const = 0; //  <- ADD THIS

Finally

FileUtils's new method getRootPath() is created and calling it may return something like "/storage/emulated/0/".