Archive

Posts Tagged ‘API’

BlipiNET 2.0

February 11th, 2010

Marek Foss od Blipi.pl zaktualizował dziś API do wersji 2.0 wprowadzając kilka ulepszeń. Co za tym idzie zaktualizowałem także BlipiNET.

Zmiany w najnowszej wersji:

  • klucz API wymagany jest tylko do wyszukiwania, reszta metod go nie używa
  • usunięte zostały metody GetTrackedBy oraz GetRank
  • powyższe metody zastąpiła metoda GetStats która zwraca pełne statystyki użytkownika: liczba obserwujących, zmiana liczby obserwujących, liczba obserwowanych, zmiana liczby obserwowanych, liczba cytowań, liczba wzmianek, ranking i zmiana rankingu

Ponieważ aktualnie pracuje nad zmianami w Pocket Blip już można zobaczyć roboczą wersję widoku profilu użytkownika:

Marek na Blipie zdradził także, że pracuje nad udostępnieniem trendów w API.

Jakub Florczyk .NET, BlipiNET, Compact Framework, Windows Forms , , , , , , ,

SamsungMobileSDKNET

January 3rd, 2010

Żeby nie było, iż jestem jednostronny to dla odmiany dziś o firmie Samsung. I o jego w moim mniemaniu cudownym dziecku Samsung Windows Mobile SDK.

Na początek małe wytknięcie pięty achillesowej firmy HTC. Otóż mimo iż produkują świetne telefony, z najlepszymy nakładkami i oprogramowaniem, to ogromnym minusem jest brak jakiegokolwiek SDK dla bibliotek HTC.
Oczywiście podstawową część obsługi telefonu możemy załatwić standardowymi bibliotekami .NET / Tapi/ ExTapi / RIL ale często te najsmaczniejsze kąski siedzą w warstwach do których HTC nas nie chce dopuścić. I do dziś się zastanawiam dlaczego.
O tyle dobrze, że niektórym udało się dostać to obsługi akcelerometru i LED-ów HTC o tyle kamera np. nadal jest jedną wielką zagadką i dostęp do surowych danych a nie ubranych w jakieś okienka Microsoftu.

Z drugiej strony pojawia się firma Samsung i udostępnia pełne SDK do funkcji telefonu. Pisząc pełne, mam na myśli: akcelerometr, kamerę, lampę kamery, radio, led, haptics, czujnik światła, mysz optyczną, orientację 2D i 3D, czujnik zbliżeniowy, procesor audio, slider-a, wyjście TV, wibrację i kółko nawigacji. Jeżeli jeszcze ci szczęka nie opadła, to jest właśnie dobry moment.

Samsung całość udostępnił jako SDK, które można pobrać tutaj. Biblioteki są przygotowane pod C++ z jednym przykładem natywnym.

Jako, że nie mogłem znaleźć wrappera z pełną implementacją, postanowiłem go napisać samemu. Biblioteka dostępna jest na CodePlex SamsungMobileSDKNET. Na obecną chwilę zawiera pełną implementację wersji 2.1. Ale ponieważ nie posiadam telefonu Samsunga, żaden element nie jest przetestowany. Dlatego prośba dla programistów z telefonami Samsunga o przetestowanie poszczególnych elementów. No chyba, że wcześniej z Orange-a wezmę Samsunga Omnia II – bo ostatnio mi proponowali nawet w rozsądnej cenie i sam przetestuje poszczególne elementy.

Jakub Florczyk .NET, Compact Framework, SamsungMobileSDKNET , , , , , , , ,

RilNET – Radio Interface Layer (RIL) .NET wrapper – sprostowanie

January 3rd, 2010

A propos artykułu RilNET – Radio Interface Layer (RIL) .NET wrapper należy się drobne sprostowanie działania biblioteki a przede wszystkim obsługi lokalizacji.

Otóż po wielu testach na telefonach firm HP i HTC oraz po przeczytaniu kilku artykułów w sieci wszystkim osobom, które używają RIL-a należy się małe wyjaśnienie o którym nie zdawałem sobie sprawy w momencie pisania wpisu.

Otóż implementacja biblioteki RIL zależy od producenta telefonu. Sprowadza się to do tego, iż część funkcji może nie być w ogóle zaimplementowana!

W praktyce wygląda to tak, iż mój wysłużony HP 614C nie posiadał zaimplementowanej metody udostępniającej informację o komórce sieci  GetCellTowerInfo przez co w artykule błędnie zasugerowałem, że to pewnie wina sieci Orange.
Po zamianie i testach na HP Touch Pro2 wszystko działa poprawnie. Funkcja zwraca informacje o sieci!

