jump to navigation

Visual Studio for Mac, cho phép lập trình ứng dụng trên nhiều nền tảng 17/05/2017

Posted by banghn in android, programming, iphone programming, lập trình, lập trình android, lập trình mobile, MacOS, Mobile Development, programming, Sử dụng Tools.
add a comment

Mới đây Microsoft cho ra mắt Visual Studio cho MacOS, và cho phép lập trình viên phát triển ứng dụng trên nhiều nền tảng. Sau nhiều lần thử nghiệm thì Microsoft cũng đã phát hành bản chính thức.

Screen-Shot-2017-04-25-at-2.05.30-PM

Theo Microsoft thì bộ Studio được thiết kế (design) native với MacOS, cho phép các nhà phát triển ứng dụng quản lý được việc lưu trữ với nhiều nền tảng cung cấp khác nhau (Như Github, Visual Studio Team Services,..)  Các nhà phát triển có thể phát triển tinh chỉnh các nền tảng ứng dụng di động (Android, IOS) tiện lợi hơn, ngoài ra có thể phát triển các nền tảng về web với sự hỗ trợ của ASP.NET. Về mặt ngôn ngữ thì công cụ này vẫn hỗ trợ C#, F#

Người dùng có thể tải xuống ba phiên bản Visual Studio cho Mac khác nhau, bao gồm Visual Studio Community, Visual Studio Professional và Visual Studio Enterprise. Hiện tại nhận thấy bản Community cung cấp như là một dạng miễn phí cho các đối tượng sinh viên hay cá nhân, bản Professional hướng tới tổ chức phát triển nhỏ với thêm nhiều công cụ tiện ích hỗ trợ có tính phí và bản dành cho doanh nghiệp chuyên phát triển ứng dụng Enterprise với nhiều tính năng cao cấp hơn.

Các bạn có thể tham khảo thêm trên trang chủ và tìm download các bản Studio phù hợp

https://www.visualstudio.com/vs/visual-studio-mac/

[Mac OS Sierra] How to fixed: “Downloaded .app is damaged and can’t be opened” 27/02/2017

Posted by banghn in MacOS, Tìm hiểu & chia sẽ.
add a comment

Mac OS X security by default does not allow all .app extensions to be installed. At worst, it will throw an error message that the app “is damaged and can’t be opened.”

error

This error makes you believe that the downloaded app is corrupted and that there is no application that could let it open. However, sometimes this is just a security issue that can be corrected.

With old version (before version Sierra), you can fixed by the way: Goto System Preferences, choose Security & Privacy, in General Tab we need to change the Allow apps downloaded from: option to Anywhere

And now, in Sierra version Mac OS, we can fixed:

  • Open Terminal window
  • Type: sudo bash
  • [Input your password]
  • Type exactly: xattr -cr /Applications/[Your-App-name].app
  • [Enter]

Example: xattr -cr /Applications/Sketch.app

Now you can re-test your application.

Code cài đặt giải thuật PCA – Code PCA 11/08/2013

Posted by banghn in Tìm hiểu & chia sẽ.
Tags: , , , ,
2 comments
Gửi các bạn,
Sau một thời gian dài lúc trước post bài viết tổng quan nhận dạng mặt người
Rất vui khi có rất nhiều bạn quan tâm tới về đề tài này. Và có nhiều bạn hỏi về code cài đặt.
Code này mình tìm hiểu cũng qua các link trên mạng, nhưng sợ bị mất mình mang về đây. Các bạn tham khảo bên dưới.
Trang tham khảo code link gốc (Nếu vẫn còn tồn tại, không thì xem code phía dưới nhé  ^^ ).
Cài đặt giải thuật PCA:

http://c.pastebin.com/z7YmnPLf

OpenCV: Finding Faces
http://www.cognotics.com/opencv/servo_2007_series/part_2/index.html

