You may want to roll your own comparison method to compare two pieces of a string in-place, instead of using substring(), which as I guessunderstand creates an unnecessary temporary copy. It may look like this:
bool CompareInPlace(String text, int from1, int len1, int from2, int len2)
{
// ...
}
Furthermore, instead of keeping a copy of the longest duplicat found, keep its indices from and len.
Then in the end you can return text.substring(longestFrom, longestLen);.