Null budget exception – android app

Ostatnio napisałem o tym, że najważniejszą umiejętnością jaką możemy posiąść jest wiedza o tym, jak rozdzielać zadania pomiędzy tym co wykonujemy sami, a tym co powinniśmy oddelegować. Stworzyłem także taką małą aplikację do kształtowania nowych nawyków. Jeśli chodzi o nią, to nie wydałem podczas jej powstawania ani złotówki. Dzisiaj chciałem opisać jak to zrobiłem, aby jedynym moim kosztem był czas. I to najlepiej nie za dużo czasu 😉

Po pierwsze zewnętrzne biblioteki. Kiedy zerkniecie na aplikację, na starcie jest dostępny naprawdę ładny kalendarz. Nie jestem jego autorem, skorzystałem z gotowego komponentu dostępnego tutaj. A tak wygląda zrzut z mojego pliku gradle:

    compile 'com.jakewharton:butterknife:7.0.1′
    compile 'com.prolificinteractive:material-calendarview:1.4.0′
    compile 'petrov.kristiyan.colorpicker:colorpicker-library:1.1.0′
    compile 'com.github.javiersantos:MaterialStyledDialogs:1.4.1′
    compile 'com.github.PhilJay:MPAndroidChart:v2.2.5′

Wszystkie biblioteki których użyłem znalazłem na stronie android-arsenal. Jak już znalazłem wszystko co oszczędzało mi pracę, to po prostu przeczytałem trochę dokumentacji i mogłem korzystać. Bardzo ładnie zintegrowały się z Android Studio, i zostało mi o wiele mniej linii kodu do napisania 😉

Ale aplikacja, to nie tylko kod. Po za tym trzeba by jeszcze dorobić jakąś grafikę. Część grafik była we wcześniej pokazanych bibliotekach. Do ikon na toolbarze użyłem tych dostępnych na stronach design google, z kolei ikona aplikacji pochodziła ze strony flat-icon konkretnie stąd. Tutaj wymogiem było umieszczenie w about informacji o autorze, co też zrobiłem 😉 A z pozostałymi rzeczami graficznymi, np tymi potrzebnymi do sklepu Play poradziłem sobie sam, edytując choćby w paincie te elementy.

Ok, to mamy kodzik, mamy jakąś grafikę. Pozostał filmik promocyjny, który zawsze jest mile widziany. To również udało mi się zrobić, użyłem aplikacji shotcut. Ale skąd wziąłem elementy do tego filmiku? Elementy własnej aplikacji, które tam pokazuję nagrałem sobie sam 😉 Z kolei całe tło składające się z tych różnych biegaczy pobrałem ze stron videezy, oraz videvo, które udostępniają takie fragmenty za darmo 😉 Potem oczywiście odpowiedni montaż, podłączenie muzyki (Dave Depper „Motivational Beat” – „Compositions 2” ze strony freemusicarchive, oczywiście za darmo). I efekt końcowy jest taki:

I jak, wyszło w porządku, czy jednak czuć, że profesjonalista tego nie montował? 😉

Reasumując tak wyglądał mój przepis na w porządku wyglądającą aplikację, która kosztuje trochę czasu, ale za to ani złotówki 😉 Wydaje mi się, że jest on całkiem uniwersalny, także gdyby ktoś chciał tak samo jak ja, to polecam 😉 Można też oczywiście oddelegować część zadań, ważne, żeby ten wybór był świadomy 😉

Pozdrawiam!

#11 Cegła

Czasem w projekcie tak się zdarza, że programista musi zająć się grafiką. I to nigdy nie kończy się dobrze 😉 Chociaż ja uważam, że mi wyszło. Ale do rzeczy, jak pisałem wcześniej zastąpię ten jednobarwny obiekt mający przypominać klocek / cegłę właściwym obiektem. Z racji tego, że nie mogłem znaleźć niczego co by pasowało, postanowiłem stworzyć go sam 😉 Tak wygląda efekt mojej pracy.

Blender renderował przez 37 godzin 😉 Oczywiście żartuję, użyłem painta, gdzie wypełniłem obszar, następnie nałożyłem ramkę, oraz użyłem efektu sprayu z kolorem brązowym 🙂
Przy okazji umieszczenia tego obiektu w aplikacji chciałem zwrócić na coś uwagę, mianowicie jak zapobiec zniekształcaniu grafiki w Androidzie. Kilka zrzutów ekranu obrazujących problem:

 

 