// eigenface.c, by Robin Hewitt, 2007
//
// Example program showing how to implement eigenface with OpenCV
// Usage:
//
// First, you need some face images. I used the ORL face database.
// You can download it for free at
//    www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
//
// List the training and test face images you want to use in the
// input files train.txt and test.txt. (Example input files are provided
// in the download.) To use these input files exactly as provided, unzip
// the ORL face database, and place train.txt, test.txt, and eigenface.exe
// at the root of the unzipped database.
//
// To run the learning phase of eigenface, enter
//    eigenface train
// at the command prompt. To run the recognition phase, enter
//    eigenface test
#include <stdio.h>
#include <string.h>
#include “cv.h”
#include “cvaux.h”
#include “highgui.h”
//// Global variables
IplImage ** faceImgArr        = 0; // array of face images
CvMat    *  personNumTruthMat = 0; // array of person numbers
int nTrainFaces               = 0; // the number of training images
int nEigens                   = 0; // the number of eigenvalues
IplImage * pAvgTrainImg       = 0; // the average image
IplImage ** eigenVectArr      = 0; // eigenvectors
CvMat * eigenValMat           = 0; // eigenvalues
CvMat * projectedTrainFaceMat = 0; // projected training faces
//// Function prototypes
void learn();
void recognize();
void doPCA();
void storeTrainingData();
int  loadTrainingData(CvMat ** pTrainPersonNumMat);
int  findNearestNeighbor(float * projectedTestFace);
int  loadFaceImgArray(char * filename);
void printUsage();
//////////////////////////////////
// main()
//
void main( int argc, char** argv )
{
        // validate that an input was specified
        if( argc != 2 )
        {
                printUsage();
                return;
        }
        if( !strcmp(argv[1], “train”) ) learn();
        else if( !strcmp(argv[1], “test”) ) recognize();
        else
        {
                printf(“Unknown command: %s\n”, argv[1]);
                printUsage();
        }
}
//////////////////////////////////
// learn()
//
void learn()
{
        int i, offset;
        // load training data
        nTrainFaces = loadFaceImgArray(“train.txt”);
        if( nTrainFaces < 2 )
        {
                fprintf(stderr,
                        “Need 2 or more training faces\n”
                        “Input file contains only %d\n”, nTrainFaces);
                return;
        }
        // do PCA on the training faces
        doPCA();
        // project the training images onto the PCA subspace
        projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 );
        offset = projectedTrainFaceMat->step / sizeof(float);
        for(i=0; i<nTrainFaces; i++)
        {
                //int offset = i * nEigens;
                cvEigenDecomposite(
                        faceImgArr[i],
                        nEigens,
                        eigenVectArr,
                        0, 0,
                        pAvgTrainImg,
                        //projectedTrainFaceMat->data.fl + i*nEigens);
                        projectedTrainFaceMat->data.fl + i*offset);
        }
        // store the recognition data as an xml file
        storeTrainingData();
}
//////////////////////////////////
// recognize()
//
void recognize()
{
        int i, nTestFaces  = 0;         // the number of test images
        CvMat * trainPersonNumMat = 0;  // the person numbers during training
        float * projectedTestFace = 0;
        // load test images and ground truth for person number
        nTestFaces = loadFaceImgArray(“test.txt”);
        printf(“%d test faces loaded\n”, nTestFaces);
        // load the saved training data
        if( !loadTrainingData( &trainPersonNumMat ) ) return;
        // project the test images onto the PCA subspace
        projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
        for(i=0; i<nTestFaces; i++)
        {
                int iNearest, nearest, truth;
                // project the test image onto the PCA subspace
                cvEigenDecomposite(
                        faceImgArr[i],
                        nEigens,
                        eigenVectArr,
                        0, 0,
                        pAvgTrainImg,
                        projectedTestFace);
                iNearest = findNearestNeighbor(projectedTestFace);
                truth    = personNumTruthMat->data.i[i];
                nearest  = trainPersonNumMat->data.i[iNearest];
                printf(“nearest = %d, Truth = %d\n”, nearest, truth);
        }
}
//////////////////////////////////
// loadTrainingData()
//
int loadTrainingData(CvMat ** pTrainPersonNumMat)
{
        CvFileStorage * fileStorage;
        int i;
        // create a file-storage interface
        fileStorage = cvOpenFileStorage( “facedata.xml”, 0, CV_STORAGE_READ );
        if( !fileStorage )
        {
                fprintf(stderr, “Can’t open facedata.xml\n”);
                return 0;
        }
        nEigens = cvReadIntByName(fileStorage, 0, “nEigens”, 0);
        nTrainFaces = cvReadIntByName(fileStorage, 0, “nTrainFaces”, 0);
        *pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0, “trainPersonNumMat”, 0);
        eigenValMat  = (CvMat *)cvReadByName(fileStorage, 0, “eigenValMat”, 0);
        projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0, “projectedTrainFaceMat”, 0);
        pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0, “avgTrainImg”, 0);
        eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *));
        for(i=0; i<nEigens; i++)
        {
                char varname[200];
                sprintf( varname, “eigenVect_%d”, i );
                eigenVectArr[i] = (IplImage *)cvReadByName(fileStorage, 0, varname, 0);
        }
        // release the file-storage interface
        cvReleaseFileStorage( &fileStorage );
        return 1;
}
//////////////////////////////////
// storeTrainingData()
//
void storeTrainingData()
{
        CvFileStorage * fileStorage;
        int i;
        // create a file-storage interface
        fileStorage = cvOpenFileStorage( “facedata.xml”, 0, CV_STORAGE_WRITE );
        // store all the data
        cvWriteInt( fileStorage, “nEigens”, nEigens );
        cvWriteInt( fileStorage, “nTrainFaces”, nTrainFaces );
        cvWrite(fileStorage, “trainPersonNumMat”, personNumTruthMat, cvAttrList(0,0));
        cvWrite(fileStorage, “eigenValMat”, eigenValMat, cvAttrList(0,0));
        cvWrite(fileStorage, “projectedTrainFaceMat”, projectedTrainFaceMat, cvAttrList(0,0));
        cvWrite(fileStorage, “avgTrainImg”, pAvgTrainImg, cvAttrList(0,0));
        for(i=0; i<nEigens; i++)
        {
                char varname[200];
                sprintf( varname, “eigenVect_%d”, i );
                cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));
        }
        // release the file-storage interface
        cvReleaseFileStorage( &fileStorage );
}
//////////////////////////////////
// findNearestNeighbor()
//
int findNearestNeighbor(float * projectedTestFace)
{
        //double leastDistSq = 1e12;
        double leastDistSq = DBL_MAX;
        int i, iTrain, iNearest = 0;
        for(iTrain=0; iTrain<nTrainFaces; iTrain++)
        {
                double distSq=0;
                for(i=0; i<nEigens; i++)
                {
                        float d_i =
                                projectedTestFace[i] –
                                projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
                        //distSq += d_i*d_i / eigenValMat->data.fl[i];  // Mahalanobis
                        distSq += d_i*d_i; // Euclidean
                }
                if(distSq < leastDistSq)
                {
                        leastDistSq = distSq;
                        iNearest = iTrain;
                }
        }
        return iNearest;
}
//////////////////////////////////
// doPCA()
//
void doPCA()
{
        int i;
        CvTermCriteria calcLimit;
        CvSize faceImgSize;
        // set the number of eigenvalues to use
        nEigens = nTrainFaces-1;
        // allocate the eigenvector images
        faceImgSize.width  = faceImgArr[0]->width;
        faceImgSize.height = faceImgArr[0]->height;
        eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens);
        for(i=0; i<nEigens; i++)
                eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
        // allocate the eigenvalue array
        eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 );
        // allocate the averaged image
        pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
        // set the PCA termination criterion
        calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
        // compute average image, eigenvalues, and eigenvectors
        cvCalcEigenObjects(
                nTrainFaces,
                (void*)faceImgArr,
                (void*)eigenVectArr,
                CV_EIGOBJ_NO_CALLBACK,
                0,
                0,
                &calcLimit,
                pAvgTrainImg,
                eigenValMat->data.fl);
        cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
}
//////////////////////////////////
// loadFaceImgArray()
//
int loadFaceImgArray(char * filename)
{
        FILE * imgListFile = 0;
        char imgFilename[512];
        int iFace, nFaces=0;
        // open the input file
        if( !(imgListFile = fopen(filename, “r”)) )
        {
                fprintf(stderr, “Can\’t open file %s\n”, filename);
                return 0;
        }
        // count the number of faces
        while( fgets(imgFilename, 512, imgListFile) ) ++nFaces;
        rewind(imgListFile);
        // allocate the face-image array and person number matrix
        faceImgArr        = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
        personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
        // store the face images in an array
        for(iFace=0; iFace<nFaces; iFace++)
        {
                // read person number and name of image file
                fscanf(imgListFile,
                        “%d %s”, personNumTruthMat->data.i+iFace, imgFilename);
                // load the face image
                faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);
                if( !faceImgArr[iFace] )
                {
                        fprintf(stderr, “Can\’t load image from %s\n”, imgFilename);
                        return 0;
                }
        }
        fclose(imgListFile);
        return nFaces;
}
//////////////////////////////////
// printUsage()
//
void printUsage()
{
        printf(“Usage: eigenface <command>\n”,
               ”  Valid commands are\n”
               ”    train\n”
               ”    test\n”);
}

