JAVA ANDROID 02 (p) - system plików, ListView, Dialogs, permissions

JAVA ANDROID 02 (p) - system plików, ListView, Dialogs, permissions
ukryj menu
SPEC
aktualizacja: 2022-03-11 11:14:23
Tematyka:

- System plików urządzenia, dostęp do katalogów i plików
- ListView i ArrayAdapter - tworzenie list przewijanych
- Dialogs - okienka


1. Scenariusz aplikacji na dziś

przy starcie aplikacji powinien się utworzyć folder główny WaszeImieNazwisko w folderze PICTURES 
oraz trzy przykładowe podfoldery na albumy zdjęć:

--- miejsca
--- ludzie
--- rzeczy

przy kolejnym starcie aplikacja sprawdza czy taki folder już istnieje, jeśli tak, to go nie tworzy
kolejne foldery będzie dodawał już użytkownik w dalszej części projektu

2. Ekrany (Activities) na dziś

w których odbywają się jakieś działania

MainActivity - uprawnienia, system plików
AlbumsActivity - ListView, ArrayAdapter

3. ListView i ArrayAdapter - ekran prezentujący albumy w postaci listy

a) utwórz w folderze Layout (New / Layout Resource File) plik xml odpowiedzialny za wygląd jednego wiersza w ListView:

prawy klawisz na katalog res / layout

potem 

New / Layout Resource File / root element / LinearLayout

proponowana struktura wewnątrz tego pliku

- LinearLayout (horizontal)
--- ImageView
--- TextView

b) w pliku xml AlbumsActivity, dodaj statycznie ListView, dodaj id


<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"        
/>kopiuj





c) w kodzie Activity tego ekranu:

odwołaj się do ListView (findview)

dla testów utwórz prostą tablicę stringów:

String[] array = new String[]{"wynik 1","wynik 2","wynik 3"};kopiuj

utwórz obiekt ArrayAdapter:

ArrayAdapter<String> adapter = new ArrayAdapter<>(
   MainActivity.this,       // tzw Context
   R.layout.row_layout,     // nazwa pliku xml naszego wiersza na liście
   R.id.tv1,                // id pola txt w wierszu
   array );                 // tablica przechowująca testowe danekopiuj






przypisz adapter do ListView:

listView.setAdapter(adapter);kopiuj

w tym momencie już powinna się wyświetlać lista z trzema testowymi wierszami
których wygląd ustalamy w pliku xml (pkt a)

d) dodaj obsługę kliknięcia w wiersz ListView (nie wklejaj, napisz setonitem, new OnItem...)

listView.setOnItemClickListener(new OnItemClickListener() {
   @Override
   public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {     
      Log.d("TAG","numer klikanego wiersza w ListView = " + i);
   }
 });
kopiuj





e) długie przytrzymanie elementu listy

listView1.setOnItemLongClickListener...kopiuj

4. AndroidManifest.xml - umożliwienie ingerencji w system plików

W pliku AndroidManifest.xml dodaj uprawnienia uses-permission :

napisz <uses-permission

a z listy wybierz dwa razy: 

WRITE_EXTERNAL_STORAGE kopiuj
READ_EXTERNAL_STORAGE kopiuj     

UWAGA: w wersjach Androida >= 6 należy jeszcze manualnie ustawić uprawnienia dla danej aplikacji w telefonie/tablecie
lub wywołać okno dialoga, które umożliwi udzielenie uprawnień przez użytkownika

5. Uprawnienia - dialog

dla androida od wersji 9 potrzebne jest zezwolenie w pliku manifest na jakiekolwiek ingerencje
w system plików poza aplikacją

<application
    ...
    android:requestLegacyExternalStorage="true"
    ...
>kopiuj


kolejny krok to wywołanie funkcji która pokaże oko dialogowe


public void checkPermission(String permission, int requestCode) {
        // jeśli nie jest przyznane to zażądaj
        if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        } else {
            Toast.makeText(MainActivity.this, "Permission already granted", Toast.LENGTH_SHORT).show();
        }
}kopiuj