Jak widać obrazek w mniejszym lub większym stopniu jest rozciągnięty, co w sumie nie powinno nas dziwić. Ale istnieje lekarstwo, a jego nazwa brzmi – nine patch.
Narzędzie zostało udostępnione razem z sdk Androida i znajduje się w folderze tools, należy uruchomić je z wiersza poleceń, nazywa się draw9patch.bat. W sieci znajduje się również kilka wersji, z jednej z nich skorzystamy, a w ten sposób wygląda narzędzie dostarczane razem z SDK:
My natomiast użyjemy Android Asset Studio – nine patches, dlatego, że ma nieco bardziej przejrzysty interfejs. Ogólnie w naszym przypadku nie ma nic skomplikowanego, zacząłem od zmiany rozmiaru tej belki, ustawiłem go na 100×1000 px, oraz lekkiego wyrównania krawędzi. Następnie wrzuciłem na stronę internetową, i ustawiłem odpowiednio rozciąganie, tak to wyglądało:
Cała logika opiera się na tym, że odpowiednie obiekty rozciągają się w różne strony, według takiego schematu.
Jak widać mamy tutaj 9 obszarów, strzałki oznaczają kierunki rozciągania, z kolei X, oznacza, że obraz w tym miejscu się nie zmienia. Pliki typu nine-path od zwykłych png różnią się dodatkowy rozszerzeniem .9 po nazwie pliku, system Android traktuje je jak zwykłe grafiki. Po pobraniu i podmianie plików otrzymałem taki efekt:

 

Problem udało się rozwiązać, zajęło to dosłownie chwilkę, a znacznie poprawia wizualne doznania użytkowników 😉
Pozdrawiam!

#2 Nie dla metody Copiego-Paste’a, czyli ponowne użycie layoutów w Androidzie

Możliwość ponownego użycia fragmentu kodu, funkcjonalności jest jedną z wytycznych tworzenia dobrego, obiektowego oprogramowania. Znamy klasy, z których możemy dziedziczyć (btw, wiecie jaki jest najlepszy obiektowy sposób zdobycia fortuny? Dziedziczenie :D), znamy interfejsy, przeciążanie itd. Logicznie podobne podejście możemy zastosować tworząc interfejsy użytkownika w androidzie.

Zaczynamy od najmniejszego elementu który chcemy wykorzystać, czyli w przypadku mojej aplikacji, był to ogólny typ: View (przynajmniej na razie, finalnie pewnie zostanie zastąpiony jakimś ImageView). Dla tego typu View, który w aplikacji będzie symbolizował pojedynczą belkę tworzymy odpowiedni styl (styles.xml), u mnie wyglądało to tak:

    <style name=”BricksStyle” parent=”AppTheme”>
        <item name=”android:layout_width”>match_parent</item>
        <item name=”android:layout_height”>wrap_content</item>
        <item name=”android:layout_weight”>1</item>
        <item name=”android:background”>@color/colorAccent</item>
        <item name=”android:layout_margin”>5dp</item>
        <item name=”android:visibility”>invisible</item>
    </style>

Warto korzystać ze stylów nawet kiedy mamy mieć dwa takie same przyciski w aplikacji, dzięki temu zmiana jednego parametru, będzie następowała w jednym miejscu. Ja będę miał naprawdę sporo tych obiektów, dlatego chociażby zmiana parametru visibility w jednym miejscu zamiast stu, pozwala mi podejrzeć aplikację na podglądzie w android studio. Przed zbudowaniem aplikacji też wystarczy zmiana tylko w tym jednym miejscu, żeby zachować jej logikę działania. Gdybym chciał zmienić kolor belek, to znowu tylko jedna linia kodu. A oto jak wykorzystałem ten styl:

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:id=”@+id/container”
    android:layout_width=”match_parent”
    android:layout_height=”wrap_content”
    android:orientation=”vertical”>

    <View
        android:id=”@+id/brick10V”
        style=”@style/BricksStyle” />

    <View
        android:id=”@+id/brick9V”
        style=”@style/BricksStyle” />

    <View
        android:id=”@+id/brick8V”
        style=”@style/BricksStyle” />

Jak widać, zamiast do każdego obiektu View wklepywać to samo, wpisuję tylko jedną linię kodu.