Tìm hiểu PhoneGap – Tạo ứng dụng đa hệ trên mobile 23/05/2012

Posted by banghn in android, Android Development, android, programming, Mobile Development, Thông tin công nghệ.
Tags: , , ,
add a comment

Hôm qua nay mình có tìm hiểu sơ một về một công nghệ viết ứng dụng trên mobile. Có thể tạo ứng theo kiểu có thể chạy trên nhiều hệ điều hành mobile khác  nhau. Gọi là Hybird app.

PhoneGap

PhoneGap

1.Tại sao lại sinh ra ứng dụng Hybird app?

Việc các thiết bị mobile ngày càng phát triển dẫn đến những khó khăn trong lập trình các ứng dụng bên trong nó:

  • Quá nhiều hệ điều hành nhiều nền tảng khác nhau.
  • Cần nhiều team để làm việc trên những hệ điều hành, nền tảng đó.
  • Với mỗi lĩnh vực cần chuyên gia có kinh nghiệp trên lĩnh vực đó.
  • Với mỗi nền tảng thì trong từng phiên bản có sự phân mảng khác nhau. Ví dụ với android tính năng này support trên android 2.2 nhưng ver < 2.2 không support….
  • Nhiều môi trường làm việc khác nhau (Window, Mac,..) Tools làm việc…