wywołanie w onCreate()

checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 100);kopiuj

reakcja na rezultat czyli przyznanie lub nie, permission
funkcję piszemy w klasie, poza onCreate
najlepiej napisać onreqper... i poczekać na podpowiedź


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //
        switch (requestCode) {
            case 100:
                if (grantResults.length > 0 &&
                        grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //tak
                } else {
                    //nie
                }
                break;
            case 101 :
               
                break;
        }

}kopiuj



6. System plików Androida

proponuję tworzyć folder na pliki aplikacji w folderze DIRECTORY_PICTURES:

File pic = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES );kopiuj

utworzenie katalogu

File dir = new File(pic, "moje_nazwisko");kopiuj
dir.mkdir()kopiuj


przykład zwracający tablicę plików w katalogu

File[] files = pic.listFiles() // tablica plikówkopiuj
files.length // ilość plikówkopiuj
Arrays.sort(files) // sortowanie plików wg nazwykopiuj

pętla czytająca dane z plików w katalogu

for (File file : pic.listFiles()){
    //
}kopiuj




potrzebne operacje na systemie plików

pic.getPath()      // pełna ścieżka
pic.getName()      // nazwa
pic.getParent()    // nazwa nadrzędnego
pic.exists()       // czy istnieje
pic.isDirectory()  // czy jest katalogiem
pic.isFile()       // czy jest plikiem
pic.isHidden()     // czy ukrytykopiuj







usunięcie pliku / katalogu

file.delete();kopiuj

usunięcie katalogu (uwaga - przed usunięciem katalogu należy usunąć wszystkie pliki, najlepiej
pętlą foreach, jak w przykładzie poniżej)


for (File file : anyDir.listFiles()){
    //usuwaj pliki
}kopiuj




a potem usunąć katalog

dir.delete();kopiuj

dokumentacja:

https://developer.android.com/reference/java/io/File.html

pozbycie się paska tytułu u góry layoutu


7. Dialogi 

posłużą m.in. jako zabezpieczenie przed przypadkowym usunięciem albumu czy zdjęcia, 
do wprowadzania danych do aplikacji

a) dialog z jednym butonem

AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Uwaga!");
alert.setCancelable(false);  //nie zamyka się po kliknięciu poza nim
alert.setMessage("TEST");
alert.setNeutralButton("OK", null).show();  // null to pusty clickkopiuj


b) dialog z ikoną i kliknięciem butona

AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Uwaga");
alert.setMessage("komunikat");
alert.setIcon(R.drawable.anyicon);      
alert.setNeutralButton("OK", new AlertDialog.OnClickListener() {            
    public void onClick(DialogInterface dialog, int which) {
                //komunikat                
            }
        });
            
alert.show();kopiuj


c) dialog z dwoma butonami, TAK, NIE

AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Uwaga!");
alert.setMessage("komunikat");
//ok
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {                
    public void onClick(DialogInterface dialog, int which) {
        //wyświetl zmienną which
    }
                    
});

//no
alert.setNegativeButton("NO", new DialogInterface.OnClickListener() {                
    public void onClick(DialogInterface dialog, int which) {
        //wyświetl which
    }
    });
//
alert.show();kopiuj


d) dialog z listą możliwych opcji

AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Uwaga!");
//nie może mieć setMessage!!!
String[] opcje = {"tanie","średnie","drogie"};
alert.setItems(opcje, new DialogInterface.OnClickListener() {                
    public void onClick(DialogInterface dialog, int which) {                    
            // wyswietl opcje[which]);
                    
    }
});
//
alert.show();kopiuj


e) dialog z inputem

AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Uwaga!");
alert.setMessage("login lub hasło jest puste!!!");
//tutaj input
EditText input = new EditText(this);
input.setText("podaj login");
alert.setView(input);
//teraz butony jak poprzednio i
alert.show();kopiuj