Oczywiście można sobie zadać pytanie: no i co z tego? Otóż wbrew pozorom bardzo wiele. Chociażby to, że Google Maps potrafi obsługiwać RIL-a i jest w stanie określić waszą przybliżoną pozycję na podstawie wieży komórkowej.

Podsumowując. Jest to kolejny powód aby kupować telefony poważnych firm. Choć HP kiedyś bardzo się starało w sprawie PocketPC, obecnie daleko im do czołówki i standardów króla HTC.

Jakub Florczyk .NET, Compact Framework, RilNET , , , , , , , ,

BlipiNET

December 23rd, 2009

W nowej wersji Pocket Blip pracuję nad zmianą dostawcy wyszukiwarki oraz statystykami użytkowników. Wybór dostawcy padł na Blipi Marka Fossa, ponieważ poza wyszukiwarką Marek udostępnia też ranking i licznik obserwujących. Z tego powodu powodu popełniłem bibliotekę dostępową .NET do API. Projekt można znaleźć na CodePlex BlipiNET.

Jak w przypadku innych bibliotek zdecydowałem się na “toporne” metody HttpWebRequest ze względu na brak nowych rozwiązań a’la WCF w wersji Json w Compact Framework.

Przykłady użycia:

// Wyszukiwanie wiadomości
BlipiService bs = new BlipiService("[twój klucz API]");
Message[] messages = bs.Search("jakubflorczyk");
// Ranking (Top100)
BlipiService bs = new BlipiService("[twój klucz API]");
User userRank = bs.GetRank("jakubflorczyk");

Dostępna jest pełna implementacja aktualnego API:
- wyszukiwanie
- pobieranie rankingu użytkownika
- pobieranie licznika obserwujących użytkownika
- pobieranie statystyk Top 10 i 100

Jakub Florczyk .NET, BlipiNET, Compact Framework, Windows Forms , , , , , , ,

FlakerNET 2.0

August 3rd, 2009

Zaktualizowałem FlakerNET do ostatnich zmian API wprowadzonych przez twórców Flakera.

Nowe funkcjonalności to m.in.:
- pobieranie obserwowanych
- pobieranie obserwujących
- pobieranie wiadomości obserwowanych tagów
- pobieranie wiadomości przyjaciół
- wyszukiwanie
- itp.

Jakub Florczyk .NET, Compact Framework, FlakerNET, Windows Forms , , , , , , ,

FlakerNET 1.0

July 6th, 2009

Powiedziałem “a” trzeba powiedzieć “b” i po BlipNet popełniłem bibliotekę dostępową do API Flakera. Projekt można znaleźć na CodePlex FlakerNET.

Jak w przypadku BlipNet zdecydowałem się na “toporne” metody HttpWebRequest ze względu na brak nowych rozwiązań a’la WCF w wersji Json w Compact Framework.

Przykłady użycia:

// Flakosfera
Entry[] entires = new FlakerService().GetFlakosphere();
// Dodanie wpisu
new FlakerService("login", "password").AddEntry("Hello world!");

Dostępna jest pełna implementacja aktualnego API, m.in.:
- pobieranie flakosfery
- dodawanie wiadomości z linkami i zdjęciami
- pobieranie użytkowników
- pobierania przyjaciół
- pobieranie ulubionych wpisów
- sprawdzanie autoryzacji
- dodawanie / usuwanie ulubionych
- traker
- itd.

Jakub Florczyk .NET, Compact Framework, FlakerNET, Windows Forms , , , , , , ,

RilNET – Radio Interface Layer (RIL) .NET wrapper

June 18th, 2009

Długo się zanosiłem z wrapperem na RIL-a i zawsze mi brakowało czasu, ale może od początku…

Dla niezorientowanych Radio Interface Layer jest warstwą łączącą hardware telefonu z oprogramowaniem. Pisząc hardware mam na myśli część telefonu Windows Mobile odpowiedzialną za wykonywanie połączeń i transfer danych do stacji komórkowych (Radio). Z punktu widzenia programisty nic poniżej RIL-a już nie ma poza samym sprzętem. Więcej o samym systemie można poczytać na http://msdn.microsoft.com/en-us/library/aa920475.aspx.

Poniżej schemat architektury w Windows Mobile (RIL występuje także w Windows CE):

RIL WM Architecture