Xuất hiện các framework sử dụng html, css, js để viết các ứng dụng web mà có thể chạy trên nhiều nền tảng di động khác nhau như PhoneGap, Titanium,…. Trong đó phổ biến nhất là PhoneGap

2.PhoneGap

  • PhoneGap ra đời dựa trên công nghệ web để xây dựng các ứng dụng đi động
  • PhoneGap sử dụng HTML,CSS, và Javascript và xây dựng một bộ các API bằng java script, chương trình thiết kế giao diện bằng HTML, lập trình logic bằng javascript và chạy trong môi trường Web của thiết bị, thông qua PhoneGrap javascipt API thì ứng dụng có thể truy cập được vào những tính năng gốc của máy điện thoại.
  • Người lập trình PhoneGap phát triển chương trình mà không phụ thuộc nhiều vào ngôn ngữ của các Platform Iphone, BB,Symbian. Ứng dụng được phát triển trên IDE của platform ví dụ Iphone dùng Xcode và gói thư viện, BB xài eclipse…
Kiến trúc tổng quan Ponegap

Kiến trúc tổng quan Ponegap

Các tính năng quan trọng của PhoneGap

PhoneGap hỗ trợ truy xuất hầu hết các API của thiết bị như API camera, File, Lưu trữ SQL Lite, Media, GeoLocation…

Các API PhoneGap hỗ trợ

Các API PhoneGap hỗ trợ

Một số tính năng hạn chế của PhoneGap

Một số tính năng chung khác mà phonegap hỗ trợ và hạn chế

Một số tính năng chung khác mà phonegap hỗ trợ và hạn chế

3.Ưu điểm và hạn chế khi phát triển phonegap

Các ưu điểm

  • Một opensource free
  • Hỗ trợ trên nhiều platform iOS, Android, Window mobile, BlackBery, Symbian, webOS, bada à phát triển 1 ứng dụng có thể chạy trên nhiều nền tảng khác nhau, không cần bỏ nhiều resource riêng cho từng nền tảng ứng dụng; đồng nhất giao diện ứng dụng trên các nền tảng khác nhau.
  • Sử dụng javaScript/HTML có thể gọi tới các API native code C,C++, Java
  • Hỗ trợ gần như hầu hết tất cả các thư viện gọi tới hệ điều hành phone. (Định vị, Camera, truy cập file, database…)

 Khó khăn

  • Khó hoạt động trên các mobile browser cũ vì không hỗ trợ javascript và tốc độ chậm
  • Việc quản lý các tài nguyên sâu của thiết bị không thực hiện được như: quản lý các tiến trình(đồng bộ, bất đồng bộ), khả năng đồ họa hạn chế (3D).
  • Layout ứng dụng sẻ không phù hợp khi qua các màn hình thiết bị có độ phân giải khác nhau, và tùy thuộc vào độ hỗ trợ của trình HTML của thiết bị. vd các apps cho android trên các thiết bị khác nhau thì sẽ không rõ nét vì trên androids hỗ trợ các bộ icon cho các độ phân giải khác nhau nên rõ nét hơn.
  • Các bộ nhập liệu trên từng thiết bị không điều khiển được như: keypad, track ball, tapping,rocker …
  • Khó trong việc phát triển vì debug khó khăn
  • Tài liệu khá ít, Phonegap đang trên đà hoàn thiện vì thế nguy cơ tiềm ẩn khi phát triển ứng dụng bị stuck là điều có thể xảy ra.

4.Kết luận

  • Phonegap thích hợp để phát triển các ứng dụng không cần đòi hỏi giao diện quá cao, quá nét như các native app (vd apps quản lý bán hàng, quản lý thông tin nhân sự….)
  • Các apps thiên về xử lý native nhiều, đòi hỏi giao diện, mức độ tương tác, đa phương tiện cao và sắc nét trên từng nền tảng hơn thì không nên dùng phonegap như apps xử lý đồ họa(3D)
  • Tuy  PhoneGap có thể làm rất tốt việc tạo ra hầu hết ứng dụng, nhưng chúng không thể làm cho JavaScript chạy hiệu quả như chương trình C. Phiên bản web làm việc ổn, nhưng ứng dụng viết riêng cho thiết bị đem đến cho người dùng trải nghiệm tốt hơn mà ứng dụng web hiện nay không thể đạt được.

Bài viết chỉ mới là tìm hiểu sơ bộ về PhoneGap cũng như các công nghệ Hybird khác. Bài viết sau mình sẽ bắt đầu đi rõ hơn về kiến trúc, các API support của PhoneGap.
PhoneGap support nhiều OS khác nhau, nhưng mình sẽ chọn Android để làm việc chính với PhoneGap. Và sẽ nói cách setup môi trường làm việc, demo…

———————————————————

bloghnb

Tham khảo thêm: http://phonegap.com/

Ebook: Beginning Phonegap

Dự báo vui về năm rồng Mậu Thìn (1988) 27/01/2012

Posted by banghn in Góc cá nhân.
Tags: , , , ,
add a comment

Trước giờ ít quan tâm tới những dự đoán, dự báo như thế này. :). Nhưng lỡ đọc qua để đây thử kiểm nghiệm một năm tới cho vui.

Với tôi một năm tới mục tiêu của tôi là khắc phục, làm chủ được bản thân (không nóng nảy,  không vội vàng có thể sống chậm một tí..) và làm một việc mà 4 năm trước tôi đã từng làm và làm tốt (cái này bí mật một tí tuy không có gì ghê gớm 🙂 )

Mậu Thìn (1988), Mệnh Đại Lâm Mộc (cây ở rừng lớn)

Năm rồng

Năm rồng

Năm nay, Thiên can Mậu gặp Nhâm (Dương Thổ gặp Dương Thuỷ). Theo Ngũ hành Thổ khắc Thuỷ (khắc xuất). Người tuổi Mậu Thìn năm nay luôn là người chiến thắng, thành đạt, toại nguyện. Tuy nhiên, do là “khắc” nên phải chiến đấu giành giật mới có. Cần tránh tư tưởng “há miệng chờ sung”.

Nam: Vốn là người tự tin, khôn ngoan và nhiều tham vọng, năm nay là năm thuận, nên cố gắng gánh vác việc lớn ắt sẽ thắng lợi, giao việc lớn để thử thách. Về mặt tài chính sẽ gặt hái được nhiều nhưng trang trải cũng lớn nên “của ăn của để” chẳng được là bao. Năm dễ đi đến hôn nhân nếu không cũng có bạn gái. Nam Mậu Thìn hợp với nữ Kỷ Tỵ (1989), Quý Dậu (1993), Đinh Mão (1987). Khắc với nữ tuổi Mậu Thìn (1988), Nhâm Thân (1992), Tân Mùi (1991).

Nữ: Là người cương nghị, thẳng thắn nhưng hơi nóng nảy và “khô”. Năm nay là cơ hội về nhiều mặt, nên phải bớt nóng và ít “khô” hơn để hoà nhập, nắm bắt cơ hội thì kết quả mỹ mãn trên mọi lĩnh vực luôn chờ đón bạn. Ngoài sự nghiệp, ở tuổi này nghĩ đến chọn bạn đời và xây dựng mái ấm gia đình là điều phải tính đến. Tuổi Mậu Thìn nên tìm bạn trăm năm với nam tuổi Kỷ Tỵ (1989), Đinh Mão (1987), Ất Sửu (1985). Khắc với tuổi Bính Dần (1986), Canh Thân (1980), Tân Mùi (1991).Box:Dự báo theo tử vi thực chất là giải bài toán hàm số với nhiều tham số (biến số) đó là giới tính, giờ, ngày, tháng, năm sinh theo hệ Can chi (Hệ nhị phân). Để có được đáp số (dự đoán) chính xác không phải dễ.

