Einzelnen Beitrag anzeigen

philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
893 Beiträge
 
Delphi 10.4 Sydney
 
#1

Delphi 10.4.2 und Android 11: Wie finde ich den Pfad für die SD-Karte heraus?

  Alt 25. Feb 2021, 16:06
Hi,

bis Android 10 suche ich folgendermaßen nach dem möglichen Pfaden für die SD-Karte (oder USB-Sticks):

Delphi-Quellcode:
procedure searchForExternalDevice(deviceNr: byte);
var possibleList: TStringPairList;
  searchForDir: String;
  i: Integer;
  dirExists: Boolean;
  dirList: TStringDynArray;
begin
  possibleList:=TStringPairList.create(True);
  if (TOSVersion.Major<11) then
    TFileUtils.listSDUSB();
  try
    dirList:=TDirectory.GetDirectories('/storage', TSearchOption.soTopDirectoryOnly, nil);
    for i:=0 to length(dirList) - 1 do
    begin
      if (MatchesMask(dirList[i], '/storage/????-????')) then
      begin
        possibleList.add(TStringPair.create(dirList[i] + '/Android/data/', 'com.icTrainer/files/'));
        possibleList.add(TStringPair.create(dirList[i] + '/icTrainer/', ''));
      end;
    end;
  except
    on E: Exception do
      log.d('Can´t access /storage: ' + E.message);
  end;
  try
    dirList:=TDirectory.GetDirectories('/mnt/media_rw', TSearchOption.soTopDirectoryOnly, nil);
    for i:=0 to length(dirList) - 1 do
    begin
      if (MatchesMask(dirList[i], '/mnt/media_rw/????-????')) then
        possibleList.add(TStringPair.create(dirList[i] + '/icTrainer/', ''));
    end;
  except
    on E: Exception do
      log.d('Can´t access /mnt/media_rw: ' + E.message);
  end;
  possibleList.add(TStringPair.create('/storage/sdcard1/Android/data/', 'AppName/files/'));
  possibleList.add(TStringPair.create('/storage/usbotg/AppName/', ''));
  possibleList.add(TStringPair.create('/storage/sdcard1/AppName/', ''));
  possibleList.add(TStringPair.create('/storage/usbdisk/AppName/', ''));
  possibleList.add(TStringPair.create('/mnt/media_rw/AppName/', ''));

  for i:=0 to possibleList.count - 1 do
  begin
    searchForDir:=possibleList[i].val1 + possibleList[i].val2;
    if ((externalDevice1 = searchForDir) or (externalDevice2 = searchForDir)) then
      continue;
    dirExists:=DirectoryExists(possibleList[i].val1);
    log.d('Search for ' + possibleList[i].val1 + ' ' + TStringUtils.BoolToStr(dirExists));
    if (dirExists) then
    begin
     //und hier mache ich jetzt was mit dem Pfad
      exit;
    end;
  end;
end;

class procedure TFileUtils.listSDUSB();
begin
    jfMntPath := TJFile.JavaClass.init( StringToJString( '/storage' ) );
    if jfMntPath.isDirectory and jfMntPath.exists then begin
      nSDK_Level := TJBuild_VERSION.JavaClass.SDK_INT;
      if nSDK_Level >= 19 then
      begin
        sMediaMounted := JStringToString( TJEnvironment.JavaClass.MEDIA_MOUNTED );
        jfList := jfMntPath.listFiles;
        for i := 0 to jfList.Length-1 do
        begin
          // getStorageState is added in API level 19; deprecated in API level 21, which introduces getExternalStorageState(File). Delphi interface does not supports this method with parameter.
          sPathStorageState := JStringToString( TJEnvironment.JavaClass.getStorageState( jfList.Items[i] ) );
          if SameText( sPathStorageState, sMediaMounted ) then
            mlog.info('External(1)(1): '+JStringToString(jfList.Items[i].getPath))
          else
            mlog.info('External(1)(2): '+JStringToString(jfList.Items[i].getPath));
        end;
      end;
    end;
    mlog.info('External(2): '+JStringToString(TJEnvironment.JavaClass.getExternalStorageDirectory.getPath));
end;
Mit Android-11 geht dies nicht mehr, man hat aber Zugriff auf den Pfad der eigenen App (z.B. /storage/???/Android/data/AppName/files/). Dies weiß ich, weil ich auf einem Device mit Android-10 den Pfad ermittelt hatte, danach ein Update auf Android-11 durchgeführt habe und weiterhin Zugriff auf meine Files hatte.

Nur wie ermittelt man den Pfad von USB-Sticks oder SD-Karten auf einem Android-11-Device?
Es reicht mir aus, darin auch nur auf den Pfad der eigenen App zugreifen zu können.

Grüße, Philipp
  Mit Zitat antworten Zitat