Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   [Android] angeschlossene "/storage/"s finden (https://www.delphipraxis.net/189898-%5Bandroid%5D-angeschlossene-storage-s-finden.html)

nikosophi 5. Aug 2016 17:14

[Android] angeschlossene "/storage/"s finden
 
Hallo in die Runde...

hat es jemand geschafft für Firemonkey/Android die "Namen" der angeschlossenen SD-Karten oder USB Sticks zu ermitteln.
Ich versuche seit einiger Zeit vornehmlich für Android 6.01 zu ermitteln, ob und wenn ja, welche Speichermedien angeschlossen sind.

Erwarten würde ich eine Liste wie:
/storage/emulated/0/ // interne Karte
/storage/extSdCard/ // zusätzliche Karte, wenn eingelegt
/storage/UsbDriveA/ // USB Stick, wenn angesteckt
...

Getestet habe ich bisher folgendes:

1) alte Methode aus PC Zeiten:

P := '/storage/';
if (FindFirst(P + '*', faAnyFile, Sr) = 0) then
repeat
cPath := Sr.Name;
if copy(cPath, 1, 1) = '.' then begin
log (cPath+' wird ignoriert.');
end else begin
log ('Prima: '+cPath);
end;
until (FindNext(Sr) <> 0);
FindClose(Sr);

Ergebnis:
Auf allen Geräten ( Nexus5 6.01, Nexus7 6.01, S3 4.3) wir nur "." und ".." gefunden. Also nicht mal der interne Speicher.

2) FlyFilesUtils von wang80919qq heruntergeladen von:
https://sourceforge.net/projects/fmxflyfilesutils/

Eine schöne Sammlung netter Funktionen.
Alle Funktionen, die auf externe SD Karten zugreifen sollen, wie etwa "FlyFilesUtils.GetExterStoragePath" liefern für Android 6 keine Ergebnisse.
Für Android 4.3 gehts. Zwar liefert getVolumePaths aus 'android/os/storage/StorageManager' auch USB Anschlüsse '/storage/UsbDriveA/ bis '/storage/UsbDriveF/
obwohl kein Stick oder nur einer angeschlossen sind, aber immerhin.
Für Android 6 ist es aber nicht zu gebrauchen.

3) Wenn die möglichen Bezeichnungen '/storage/sdcard' '/storage/sdcard_ext' '/storage/_ExternalSD' und so weiter wenigstens eindeutig wären, könnte man die Liste der möglichen Bezeichnungen ja durchprobieren.
Aber natürlich hat ein Kunde ein Gerät, das ich leider nicht zum testen selbst verwenden kann eine Bezeichnng mit einer fürchterlichen Nummer drin.
Das habe ich auch in dem Artikel wiedergefunden:

http://www.heise.de/ct/artikel/Hinte...t-2679598.html

Zitat:
Beim verschlüsselten Formatieren bekommt die SD-Karte eine spezielle ID und wird unter /storage gemountet, unsere beispielsweise unter /storage/586675d6-6838-4bc0-abdf-df0fab107195/0. Environment.getExternalStorage() liefert nun diesen Pfad zurück.

Es hilft also nichts. Das OS muss den Namen herausrücken. Aber wie???

Hilfe wird sehnsüchtig und dankbar entgegengenommen!

Rollo62 5. Aug 2016 19:13

AW: [Android] angeschlossene "/storage/"s finden
 
Habs jetzt nicht getestet oder nachsehen können,

aber was gibt denn
http://docwiki.embarcadero.com/Libra...GetDirectories
und
http://docwiki.embarcadero.com/Libra...ctory.GetFiles
zurück ?

Kann sein das die auch das gleiche FindFirst/Next machen.

Rollo

nikosophi 8. Aug 2016 17:36

AW: [Android] angeschlossene "/storage/"s finden
 
Hallo Rollo,

konnte nicht früher testen, da sich vermeintlich wichtigere Dinge vorgedrängt haben...

Erst mal: Danke für Deine Antwort.

Also mit "GetFiles" bekomme ich keinen einen Eintrag zurück:
lList := system.IOUtils.TDirectory.GetFiles ('/storage/');
length(lList) ist 0

Mit "GetDirectories" kommt folgendes:
"/storage/emulated"
"/storage/self"

Beide Verzeichnisse existieren auch. ( DirectoryExists ).

Wenn ich einen USB Stick dranhänge kommt noch ein Eintrag hinzu:
"/storage/C6Ba-F48A"
Das Verzeichnis gibts aber nicht laut "DirectoryExists".

Wenn ich mit anderen Programmen drauf gucke zB "ES Datei Explorer" dann wird der USB Stick als "USB1002" angezeigt.

Kann doch nicht so schwer sein, SD Karten oder USB Sticks anzusprechen, wir sind hier ja nicht bei ios ;-)

Hat vielleicht noch jemand eine Idee???

Rollo62 8. Aug 2016 18:33

AW: [Android] angeschlossene "/storage/"s finden
 
Hast du die permissions richtig gestetzt ?
http://docwiki.embarcadero.com/RADSt...es_Permissions
http://www.fmxexpress.com/access-ext...ey-on-android/
Vielleocht muss man auf Nicht-Standard-Direktories mit den Android Intents losgehen:
http://eagle.phys.utk.edu/guidry/android/writeSD.html

