У меня нет непосредственного опыта, но, судя по API, вы можете просто написать свой собственный класс, который реализует интерфейс Application.ActivityLifecycleCallbacks
, и зарегистрировать этот класс в предоставленном экземпляре класса Application
getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass);
Этот класс получит те же обратные вызовы, что и ваши отдельные действия. Удачи.
PS. Кстати, это уровень API 14, поэтому он не будет работать на старых телефонах.
Вы можете использовать функцию PathGetCharType , функцию PathCleanupSpec или следующий трюк:
function IsValidFilePath(const FileName: String): Boolean;
var
S: String;
I: Integer;
begin
Result := False;
S := FileName;
repeat
I := LastDelimiter('\/', S);
MoveFile(nil, PChar(S));
if (GetLastError = ERROR_ALREADY_EXISTS) or
(
(GetFileAttributes(PChar(Copy(S, I + 1, MaxInt))) = INVALID_FILE_ATTRIBUTES)
and
(GetLastError=ERROR_INVALID_NAME)
) then
Exit;
if I>0 then
S := Copy(S,1,I-1);
until I = 0;
Result := True;
end;
Этот код делит строку на части и использует MoveFile для проверки каждой часть. MoveFile завершится ошибкой из-за недопустимых символов или зарезервированных имен файлов (например, «COM») и вернет успех или ERROR_ALREADY_EXISTS для допустимого имени файла.
PathCleanupSpec находится в Jedi Windows API в Win32API / JwaShlObj.pas
Что касается вопроса о том, есть ли какая-либо функция API для очистки файла с именем (или даже проверки его действительности), похоже, что ее нет. Цитата из комментария к функции PathSearchAndQualify () :
Похоже, не существует никакого Windows API, который проверял бы путь, введенный пользователем; это оставлено как специальное упражнение для каждого приложения.
Таким образом, вы можете ознакомиться с правилами допустимости имени файла только из Имена файлов, пути и пространства имен (Windows) :
Использовать почти любой символ в текущей кодовой странице для имени, включая символы Unicode и символы из расширенного набора символов (128–255), за исключением следующего:
Не используйте следующие зарезервированные имена устройств для имени файл: CON
, PRN
, AUX
, NUL
, COM1..COM9
, LPT1 ..LPT9
.
Также избегайте этих имен, за которыми сразу следует расширение; например, NUL.txt
не рекомендуется.
Если вы знаете, что ваша программа будет писать только в файловую систему NTFS, вы, вероятно, можете быть уверены, что нет других символов, которые файловая система не поддерживает allow, поэтому вам нужно будет только проверить, что имя файла не слишком длинное (используйте константу MAX_PATH
) после того, как все недопустимые символы будут удалены (или заменены, например, символами подчеркивания).
A Программа также должна убедиться, что очистка имени файла не привела к конфликту имен файлов, и она автоматически перезаписывает другие файлы с тем же именем.
Проверить, содержит ли строка недопустимые символы; решение из здесь :
//test if a "fileName" is a valid Windows file name
//Delphi >= 2005 version
function IsValidFileName(const fileName : string) : boolean;
const
InvalidCharacters : set of char = ['\', '/', ':', '*', '?', '"', '<', '>', '|'];
var
c : char;
begin
result := fileName <> '';
if result then
begin
for c in fileName do
begin
result := NOT (c in InvalidCharacters) ;
if NOT result then break;
end;
end;
end; (* IsValidFileName *)
И для строк, возвращающих False, вы можете сделать что-то простое, например this для каждого недопустимого символа:
var
before, after : string;
begin
before := 'i am a rogue file/name';
after := StringReplace(before, '/', '',
[rfReplaceAll, rfIgnoreCase]);
ShowMessage('Before = '+before);
ShowMessage('After = '+after);
end;
// Before = i am a rogue file/name
// After = i am a rogue filename
Что ж, проще всего использовать регулярное выражение и версию gsub
вашего любимого языка для замены всего, что не является «словесным символом». Этот класс символов будет « \ w
» в большинстве языков с регулярными выражениями, подобными Perl, или « [A-Za-z0-9]
» в качестве простого варианта в противном случае.
] В частности, в отличие от некоторых примеров в других ответах, вы не хотите искать недопустимые символы для удаления, а ищите допустимые символы, которые нужно сохранить. Если вы ищете недопустимые символы, вы всегда уязвимы для введения новых символов, но если вы ищете только действительные, вы можете быть немного менее неэффективными (поскольку вы заменили символ, который на самом деле не нужно), но по крайней мере вы никогда не ошибетесь.
Теперь, если вы хотите сделать новую версию максимально похожей на старую, вы можете подумать о замене. Вместо удаления вы можете заменить символ или символы, которые вам подходят. Но это достаточно интересная проблема, и, вероятно, это хорошая тема для другого вопроса.
Я сделал это:
// Initialized elsewhere...
string folder;
string name;
var prepl = System.IO.Path.GetInvalidPathChars();
var frepl = System.IO.Path.GetInvalidFileNameChars();
foreach (var c in prepl)
{
folder = folder.Replace(c,'_');
name = name.Replace(c, '_');
}
foreach (var c in frepl)
{
folder = folder.Replace(c, '_');
name = name.Replace(c, '_');
}
{
CleanFileName
---------------------------------------------------------------------------
Given an input string strip any chars that would result
in an invalid file name. This should just be passed the
filename not the entire path because the slashes will be
stripped. The function ensures that the resulting string
does not hae multiple spaces together and does not start
or end with a space. If the entire string is removed the
result would not be a valid file name so an error is raised.
}
function CleanFileName(const InputString: string): string;
var
i: integer;
ResultWithSpaces: string;
begin
ResultWithSpaces := InputString;
for i := 1 to Length(ResultWithSpaces) do
begin
// These chars are invalid in file names.
case ResultWithSpaces[i] of
'/', '\', ':', '*', '?', '"', '<', '>', '|', ' ', #$D, #$A, #9:
// Use a * to indicate a duplicate space so we can remove
// them at the end.
{$WARNINGS OFF} // W1047 Unsafe code 'String index to var param'
if (i > 1) and
((ResultWithSpaces[i - 1] = ' ') or (ResultWithSpaces[i - 1] = '*')) then
ResultWithSpaces[i] := '*'
else
ResultWithSpaces[i] := ' ';
{$WARNINGS ON}
end;
end;
// A * indicates duplicate spaces. Remove them.
result := ReplaceStr(ResultWithSpaces, '*', '');
// Also trim any leading or trailing spaces
result := Trim(Result);
if result = '' then
begin
raise(Exception.Create('Resulting FileName was empty Input string was: '
+ InputString));
end;
end;