Ok, a jak tego użyć we właściwym activiti layoucie? Korzystamy z dyrektywy include, która może przyjmować parametry takie jakie dostarcza nam właściwy layout. Oto jakie efekty udało mi się osiągnąć:


A oto jak wygląda fragment layoutu:

    <include
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        layout=”@layout/stack_bricks_layout”
        android:layout_above=”@+id/lineTV”
        android:layout_alignParentStart=”true”
        android:layout_marginLeft=”15dp”
        android:layout_marginRight=”15dp”
        android:layout_toStartOf=”@+id/ITV”
        android:layout_below=”@+id/plusLeftBtn”
        android:id=”@+id/includeLeftStack” />

    <include
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        layout=”@layout/stack_bricks_layout”
        android:layout_above=”@+id/lineTV”
        android:layout_alignParentEnd=”true”
        android:layout_marginLeft=”15dp”
        android:layout_marginRight=”15dp”
        android:layout_toEndOf=”@+id/ITV”
        android:id=”@+id/includeRightStack”

        android:layout_below=”@+id/minusRightBtn” />


Jak widać, zawiera ona dwie dyrektywy include, które działają z tymi przyciskami do góry (plus i minus z prawej i lewej strony). I tutaj dochodzimy do sedna problemu. Mamy po dwa takie same identyfikatory na jednym activiti-layoucie.  Tzn np: @+id/brick1V po prawej i po lewej stronie, w jaki sposób przyciski odróżniają, do którego layoutu mają dodawać i odejmować? Działa to w ten sposób, że łączymy się z każdym z tych layoutów dzięki identyfikatorowi dyrektywy include. Znowu będę posiłkował się kodem:
    public View[] getBricksStack(View container)
    {
        View bricks1 = container.findViewById(R.id.brick1V);
        View bricks10 = container.findViewById(R.id.brick10V);
        return new View[]{null, bricks1, bricks2, bricks3, bricks4, bricks5, bricks6,
                bricks7, bricks8, bricks9, bricks10};
    }


    public void refreshView(int counter, View[] bricksArray)
    {
        for(int i = 1; i<=10; i++)
        {
            if(i<=counter)
                bricksArray[i].setVisibility(View.VISIBLE);
            else
                bricksArray[i].setVisibility(View.INVISIBLE);
        }
    }

    private View[] bricksLeftArray;
    private View[] bricksRightArray;
    StackBricksViewGroup stackBricksViewGroup = new StackBricksViewGroup();
        View stackBricksContainerLeft = findViewById(R.id.includeLeftStack);
        View stackBricksContainerRight = findViewById(R.id.includeRightStack);
        bricksLeftArray = stackBricksViewGroup.getBricksStack(stackBricksContainerLeft);
        bricksRightArray = stackBricksViewGroup.getBricksStack(stackBricksContainerRight);

Zastosowanie tego typu podejścia znacznie ogranicza potrzeby kopiowania kodu, możemy stworzyć wielopoziomowy layout i wykorzystywać go w naprawdę fajny sposób, dzięki czemu zmian będziemy dokonywali zawsze tylko w jednym miejscu.

Na ten moment zrezygnowałem z korzystania z fragmentów w aplikacji, w następnym wpisie spróbuję pokazać jak poprawić animację pojawiania się naszego obiektu, jeszcze nigdy tego nie robiłem 😉

PS. Pozwolę sobie na pochwalenie się statystykami od kiedy wystartowałem w tym konkursie 😉

Może w dobie internetu, gdzie zdjęcie z kotem zdobywa milion odsłon to nie dużo, nie mniej dla mnie, to aż 100 osób które interesowało to co mam zaoferowania. Nabrałem ochoty stworzyć post który będzie miał o wiele lepszą jakość, niż zwykła notka. Chcę to robić lepiej, ponieważ ktoś chce to czytać. Dzięki! 😉
Pozdrawiam!

Zmiana density (dpi) w androidzie bez roota

Dzisiaj opiszę jak zmienić DPI bez rootowania telefonu i utraty danych. Wbrew pozorom jest bardzo proste, ale miałem pewne problemy korzystając z tej metody z niektórymi aplikacjami(np. Swiftkey), z kolei klasycznie, przestawiając w pliku build.prop było w porządku. Cóż, ten sposób jest dobry, kiedy szukamy idealnego ustawienia dla siebie 😉 pozwala szybko się przestawiać. Nie mniej, warto ustawić interesujące nas DPI i uruchomić kilka aplikacji, zobaczyć, czy wyglądają i działają w porządku. Warto też pamiętać o tym, że widgety głupieją i czasem znikną z ekranu, tak samo jak foldery z aplikacjami (najczęściej zdarza się to przy zmianie w górę czyli z mniejszej cyfry na większą). Dla porządku napiszę, żadnej odpowiedzialności z mojej strony za cokolwiek. Zmiany na własną odpowiedzialność. Zaczynamy:

1. Aby zadziałało muszą być zainstalowane sterowniki adb, telefon musi mieć włączone debugowanie, oraz oczywiście musi być widoczny w systemie
2. Uruchamiamy wiersz polecenia jako administrator
3. Komenda adb devices zwraca nam informację o podłączonych urządzeniach, najlepiej, żeby podłączone było jedno i żadnych emulatorów
4. Wpisujemy: adb shell wm density 480 && adb reboot 
5. 480 możemy zastąpić liczbą dpi jakie nas interesuje
5. Jeśli zadziałało, telefon uruchomi się od nowa ze zmienionym dpi
5. Operację możemy powtarzać wielokrotnie, aż do uzyskania interesującego wyniku.
6. Jeśli się rozmyślimy i będziemy chcieli przywrócić standardowe dpi, czyli to zapisane w pliku build.prop: adb shell wm density reset && adb reboot

Tak wygląda cała instrukcja, łatwizna prawda? 😉 Efekty zmian można obejrzeć poniżej:

klasyczne DPI Nexus 5, czyli 480 (klasyczne fullHD)
dpi 350, jak widać zmieniła się nam siatka na 5 aplikacji w poziomie

 

dpi 400, ustawione w moim telefonie, wg mnie wygląda najlepiej na Nexusie 5.
Noo i na koniec, co tak właściwie oznacza DPI? Otóż jest to skrót od „dots per inch”, czyli punkty na cal. Oznacza jaka ilość pikseli przypada na cal powierzchni w naszym urządzeniu. Są do tego odpowiednie standardy, ale modyfikacja tych wartości naprawdę może poprawić wygląd i przyjemność korzystania z naszych urządzeń.
Pozdrawiam!

Android 6.0 Marshmallow, nowości, trzy zgrzyty + dwa fixy. Multiwindow, a także density.

Premiera finalnego wydania Androida Marshmallow już za nami, emocje opadły, dla porządku wrzucę główne nowości:

– nowa kontrola uprawnień (np można zainstalować facebooka i zabronić mu przeglądania kontaktów), a nie tak jak kiedyś, jeśli instalujesz aplikację, zgadzasz się na wszystko
– doze, czyli lepsze zarządzanie baterią, tzn telefon uczy się kiedy go nie używasz i w tym czasie nie zbiera powiadomień, znacznie ogranicza ruch w sieci i w ten sposób oszczędza baterię
– kopie zapasowe ustawień, w tym momencie więcej rzeczy jest przechowywanych na serwerze Google, wystarczy tylko zalogować się do aplikacji i dane się synchronizują.
– lepsza edycja tekstu, z poziomu zaznaczenia możliwość włączenia np. tłumacza
– natywne wsparcie czytnika linii papilarnych

I w sumie..tyle. Zaraz, zaraz, czegoś tutaj brakuje:
W wersjach developerskich mieliśmy przecież multiwindow. A do tego był zapowiedziany Now on tap. Z rzeczy które mnie jeszcze osobiście denerwują jest density na poziomie 480. Wszystkie elementy designu są olbrzymie.

Co z Now on tap? Niestety, nie dostępne w naszym kraju. Szkoda, funkcja naprawdę fajna, natychmiastowe wyszukiwanie danych w zależności od kontekstu ekranu. Np, pytam żony, czy może pójdzie na pizzę, ona pyta gdzie, a ja przytrzymuję klawisz home i już wiem, gdzie są najbliżej zjem pizzę. Szkoda, niestety musimy poczekać.

Co z density? Cóż jest pewien sposób na zmianę, który działa zawsze, ale jest niestabilny (kiedyś go opiszę). Pozostaje edycja pliku build.prop.

A co z multiwindow? Otóż udało mi się znaleźć sposób, opisuje jak tego dokonać (oczywiście, nie biorę odpowiedzialności za ewentualne uszkodzenia itp, etc…).