Tuy nhiên, đây là cách lý giải, quy nạp có logic trật tự và mang tính hướng thiện. Bởi vậy không nên tin theo kiểu “định mệnh” không thể thay đổi mà nên hiểu đó chỉ là xu hướng của cuộc đời giúp ta biết sở trường để phát huy, sở đoản để khắc phục. Đã là dự đoán ắt có đúng, có sai đừng quá tin hay quá ngờ vực là hai thái cực “thái quá và bất cập”. Hãy cứ trải nghiệm để rút ra những điều bổ ích là điều cần thiết.

Trích từ báo: baoquangngai.com.vn

Có nên mua và sử dụng Smartphone hay không? 03/11/2011

Posted by banghn in android, Góc cá nhân, iphone.
Tags: , , ,
add a comment

Đây cũng là câu hỏi của nhiều người khi sắp mua hay muốn sử dụng một chiếc điện thoại thông minh. Và tôi trước kia cũng vậy.

Smartphone

Smartphone

Với đa số nhiều người thì nếu có điều kiện, tiền bạc thoải mái một tí thì sở hữu một chiếc điện thoại thông minh là một nhu cầu. Cũng có một vài trường hợp thì có vài ý nghĩ khác cho rằng việc dùng điện thoại thông minh không có gì khác biệt cho lắm, suy cho cùng thì cũng là nghe gọi nhắn tin… 🙂

Có thể có vài nhận xét trái chiều nhau nhưng điều nhận thấy rằng sau khi dùng một chiếc điện thoại thông minh thì hầu như ai cũng thích dùng nó cả, nó có nhiều tiện ích hấp dẫn người dùng và hỗ trợ nhiều loại người dùng.

Hầu như ai cũng thích dùng, vậy thì dùng nó mang lại lợi ích gì ?. Nhiều thứ, có thể nói như vậy và tùy vào đối tượng người dùng. Với đa số người thì điện thoại thông minh mang lại người ta nhiều điều thú vị với sự giải trí tuyệt vời (xem phim, nghe nhạc, game,…), những người muốn sử dụng điện thoại thông minh cho nhu cầu học thì nó có thể cài thêm nhiều tiện ích hỗ trợ như từ điển, các phần mềm học ngoại ngữ,… Với những người dùng cho công việc thì việc lưu trữ lịch họp, nhắc  bạn công việc, việc check mail trở nên dễ dàng hơn bao giờ…

Còn những ai thích công nghệ thì lựa chọn điện thoại thông minh để khám phá thì một điều tốt thôi, có thể cho bạn nhiều ý tưởng để xây dựng những ứng dụng tích hợp vào nó. Với tôi cũng vậy đang làm về android, sử dụng một chiếc chạy android tiếp xúc với nhiều phần mềm chạy trên đó cho tôi nhiều cảm nhận về sự tốt thuận tiện hơn khi xây dựng ứng dụng trong khi mình làm…

Đó là một số thuận tiện, ngoài ra có quá nhiều tiện ích bạn không thể biết đên khi bạn chưa sử dụng tới nó. Ví dụ tôi có vài người bạn ở nước ngoài lúc trước muốn nói chuyện thì chỉ biết tới yahoo để chat, email hay cao hơn dùng skype để nói chuyện. Nhưng dùng điện thoại chạy android tôi có thể cài Viber một phần mềm chuyên gọi điện trực tuyến thông qua internet. Tài khoản chính là số điện thoại của bạn luôn… làm cho bạn cảm giác như đang nói chuyện bình thường vậy… 🙂

Có thể cùng một chức năng như nhau nhưng điện thoại thông minh hành xử khác điện thoại phổ thông làm cho ta sẽ thích chúng.

Do vậy tôi nghĩ nếu có điều kiện thì việc bạn phân vân có nên mua và sử dụng một chiếc smartphone hay không thì tôi nghĩ không có gì phải phân vân. Chỉ là phân vân nên mua con như thế nào để vừa với kinh phí của mình. 🙂

Sử dụng ExifInterface, và cách giải quyết vấn đề khi sử dụng với android 1.6 09/09/2011

Posted by banghn in Android Development.
Tags: , , , , ,
add a comment

ExifInterface là một lớp hỗ trợ xử lý một vài thuộc tính trong việc xử hình ảnh. Nhưng nó chỉ support trên android 2.2 trở lên (API Level 5)