Die Verzeichnisse haben aber auch selten volle Zugriffsrechte
http://docwiki.embarcadero.com/RADSt...rget_Platforms


Rollo

bra 9. Aug 2016 08:55

AW: [Android] angeschlossene "/storage/"s finden
 
Wir verwenden folgende Routine, schau mal, ob die bei dir das richtige liefert - würde mich nämlich auch interessieren 8-):

Delphi-Quellcode:
function GetSdCardPath: JFile;
var
  i, nSDK_Level: Integer;
  jfMntPath: JFile;
  jfList: TJavaObjectArray<JFile>;
  sMediaMounted, sPathStorageState: string;
begin
  Result := nil;
  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 begin
          Result := jfList.Items[i];
          Break;
        end;
      end;
    end;
  end;
end;

nikosophi 9. Aug 2016 11:32

AW: [Android] angeschlossene "/storage/"s finden
 
Prima, Danke!
Werde ich machen und Bescheid geben, wenn ich wieder Zugriff auf die Kunden Devices habe.
( Denke so Ende der Woche ).

nikosophi 4. Sep 2016 11:33

AW: [Android] angeschlossene "/storage/"s finden
 
Wow cool, habe meine Zeitplanung nur um 300% überschritten- ich werde halt immer besser ;-)

Aber im Ernst: die "wahre" Lösung scheint es nicht zu geben. Wieviele unterschiedliche Geräte Arten letztendlich geprüft wurden, weiß ich nicht genau, müssen aber über 15 gewesen sein.
Also unterschiedliche Devices oder Android Versionen.

Am liebsten hätte ich die Variante von "bra" verwendet, da jfList immer die korrekte Anzahl an wirklich angeschlossenen Speicherkarten oder Sticks anzeigt. Sogar bei Android 4.
Also USB Stick anstöpseln und zack: ein Eintag mehr.
Allerdings liefert sPathStorageState stets "unknown".

Ich habe letztendlich zwei verschiedene Funktionen verwendet und die Ergebnisse in eine eindeutige Liste geschrieben.

1) FlyFilesUtils.GetExternalStoragePath // von wang80919qq link siehe ersten post
2) system.IOUtils.TDirectory.GetDirectories ('/storage/');

Zur Verbesserung sollte man noch den freien Speicher prüfen, da oft USBDriveA-USBDriveF aufgelistet werden, auch wenn kein oder nur ein Stick angeschlossen ist.

Falls es was besseres gibt, bitte melden!


hier die Funktion:
Code:
function InitCacheCombobox: boolean;
var
  cFunctionname: string;

  cPath, cExtern, cIntern, cMsg, cName, cFileINIExt: string;
  i: longInt;
  sr: TSearchRec;
  lList: System.Types.TStringDynArray;
  LSearchOption: TSearchOption;
begin
  cFunctionname := unit_name + 'InitCacheCombobox';
  result  := FALSE;
  try
    try
      haupt_util.AddDebugInfo ( '*** Laufwerksabfragen: ***' );

{$IFDEF ANDROID}

      cPath := FlyFilesUtils.GetExternalStoragePath;
      cMsg := Format('GetExternalStoragePath: %s free Diskspace: %d Byte davon frei: %d Byte', [cPath, FlyFilesUtils.GetTotalSpaceSize(cPath), GetFreeSpaceSize(cPath)]);
      haupt_util.AddDebugInfo (cMsg);
      Add2CacheCombobox (cPath);

////////////////////////////////////////////////////////////////////////////////
      LSearchOption := TSearchOption.soAllDirectories;
      lList := system.IOUtils.TDirectory.GetDirectories ('/storage/');

      for i := 0 to pred(length(lList)) do begin
        cPath := lList[i];
        haupt_util.AddDebugInfo ('GetDirectories(1): '+inttostr(i)+') '+cPath);
        Add2CacheCombobox (cPath);
      end;
////////////////////////////////////////////////////////////////////////////////

{$endif}
    haupt_util.AddDebugInfo ( '*** Laufwerksabfragen Ende ***' );
    except
      on E:Exception do begin
        haupt_util.WriteExceptionLog ( E, cFunctionname );
      end;
    end;
  finally
  end;
end;

philipp.hofmann 5. Apr 2019 12:43

AW: [Android] angeschlossene "/storage/"s finden
 
Ich habe es jetzt sowohl mit
- FlyFilesUtils.GetExternalStoragePath
- als auch mit der Implementierung von Bra und
- system.IOUtils.TDirectory.GetDirectories ('/storage/')
ausprobiert. Auf meinem Samsung Galaxy S4 Tablet bekomme
ich die SD-Card sauber gemountet in /storage/0000-0000 zurück und kann damit arbeiten.
Den USB-Stick sehe ich aber nur als OTG/USB2002 und er ist nicht gemountet.
Irgendwie steht auch in den Einstellungen, dass über den USB-C-Port nur geladen wird und ich kann es nicht auf Dateiübertragung umstellen.

Gibt es irgendeinen Trick den USB-Stick doch zu mounten, damit er auch als /storage/????-???? auftaucht und via Delphi-App nutzbar ist?
So kann ich den USB-Stick nur selbst im ES-Datei-Explorer nutzen, nicht aber in der Delphi-App, oder doch?


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz