Saturday, October 15, 2016

Vòng đời ứng dụng Android - Android Life Cycle

Vòng đời của một ứng dụng Android là kiến thức cơ bản mà bất kỳ lập trình viên Android nào cần phải biết. Đây là kiến thức rất quan trọng để phát triển các ứng dụng Android
Sau đây mình xin trình bày một ứng dụng  nhỏ  Life Cycle App về vòng đời của một Android Application
Các thành phần chính của ứng dụng: 
  1. Một Toast-msg để hiện thị trạng thái của ứng dụng : onCreate, onStart, onPause, onResume, onDestry, onRestart, onStop
  2. Một EditText: cho người dùng nhập màu sắc của background
  3.  SharePreferences lưu trạng thái của ứng dụng, mỗi khi ứng dụng tắt đi bật lại sẽ lưu màu background lần cuối cùng mà người dùng nhập
  4.  Button Exit: kết thúc ứng dụng
  5. TextView: hiện thị màu background hiện tại
  6. Khi chạy chương trình, nhiệm vụ của bạn là quan sát trình tự của thông điệp hiển thị khi ứng dụng:
  • Load lần đầu tiên
  • Click HOME button
  • Click BACK hoặc Exit button
  • Chạy lại ứng dụng khi xét màu bacground
Bắt đầu code nào :D

Bước 1: 
  Tạo ứng dụng android trên Android Studio tên Life Cycle Android.  Hiện tại mình đang dùng phiên bản Android Studio 2.2.1
Bước 2: 
  Tạo giao diện cho ứng dụng trong file activity_main.xml gồm 3 thành phần: 
  • Button
  • EditText
  • TextView
activity_main.xml


 <?xml version="1.0" encoding="utf-8"?>  
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:id="@+id/activity_main"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:orientation="vertical"  
   tools:context="com.hust.tuanbk.lifecycleandroid.MainActivity">  
   <EditText  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:hint="Input Background(Red, Green, Blue, While)"  
     android:id="@+id/inputColor"/>  
   <Button  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:id="@+id/btExit"  
     android:layout_marginTop="20dp"  
     android:layout_gravity="center"  
     android:text="Exit"/>  
   <TextView  
     android:id="@+id/textView"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:text="Color"/>  
 </LinearLayout>  

Trong MainActivity.java
Có các hàm chính sau

  1. Xử lý sự kiện cho Button Exit

  2.   //set Button Event  
         btExit.setOnClickListener(new View.OnClickListener() {  
           @Override  
           public void onClick(View v) {  
             finish();  
           }  
         });  
    

  3. Lưu trạng thái của ứng dụng dùng SharePreferences

  4.   private void saveStateData(String chosenColor){  
         SharedPreferences myPrefContainer = getSharedPreferences(PREFNAME, Activity.MODE_PRIVATE);  
         SharedPreferences.Editor myPrefEditor = myPrefContainer.edit();  
         String key = "chosenBackgroundColor";  
         String value = textView.getText().toString();  
         myPrefEditor.putString(key, value);  
         myPrefEditor.commit();  
       } //save data  
    

  5. Update trạng thái của ứng dụng

  6.  private void updateMeUsingSavedStateData() {  
        // (in case it exists) use saved data telling backg color  
         SharedPreferences myPrefContainer = getSharedPreferences(PREFNAME, Activity.MODE_PRIVATE);  
         String key = "chosenBackgroundColor";  
         String defaultValue = "white";  
         if (( myPrefContainer != null ) && myPrefContainer.contains(key)){  
           String color = myPrefContainer.getString(key, defaultValue);  
           setBackgroundColor(color, myScreen);  
         }  
       }//updateMeUsingSavedStateData  
    

Ta sẽ override các hàm trạng thái của ứng dụng: show Toast trong hàm Lưu trạng thái trong hàm onPause() và update trạng thái ứng dụng trong hàm onStart()

   @Override  
   protected void onDestroy() {  
     super.onDestroy();  
     Toast.makeText(getApplicationContext(), "onDestroy", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onPause() {  
     super.onPause();  
     //save state data (background color)  
     String chosenColor = textView.getText().toString();  
     saveStateData(chosenColor);  
     Toast.makeText(getApplicationContext(), "onPause", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onRestart() {  
     super.onRestart();  
     Toast.makeText(getApplicationContext(), "onRestart", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onStart() {  
     super.onStart();  
     updateMeUsingSavedStateData();  
     Toast.makeText(getApplicationContext(), "onStart", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onStop() {  
     super.onStop();  
     Toast.makeText(getApplicationContext(), "onStop", Toast.LENGTH_LONG).show();  
   }  

MainActivity.java

 package com.hust.tuanbk.lifecycleandroid;  
 import android.app.Activity;  
 import android.content.SharedPreferences;  
 import android.os.Bundle;  
 import android.support.v7.app.AppCompatActivity;  
 import android.text.Editable;  
 import android.text.TextWatcher;  
 import android.view.View;  
 import android.widget.Button;  
 import android.widget.EditText;  
 import android.widget.LinearLayout;  
 import android.widget.TextView;  
 import android.widget.Toast;  
 import java.util.Locale;  
 public class MainActivity extends AppCompatActivity {  
   Button btExit;  
   EditText editText;  
   TextView textView;  
   LinearLayout myScreen;  
   String PREFNAME = "myPrefFile";  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
     btExit = (Button) findViewById(R.id.btExit);  
     editText = (EditText) findViewById(R.id.inputColor);  
     textView = (TextView) findViewById(R.id.textView);  
     myScreen = (LinearLayout)findViewById(R.id.activity_main);  
     //set Button Event  
     btExit.setOnClickListener(new View.OnClickListener() {  
       @Override  
       public void onClick(View v) {  
         finish();  
       }  
     });  
     editText.addTextChangedListener(new TextWatcher() {  
       @Override  
       public void beforeTextChanged(CharSequence s, int start, int count, int after) {  
       }  
       @Override  
       public void onTextChanged(CharSequence s, int start, int before, int count) {  
       }  
       @Override  
       public void afterTextChanged(Editable s) {  
         //set background to selected color  
         String chosenColor = s.toString().toLowerCase(Locale.US);  
         textView.setText(chosenColor);  
         setBackgroundColor(chosenColor, myScreen);  
       }  
     });  
     Toast.makeText(getApplicationContext(), "onCreate", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onDestroy() {  
     super.onDestroy();  
     Toast.makeText(getApplicationContext(), "onDestroy", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onPause() {  
     super.onPause();  
     //save state data (background color)  
     String chosenColor = textView.getText().toString();  
     saveStateData(chosenColor);  
     Toast.makeText(getApplicationContext(), "onPause", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onRestart() {  
     super.onRestart();  
     Toast.makeText(getApplicationContext(), "onRestart", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onStart() {  
     super.onStart();  
     updateMeUsingSavedStateData();  
     Toast.makeText(getApplicationContext(), "onStart", Toast.LENGTH_LONG).show();  
   }  
   @Override  
   protected void onStop() {  
     super.onStop();  
     Toast.makeText(getApplicationContext(), "onStop", Toast.LENGTH_LONG).show();  
   }  
   private void saveStateData(String chosenColor){  
     SharedPreferences myPrefContainer = getSharedPreferences(PREFNAME, Activity.MODE_PRIVATE);  
     SharedPreferences.Editor myPrefEditor = myPrefContainer.edit();  
     String key = "chosenBackgroundColor";  
     String value = textView.getText().toString();  
     myPrefEditor.putString(key, value);  
     myPrefEditor.commit();  
   } //save data  
   private void updateMeUsingSavedStateData() {  
    // (in case it exists) use saved data telling backg color  
     SharedPreferences myPrefContainer = getSharedPreferences(PREFNAME, Activity.MODE_PRIVATE);  
     String key = "chosenBackgroundColor";  
     String defaultValue = "white";  
     if (( myPrefContainer != null ) && myPrefContainer.contains(key)){  
       String color = myPrefContainer.getString(key, defaultValue);  
       setBackgroundColor(color, myScreen);  
     }  
   }//updateMeUsingSavedStateData  
   private void setBackgroundColor(String chosenColor, LinearLayout myScreen) {  
     //hex color codes: 0xAARRGGBB AA:transp, RR red, GG green, BB blue  
     if (chosenColor.contains("red"))  
       myScreen.setBackgroundColor(0xffff0000); //Color.RED  
     if (chosenColor.contains("green"))  
       myScreen.setBackgroundColor(0xff00ff00); //Color.GREEN  
     if (chosenColor.contains("blue"))  
       myScreen.setBackgroundColor(0xff0000ff); //Color.BLUE  
     if (chosenColor.contains("white"))  
       myScreen.setBackgroundColor(0xffffffff); //Color.WHITE  
   }  
 }  

Hình ảnh demo ứng dụng



Kết Luận: Vậy là mình đã demo xong chương trình, các bạn có thể code và tự kiểm tra các trạng thái của ứng dụng nhé

Friday, October 14, 2016

Học máy trong lập trình Android - Face Detection

Có rất nhiều APIs cho Học Máy - Machine Learning trên cloud và mobile
Trong bài này mình sẽ sử dụng Mobile Vision APIs. Mobile Version API hiện tại bao gồm 3 loại: Face Detection API, Barcode Detection API và the Text API

Face Detection API:
API này sử dụng để phát hiện và theo dõi khuôn mặt của người trong ảnh hoặc video nhưng nó chưa cung cấp khả năng nhận dạng khuôn mặt. Nó cho phép phát hiện các điểm trên mặt như mắt, mũi và miệng và phân loại mặt. Phân loại mặt được sử dụng để kiểm tra các đặc điểm như mặt đang cười hoặc nhắm mắt...API này cũng phát hiện được mặt ở các góc độ khác nhau

Hướng dẫn cụ thể
Bước 1:
Dùng Android Studio để tạo Project
Hướng dẫn cài đặt Android Studio
Mình dùng bản 2.2.1
Tạo mới 1 project: AndroidFaceDetection
Import Google Play Services SDK trong file build.gradle

 compile 'com.google.android.gms:play-services-vision:9.6.1'  


Để kích hoạt thư viện có sẵn đại diện cho face dectection, thêm thẻ meta-data sau vào manifest file:

 <meta-data  
   android:name="com.google.android.gms.vision.DEPENDENCIES"  
   android:value="face"/>  

Bước 2: Viết code
File giao diện activity_main.xml:
Tạo một Button và một ImageView


  • Button: khởi tạo xử lý dectetion
  • ImageView: ảnh xử lý, ở đây mình lấy ảnh cố định, bạn có thể xử lý bằng cách chụp ảnh từ camera hoặc xử lý lấy ảnh có sẵn trong điện thoại


 <?xml version="1.0" encoding="utf-8"?>  
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:id="@+id/activity_main"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:orientation="vertical"  
   tools:context="com.hust.tuanbk.facedetection.MainActivity">  
   <Button  
     android:id="@+id/detection"  
     android:layout_width="100dp"  
     android:layout_height="wrap_content"  
     android:text="Detection"  
     />  
   <ImageView  
     android:layout_marginTop="20dp"  
     android:id="@+id/face"  
     android:src="@drawable/face"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
 </LinearLayout>  

MainActivity.java

 package com.hust.tuanbk.facedetection;  
 import android.graphics.Bitmap;  
 import android.graphics.BitmapFactory;  
 import android.graphics.Canvas;  
 import android.graphics.Color;  
 import android.graphics.Paint;  
 import android.graphics.RectF;  
 import android.graphics.drawable.BitmapDrawable;  
 import android.os.Bundle;  
 import android.support.v7.app.AlertDialog;  
 import android.support.v7.app.AppCompatActivity;  
 import android.util.SparseArray;  
 import android.view.View;  
 import android.widget.Button;  
 import android.widget.ImageView;  
 import com.google.android.gms.vision.Frame;  
 import com.google.android.gms.vision.face.Face;  
 import com.google.android.gms.vision.face.FaceDetector;  
 import com.google.android.gms.vision.face.Landmark;  
 public class MainActivity extends AppCompatActivity {  
   Button btDetection;  
   ImageView imageFace;  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
     imageFace = (ImageView) findViewById(R.id.face);  
     btDetection = (Button) findViewById(R.id.detection);  
     btDetection.setOnClickListener(new View.OnClickListener() {  
       @Override  
       public void onClick(View v) {  
         // create a new BitmapFactory.Options object and set inmutable to true.  
         // This is to ensure that the bitmap is mutable so that we are able  
         // to programmatically apply effects to it  
         BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();  
         bitmapOptions.inMutable = true;  
         Bitmap defaultBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.face, bitmapOptions);  
         //Create a Paint object and set the style to stroke.  
         // This ensures that the shape is not filled in because we want to see  
         // the parts of the head that make it into the rectangle  
         Paint rectPaint = new Paint();  
         rectPaint.setStrokeWidth(5);  
         rectPaint.setColor(Color.CYAN);  
         rectPaint.setStyle(Paint.Style.STROKE);  
         //canvas to display our bitmap  
         Bitmap temporaryBitmap = Bitmap.createBitmap(defaultBitmap.getWidth(), defaultBitmap  
             .getHeight(), Bitmap.Config.RGB_565);  
         Canvas canvas = new Canvas(temporaryBitmap);  
         canvas.drawBitmap(defaultBitmap, 0, 0, null);  
         // get to point where we use the FaceDectector API  
         FaceDetector faceDetector = new FaceDetector.Builder(MainActivity.this)  
             .setTrackingEnabled(false)  
             .setLandmarkType(FaceDetector.ALL_LANDMARKS)  
             .build();  
         //Check if the face detector is operational already.  
         // There’s a possibility that it won’t work the first time because a library needs to be downloaded  
         // to the device and it might not have been completed in time when you need to use it.  
         if (!faceDetector.isOperational()) {  
           new AlertDialog.Builder(MainActivity.this)  
               .setMessage("Face Detector could not be set up on your device :(")  
               .show();  
           return;  
         }  
         //create a frame using the default bitmap and call on the face detector to get the face objects.  
         Frame frame = new Frame.Builder().setBitmap(defaultBitmap).build();  
         SparseArray<Face> sparseArray = faceDetector.detect(frame);  
         //drawn rectangle over the faces  
         for (int i = 0; i < sparseArray.size(); i++) {  
           Face face = sparseArray.valueAt(i);  
           float left = face.getPosition().x;  
           float top = face.getPosition().y;  
           float right = left + face.getWidth();  
           float bottom = right + face.getHeight();  
           float cornerRadius = 2.0f;  
           RectF rectF = new RectF(left, top, right, bottom);  
           canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, rectPaint);  
           for (Landmark landmark : face.getLandmarks()) {  
             int x = (int) (landmark.getPosition().x);  
             int y = (int) (landmark.getPosition().y);  
             float radius = 10.0f;  
             canvas.drawCircle(x, y, radius, rectPaint);  
           }  
         }  
         // set ImageView from our layout after which we release the face detector.  
         imageFace.setImageDrawable(new BitmapDrawable(getResources(), temporaryBitmap));  
         faceDetector.release();  
       }  
     });  
   }  
 }  

Kết quả ta được như sau:

Lưu ý: Khi chạy trên máy thật, lần đầu chạy sẽ không phát hiện được ngay vì nó còn download thư viện xuống.
Kết luận: Vậy là đã xong cảm ơn các bạn đã quan tâm. Nhớ theo dõi blog của mình thường xuyên nhé :D
Tham khảo: Moyinoluwa Adeyemi

Friday, March 4, 2016

Tổng Quan Về Hệ Điều Hành Android

Android là gì?

  • Là một nền tảng phần mềm, một hệ điều hành cho thiết bị di động
  • Dựa trên nền tảng Linux kernel
  • Phát triển bởi Google và sau đó là Open Handset Alliance (OHA)
  • Các ứng dụng Android được phát triển dựa trên ngôn ngữ lập trình JAVA
  • Sự ra đời của nền tảng Android đã được công bố vào ngày 05/112007 dưới sự thành lập của OHA

Tóm tắt lịch sử hệ điều hành Android

Lịch sử HĐH Android tính đến 2013
  • 2005
    • Google acquires startup Android Inc. to start Android platform
    • Work on Dalvik VM begins
  • 2007
    • Open Handset Alliance announced
    • Early look at SDK
  • 2008
    • Google sponsors 1st Android Developer Challenge
    • T-Mobile G1 announced
    • SDK 1.0 released
    • Android released open source (Apache License)
    • Android Dev Phone 1 released
  • 2009
    • SDK 1.5 (Cupcake)
      • New soft keyboard with “autocomplete” feature
    • SDK 1.6 (Donut)
      • Support Wide VGA
    • SDK 2.0/2.0.1/2.1 (Eclair)
      • Revamped UI, browser
  • 2010
    • SDK 2.2 (Froyo)
      • Flash support, tethering
    • SDK 2.3 (Gingerbread)
      • UI update, system-wide copy-paste
  • 2011
    • SDK 3.0/3.1/3.2 (Honeycomb) for tablets only
      • New UI for tablets, support multi-core processors
    • SDK 4.0/4.0.1/4.0.2/4.0.3 (Ice Cream Sandwich)
      • Changes to the UI, Voice input, NFC
  • 2012
    • SDK 4.1 (Jelly Bean)
    • SDK 4.2
  • 2013
    • SDK 4.3
    • SDK 4.4 (KitKat)
  • 2014
    • SDK 5.0 (Lollipop)
  • 2015
    • SDK 5.1
    • SDK 6.0 (Marshmallow)

Biểu đồ về sự phân bổ các thiết bị Android tính đến tháng 1/2016

Kiến trúc nền tảng Android

Kiếm trúc Android

Monday, February 8, 2016

Truyện Tiếng Anh Hay Từ Dễ Đến Khó Chọn Lọc + Audio

Với nhiều câu chuyện tiếng anh với nội dung là các câu chuyển cổ tích, chuyện xã hội nước ngoài được bkstudy chọn lọc từ mức độ dễ đến khó, các bạn có thể lựa chọn



Tất cả truyện ngắn ở đây được viết bằng kiểu tiếng Anh đơn giản, dễ đọc, dễ hiểu từ cách dùng từ đặt câu đến cấu trúc ngữ pháp.
Mỗi truyện có kèm theo audio giúp các bạn vừa nghe, vừa đọc nâng cao trình độ
Dưới đấy là link download:
Truyện 1 : A Ghost in Love and Other Plays Download

Truyện 2 : Love or Money? Download

Truyện 3 : The Elephant Man Download

Truyện 4 : Dr JEKYLL and Mr HYDE Download

Truyện 5 : Goldfish Download

Truyện 6 : As The Inspector Said Download

Truyện 7 : A Christmas Carol Download

Truyện 8 : David Copperfield < 2 phần >Download 1
Download 2

Truyện 9 : American Crime Stories Download