Ví dụ trên android, khi bạn chụp một tấm hình từ camera và load lên GUI, ở đa số phone bạn chụp hình đứng nhưng khi lưu ảnh được lưu dưới dạng ngang. Khi load ảnh lên view thì ảnh cũng bị quay ngang. Do dó ExifInterface giúp bạn kiểm tra được ảnh ban đầu được chụp như thế nào,…

Với ExifInterface bạn có thể dễ dàng kiểm tra:

ExifInterface exif = new ExifInterface(SourceFileName); //Since API Level 5

String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Tùy ảnh được chụp theo hướng nào, kết quả exifOrientation cho bạn giá trị khác nhau.

Nhưng vấn đề xảy ra nếu bạn dùng android 1.6 chẳng hạn thì bạn giải quyết làm sao khi không support được lớp ExifInterface 

Không phải lo lắng, có một thư viện khác giúp bạn được điều này. Thư viện metadata extraction library by Drew Noakes.
drewnoakes.com – jpeg exif / iptc metadata extraction in java

Sau khi bạn down thư viện về, bạn cần custom lại một tí để không bị lỗi. Nếu hơi khó khăn bạn có thể download link bên dưới. Mình đã custom lại để chạy được và rút gọn những phần không phù hợp để nhẹ hơn.

Khi sử dụng, ví dụ cũng như ví dụ trên với thư viện này bạn có thể làm như sau:

Metadata metadata;

metadata = JpegMetadataReader.read

Metadata(new File(filePath));

Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);

if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {

int rotated = exifDirectory .getInt(ExifDirectory.TAG_ORIENTATION);

}

Còn vấn đề gì, bạn có thể post lên để cùng thảo luận.
Các bạn có thể download link thư viện bên dưới:
khoinguonit.com – metadata.jar

Draw 9-patch Tutorial – Sử dụng nine patch 31/08/2011

Posted by banghn in Android Development.
Tags: , , , , , , ,
add a comment

Tool Draw 9-patch cho phép bạn tạo ảnh 9 patch dễ dàng hơn với WYSIWYG 

Tạo ảnh 9 -patch không phải quá khó, nhưng để sử dụng tools này có hiệu quả, vào tùy biến áp dụng được cho nhiều hình thì cũng có nhiều điều chúng ta cần quan tâm.

1. Sử dụng cơ bản:

Chúng ta cần một ảnh PNG

Mở tool draw9patch trong thư mục SDK /tools

Rồi bạn chỉ việc kéo thả ảnh ( mở ảnh png) để tiếp tục chỉnh sửa.

Bạn vẽ những pixel ở những vùng trên ảnh mà bạn muốn nơi nó ảnh được co giãn khi phóng to thu nhỏ mà không làm vỡ ảnh ở những chi tiết khác.

Sau khi vẽ xong bạn lưu lại với format 9.png

Chú ý: Khi bạn mở một ảnh thì chương trình xuất hiện thêm đường viền 1 pixel để bạn chấm những điểm mà bạn muốn ảnh của bạn co giản không bị vỡ.

draw9patch

draw9patch

 

2. Một số option trong tool:

  • Zoom: Zoom vùng ảnh bạn đang chỉnh sửa vẽ 9.patch.
  • Patch scale: scale vùng ảnh để xem kết quả pre-view của ảnh sau khi chấm 9.patch.
  • Show lock: lock vùng ảnh đang chỉnh sửa khi move chuột qua vùng ảnh.
  • Show patches: Hiển thị vùng ảnh stretchable.
  • Show content: Highlight vùng ảnh hiển thị  kết quả (purple is the area in which content is allowed).
  • Show bad patches: Hiển thị vùng ảnh được chọn để scale.
Optional controls include
Optional controls include
3.Vẽ nâng cao
Vẽ button
Dưới đây là hỉnh ảnh của một button đơn giản, để 9patch cho button thì chúng ta có thể để ý là không cho co giãn những góc của button. Như vậy ta có thể chọn 9.patch như sau.
9patch button

9patch button

Vẽ Spiner button
Với spiner chúng ta không muốn vỡ phần hình dấu mũi tên lựa chọn, thì chúng ta chỉ có thể cho giãn phần giữa của spiner. Có thể vẽ như sau.
9patch spiner button
9patch spiner button
Vẽ Search Edittext
Tương tự như spiner, chúng ta chỉ có thể co giãn ở phần giữa,
9patch search edittext
9patch search edittext
Nếu có hình bạn chỉ muốn co giãn phần ngoài, giữ nội dung ở giữa thì bạn chỉ chọn những pixel ở bên ngoài để co giãn phần ngoài.
test_9patch_patched