Jeżeli czytasz ten tekst pewnie zadasz pytanie “po co to komu?”. Z punktu widzenia CF mamy dostępne wrappery Microsoftu pozwalające na wykonywanie połączeń, wysyłanie SMS-ów, obsługę książki telefonicznej itp. Z punktu widzenia telefonu posiadamy jeszcze Tapi oraz ExTapi. A więc po co?

Otóż tak jak napisałem wcześniej RIL jest najniższą warstwą a więc pozwala na rzeczy na które wyższe warstwy nigdy nie zezwolą. Przy użyciu RIL-a możemy pobrać informację o  wieży komórkowej, możemy zarządzać kartą SIM, możemy wysyłać komendy AT, itp.

RIL pozwala na dwa sposoby odwołań:

  • Podłączenie się do systemu notyfikacji, przez co dostaniemy każde zdarzenie które wygeneruje Radio
  • Wysyłanie zapytań do systemu, przez co możemy uzyskać dowolną informację z Radio

Poniżej prosty przykład użycia:

int hrCo, hrCti, hrEi;

int hr = Ril.Initialize(1, new RILRESULTCALLBACK(RilResultCallback), new RILNOTIFYCALLBACK(RilNotifyCallback), RIL_NCLASS.ALL, 0, out hRil);

// you can bind only to RilResultCallback
// int hr = Ril.Initialize(1, new RILRESULTCALLBACK(RilResultCallback), null, 0, 0, out hRil);
// or only to or RilNotifyCallback
// int hr = Ril.Initialize(1, null, new RILNOTIFYCALLBACK(RilNotifyCallback), RIL_NCLASS.ALL, 0, out hRil);

hrCti = Ril.GetCellTowerInfo(hRil);
hrCo = Ril.GetCurrentOperator(hRil, RIL_OPFORMAT.LONG);
hrEi = Ril.GetEquipmentInfo(hRil);
hr = Ril.Deinitialize(hRil);

// after call some method remember to save returned HRESULT and compare it to hrCmdID in RilResultCallback

private void RilResultCallback(
    uint dwCode,
    int hrCmdID,
    IntPtr lpData,
    uint cbData,
    uint dwParam)
{
    if (hrCo == hrCmdID)
    {
        //Ril.GetCurrentOperator
        RILOPERATORNAMES pOperatorNames = (RILOPERATORNAMES)Marshal.PtrToStructure(lpData, typeof(RILOPERATORNAMES));

        if ((pOperatorNames.dwParams & RIL_PARAM_ON.LONGNAME) == RIL_PARAM_ON.LONGNAME) // check that LongName member is valid
        {
            string longName = Encoding.ASCII.GetString(pOperatorNames.szLongName, 0, pOperatorNames.szLongName.Length).Replace("\0", "");
        }
    }

    if (hrCti == hrCmdID)
    {
        //Ril.GetCellTowerInfo
        RILCELLTOWERINFO pCellTowerInfo = (RILCELLTOWERINFO)Marshal.PtrToStructure(lpData, typeof(RILCELLTOWERINFO));
    }

    if (hrEi == hrCmdID)
    {
        //Ril.GetEquipmentInfo
        RILEQUIPMENTINFO pEquipmentInfo = (RILEQUIPMENTINFO)Marshal.PtrToStructure(lpData, typeof(RILEQUIPMENTINFO));

        if ((pEquipmentInfo.dwParams & RIL_PARAM_EI.MANUFACTURER) == RIL_PARAM_EI.MANUFACTURER)
        {
            string manufacturer = Encoding.ASCII.GetString(pEquipmentInfo.szManufacturer, 0, pEquipmentInfo.szManufacturer.Length).Replace("\0", "");
        }

        if ((pEquipmentInfo.dwParams & RIL_PARAM_EI.MODEL) == RIL_PARAM_EI.MODEL)
        {
            string model = Encoding.ASCII.GetString(pEquipmentInfo.szModel, 0, pEquipmentInfo.szModel.Length).Replace("\0", "");
        }

        if ((pEquipmentInfo.dwParams & RIL_PARAM_EI.REVISION) == RIL_PARAM_EI.REVISION)
        {
            string revision = Encoding.ASCII.GetString(pEquipmentInfo.szRevision, 0, pEquipmentInfo.szRevision.Length).Replace("\0", "");
        }

        if ((pEquipmentInfo.dwParams & RIL_PARAM_EI.SERIALNUMBER) == RIL_PARAM_EI.SERIALNUMBER)
        {
            string serialNumber = Encoding.ASCII.GetString(pEquipmentInfo.szSerialNumber, 0, pEquipmentInfo.szSerialNumber.Length).Replace("\0", "");
        }
    }
}