Aby zacząć w komputerze muszą znajdować się sterowniki do fastboot, komputer musi być podłączony przez usb. Sposób nie wymaga roota.

1. Instalujemy Androida 6.0, (testowałem ten sposób na Nexusie 5)
2. Uruchamiamy telefon w trybie bootloader (POWER+VOL DOWN lub fastboot reboot-bootloader)
3. Instalujemy custom recovery, konkretnie TWRP, podaję link do TWRP dla Nexusa 5
3.1 Ważne, aby zaraz po zainstalowaniu, wybrać z menu Bootloadera opcję recovery, inaczej Google usunie nam naszego customowego i wrzuci swojego zaraz przy pierwszym uruchomieniu
3.2 Uwaga, po zakończeniu wszystkich operacji, po wychodzeniu z recovery twrp pyta się, czy zrootować telefon, cóż w wersji twrp-2.8.7.1 ta opcja powoduje bootloop (sprawdzone empirycznie)
4. W menu recovery wybieramy Mounts i klikamy na System
5. Jeśli nie odpalona to odpalamy konsolę, np klikając Shift+PPM i wybierając opcję: „otwórz okno polecenia tutaj”
6. W wierszu polecenia wywołujemy:
adb pull /system/build.prop
7. To polecenie skopiuje nam z telefonu do miejsca gdzie otwarliśmy konsolę plik build.prop, nie zamykamy konsoli
8. Edytujemy plik build.prop jak tekst (osobiście używam i polecam Notepad++)
9. Znajdujemy takie linie:
ro.sf.lcd_density=480
ro.build.type=user
10. Edycja pierwszej z nich pozwala na zmianę density (moja ulubiona wartość to 400)
11. Edycja drugiej z user na userdebug spowoduje, że w opcjach programistycznych, po włączeniu urządzenia pojawi się coś takiego (zwróćcie uwagę na inny kształt menu, tak się prezentuje density 400):


12. Zapisujemy plik
13. W konsoli wywołujemy po kolei:
adb push build.prop /system/
adb shell
cd system
chmod 644 build.prop
14. Uruchamiamy urządzenie normalnie
15. Po włączeniu w opcjach programistycznych cieszymy się multiwindow!

Należy pamiętać, że multiwindow jest w dalszym ciągu opcją rozwojową, w związku z tym mogą zdarzać się problemy (czytałem, że czasem battery drain).

Po tych poprawkach jest już trochę lepiej, nie mniej dalej brakuje motywów, czy możliwości edycji ikon na pasku. Cóż, czekamy na dalszy rozwój 😉

Pozdrawiam!

Jak zrobić piękną aplikację

Na pewno każdy już zauważył następującą tendencję, że im aplikacja jest ładniejsza, tym ma więcej pobrań. Content jest oczywiście bardzo ważny, ale o wiele lepiej nam korzystać z czegoś co jest przyciąga wzrok, nie jednokrotnie godząc się nawet z częściowym ukryciem potrzebnej funkcjonalności pod jakąś piękną animacją. Czasem jednak coś jest piękne, ale bezużyteczne. Ważne, aby znaleźć złoty środek pomiędzy tymi dwoma wartościami. Ale nie o tym chciałem pisać. Pytanie które chciałem dzisiaj zadać, to jak ważny jest design dla programisty Android? Odpowiedź: coraz ważniejszy. Nie każdy ma jednak talent plastyczny, aby stworzyć piękną grafikę. Ja osobiście, mam taki problem, często wychodzą mi jakieś niedopasowane kolorami i kształtami szkarady. Jednak jest na to sposób, gotowce. Użyłem jednego w swojej poprzedniej aplikacji, dlatego chciałem dzisiaj przedstawić kilka przykładów, oraz podać miejsca gdzie szukać inspiracji.
Zaczynamy od animacji której sam osobiście użyłem ostatnio, czyli:

Ten twórca stworzył jeszcze jedną, bardzo podobną:

Prawda, że są ładne? Znalazłem je na stronie android-arsenal. Godnym polecenia miejscem, gdzie możemy szukać jest również strona dribbble. O to dwa piękne cuda które tam znalazłem:

Implementacja tego typu rozwiązań jest najczęściej bardzo prosta. I stosunkowo niewielkim kosztem można naprawdę bardzo polepszyć wygląd swojej aplikacji. Przy czym jak pisałem we wstępie, nie należy zapominać o funkcjonalności 😉
Pozdrawiam!