test_9patch_patched

Kết quả thu được.
Kết quả
Kết quả
Sử dụng thuần thục cách vẽ 9patch các bạn sẽ có thể custom dễ dàng hơn những control trong android. Chúc các bạn thành công!
————————————————————-
bloghnb
Tham khảo thêm: http://android10.org, higherpass.com

Custom một control trong android? 28/08/2011

Posted by banghn in Android Development.
Tags: , , ,
add a comment
Demo Custom

Demo Custom

Control trong Android có đủ để chúng ta viết ứng dụng không.?

Câu trả lời đa số có thể trả lời “Đủ”.

Vậy tại sao chúng ta lại custom nhưng control trong android.?

Ok, Dùng control trong android cung cấp hoàn toàn cho ta một ứng dụng tốt, nhưng để ứng dụng của ta khác với người khác, cùng một ứng dụng quản lý danh bạ chẳng hạn. Nếu chúng ta có những ý tưởng mới lạ từ việc những editext nhập liệu cách điệu hơn, những dialog lạ lẫm hơn,.. điều đó làm cho ứng dụng của bạn nỗi bậc hơn… gây chú ý tới người dùng hơn.

Một điều nữa, chúng ta muốn ứng dụng của ta có GUI thống nhất trên tất cả các phiên bản, các dòng điện thoại thì custom là một lựa chọn tốt cho bạn. Vì những control trong android có giao diện có thể khác nhau từ những dòng điện thoại, phiên bản android….

Tạo những custom control cần gì.

Trước hết có lẽ chúng cũng phải sử dụng được những control của android để biết chúng ta cần gì, thiếu gì từ những control chuẩn trong android. Từ đó cho ta những custom tốt hơn, phù hợp với nghiệp vụ ứng dụng của ta hơn…

Chúng ta cần biết cách custom các shape (đường viền, bo góc, gradient,…), selector(các hiệu ứng khi chọn, click,…), sử dụng 9.path để vẽ tối ưu hơn…

Các bài viết sau mình sẽ giới thiệu cách tạo một vài custom đơn giản để các bạn nào mới tiếp cận có thể có thêm những tùy biến tốt hơn cho ứng dụng của mình.

 

 

———————————————-

bloghnb

Hướng dẫn get contact list trên nhiều phiên bản OS khác nhau trên cùng ứng dụng 17/06/2011

Posted by banghn in Android Development.
Tags: , , , , , ,
add a comment

Hôm trước có đề cập tới việc lấy danh sách liên lạc (contact list trên OS 1.6). Vấn đề lấy danh bạ điện thoại thì khá đơn giản. Ở đây chỉ có một vấn đề nhỏ tí là thư viện hỗ trợ việc lấy danh bạ và thao tác trên nó khác nhau giữa OS 1.6 và sau này.

Lấy danh bạ từ từ OS 1.6 về sau

Lấy danh bạ từ từ OS 1.6 về sau

Hôm nay gửi các bạn một cách lấy danh bạ trên cả phiên bản OS 1.6 và OS sau này trên cùng một ứng dụng.

Ý tưởng, đầu tiên bạn tìm cách lấy được phiên bản sdk của bạn. Sau đó tùy từng sdk mà bạn lựa chọn gói thư viện phù hợp. Sau bước này thì bạn thao tác bình thường.

//Dinh nghia lua chon thu vien su dung get contactlist
	static {
		int sdk = new Integer(Build.VERSION.SDK).intValue();

		if (sdk >= 5) {
			try {
				Class clazz = Class
						.forName("android.provider.ContactsContract$Contacts");

				CONTENT_URI = (Uri) clazz.getField("CONTENT_URI").get(clazz);
			} catch (Throwable t) {
				Log.e("PickDemo", "Loi khi thuc hien chuyen doi CONTENT_URI", t);
			}
		} else {
			CONTENT_URI = Contacts.People.CONTENT_URI;
		}
	}
Lấy danh bạ điện thoại từ OS 1.6 về sau

Lấy danh bạ điện thoại từ OS 1.6 về sau

 

Bạn có thể download mã nguồn tại http://www.mediafire.com/file/jrw8fsqr9clmyo2/khoinguonit.com%20-%20PickContact.rar

Pass: khoinguonit.com

 

 

—————————————–

bloghnb – IT & Life