public void RilNotifyCallback(
    uint dwCode,
    IntPtr lpData,
    uint cbData,
    uint dwParam)
{
    RIL_NCLASS dwClass = ((RIL_NCLASS)dwCode & RIL_NCLASS.ALL);

    Debug.WriteLine("NotifyCallback: " + dwClass.ToString());

    switch ((RIL_NOTIFY_RADIOSTATE)dwCode)
    {
        case RIL_NOTIFY_RADIOSTATE.RADIOEQUIPMENTSTATECHANGED:
        {
            RILEQUIPMENTSTATE pState = (RILEQUIPMENTSTATE)Marshal.PtrToStructure(lpData, typeof(RILEQUIPMENTSTATE));

            Debug.WriteLine(String.Format("Radio Support: {0}; equipment State: {1}; ready State: {2}",
                           pState.dwRadioSupport, pState.dwEqState, pState.dwReadyState));

            break;
        }
        case RIL_NOTIFY_RADIOSTATE.RADIOPRESENCECHANGED:
        {
            RIL_RADIOPRESENCE dwPresence = (RIL_RADIOPRESENCE)Marshal.ReadInt32(lpData);

            switch (dwPresence)
            {
                case RIL_RADIOPRESENCE.NOTPRESENT:
                    Debug.WriteLine("Radio module is not present");
                    break;
                case RIL_RADIOPRESENCE.PRESENT:
                    Debug.WriteLine("Radio module is present");
                    break;
            }

            break;
        }
    }
}

W przypadku gdy podłączamy się do notyfikacji musimy określić jakie notyfikacje nas interesują oraz musimy zdefiniować funkcję która będzie je odbierać. Po odebraniu zdarzenia musimy przy pomocy enumeratorów “rozwiązać” typ zdarzenia oraz zinterpretować dane. System jest tak zorganizowany, że z danymi przychodzi wskaźnik który w większości przypadków wskazuje na strukturę w której dodatkowo są zapisane informacje przy pomocy “flagowego” enumeratora o poprawności poszczególnych pól w tej strukturze.

W przypadku gdy wysyłamy zapytania po odwołaniu do funkcji musimy zapamiętać uchwyt, który funkcja zwraca a następnie w metodzie obsługującej musimy go porównać z uchwytem który uzyskujemy od urządzenia. Po tej operacji wskaźnik możemy skonwertować do odpowiedniego typu danych i podobnie jak poprzednio, odpowiednie pole wskazuje poprawność poszczególnych pól w strukturze.

Dla wszystkich osób zainteresowanych określaniem pozycji według stacji nadawczych mam złe wiadomości. Otóż w mojej sieci Orange, system zwraca błąd o braku wsparcia ze strony sieci. Może to wina miejsca w którym mieszkam a może tak jest wszędzie. Jak przetestuje to w kilku lokalizacjach to udostępnie podsumowanie.

Projekt dostępny jest oczywiście na CodePlex RilNET

Jakub Florczyk .NET, Compact Framework, RilNET , , , , , , , ,

BlipNet 0.2.2.2

May 21st, 2009

Kolejna paczka drobnych poprawek w BlipNet. Zmiany obejmują implementację stronicowania kokpitu, poprawki na pobieranie statusów oraz literówki.

Jakub Florczyk .NET, BlipNet, Compact Framework, Windows Forms , , , , , , ,

BlipNet 0.2.2.1

April 21st, 2009

Drobne poprawki w BlipNet. Zmiany obejmują błędną nazwę metody do subskrypcji użytkowników oraz kosmetyczne zmiany w plikach projektów.

Jakub Florczyk .NET, BlipNet, Compact Framework, Windows Forms , , , , , , ,

BlipNet 0.2.2.0

April 2nd, 2009

Kolejna odsłona BlipNet-a. Poprawki względem poprzedniej wersji obejmują tylko polskie kodowanie znaków. Błąd ten wyłapał Marcin Bujacz przy okazji testowania BlipMobile-a.
Na release BlipMobile z poprawnym kodowaniem niestety przyjdzie trochę poczekać, bo chciałem wprowadzić kilka zmian zaproponowanych przez Marcina.

Jakub Florczyk .NET, BlipNet, Compact Framework, Windows Forms , , , , , , ,