Hiển thị các bài đăng có nhãn Android. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Android. Hiển thị tất cả bài đăng

29/12/2018

[Android] Custom error page for WebView

Trong rất nhiều tình huống bạn cần show trang error page ví dụ 404.html cho WebView. Trong trường hợp lỗi xảy ra. Lỗi xảy ra có thể tóm tắt hai trường hợp sau đây:
  1. Web server không thể trả về kết quả . Trường hợp này chỉ cần hiện thực các phương thức sau đây:
    
    void onReceivedError(WebView view, int errorCode, String description,String failingUrl) (API < 23) 
    void onReceivedError(WebView view, WebResourceRequest request,WebResourceError error) (API >= 23)
    
  2. Web server trả về kết quả nhưng là kết quả lỗi như 404, 502, 403, ... Trường hợp này nếu chương trình bạn chỉ dùng API >= 23 thì dùng các phương thức sau đây:

    
    void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)
    void onReceivedSslError (WebView view,SslErrorHandler handler,SslError error)
    
    Tuy nhiên nếu bạn hỗ trợ API < 23 thì sao? Trong trường hợp của mình thì cần hỗ trợ từ API >=21 nên mình để ý đến phương thức sau:
    
    public WebResourceResponse shouldInterceptRequest (WebView view,WebResourceRequest request)
    
    Sau đây là skeleton code:
    
    OkHttpClient okClient = new OkHttpClient();
    try{
    final Call call = new Call (new Request.Builder()
                            .url(request.getUrl().toString())
                            .build());
    final Response response = okClient.exec(call);
    if (response.code() != 200){
        return getErrorWebResourceResponse();
    }else{
        return new WebResourceResponse(
            response.header("Content-type","text/html").split(";")[0],
            response.header("Content-Encoding","utf-8"),
            response.body().getByteStream()    
        );
    }                        
    } catch (Exception ignore){
     return getErrorWebResourceResponse();
    }
    }
    

15/08/2015

Cái giá của việc dùng enum

Bài học về chiếc ròng rọc ở môn Vật lý lớp 7 tôi học được luôn luôn đi theo suốt cuộc đời mình: Được lợi bao nhiêu lần về lực thì thiệt bấy nhiêu lần về đường đi. Không có cái gì là hoàn mỹ cả, đồng tiền thì có hai mặt mà. Trong lập trình Android thì ENUM là công cụ rất thuận tiện khi chúng ta cần diễn đạt một tập những giá trị hữu hạn hằng số của một đối tượng, thuộc tính nào đó. Vậy thì cái giá phải trả cho nó là gì?
Bạn có thể truy xuất trang web: 
https://developer.android.com/training/articles/memory.html và bạn có thể thấy dòng sau đây: "Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android." Câu này có nghĩa là "Enums thường cần 2 lần dung lượng bộ nhớ so với hằng số tĩnh. Bạn nên tuyệt đối tránh dùng enum trong Android".
Các bạn cũng biết rằng chương trình Android sẽ được biên dịch thành dạng DEX và load vào bộ nhớ chính khi thực thi chúng. Do đó kích thước của chương trình sau khi biên dịch rất quan trọng.  
Sau đây là một thí nghiệm nhỏ. Có một chương trình sau khi biên dịch sang dạng DEX có kích thước 2556 bytes. Sau đó tác giả thêm class sử dụng hằng số như sau:
public static final int V1=1;
public static final int V2=2;
public static final int V3=3;
int function(int v){
switch (v) {
case V1:
return -1;
case V2:
return -2;
case V3:
return -3;
}
return 0;
}
 Sau khi biên dịch sang dạng DEX, kích thước chương trình là 2680 bytes, tăng 124 bytes.
Thay class trên bằng cách dùng enum:

public static enum Value{

V1,
V2,
V3
};
int function(Value v){
switch (v) {
case V1:
return -1;
case V2:
return -2;
case V3:
return -3;
}
return 0;
} 
 Khi biên dịch sang dạng DEX kích thước chương trình lúc này là 4188 bytes tăng lên 1632 bytes (13 lần so với dùng hằng kiểu int. Cứ mỗi hằng enum thì cần thêm 20bytes bộ nhớ so với dùng hằng số int). Như vậy chỉ cần dùng thêm một kiểu enum thì kích thước chương trình tăng thêm kinh khủng như vậy đó. Nếu chúng ta dùng vài chục enum trong một chương trình thì lượng bộ nhớ chúng ta phí phạm sẽ thế nào?
Câu hỏi đặt ra không dùng enum vậy có cách gì khác không? Câu trả lời là ngoài cách sử dụng hằng số tĩnh như ở trên thì Android còn cung cấp cho chúng ta công cụ @IntDef annotation. Ngoài ra nếu chúng ta quen dùng enum thì có thể chọn cách dùng ProGuard để chuyển enum thành int value trước khi biên dịch cũng được nhưng cách này hơi khó khăn.
(Bài viết tham khảo từ Internet)

22/03/2013

OpenGL blend function

Trước đây làm việc OpenGL mà không hiểu mấy về cái hàm gl.glBlendFunc(a,b). Hôm qua có thời gian ngồi xem tài liệu kỹ lại thì ra là thế này. Gọi D là màu của destination (màu đang có), S là màu source (màu ta cần pha với màu đang có), ta có công thức tính màu sau khi pha như sau:
R = a*S+b*D
Lấy ví dụ: 
  • Nếu a= GL_ONE, b=GL_ONE, S=(1,0,0) (màu đỏ), D=(0,0,1) (xanh da trời). Ta sẽ có R=(1,0,1) (màu đỏ tươi)
  • Nếu a=GL_SRC_ALPHA, b= GL_ONE_MINUS_SRC_ALPHA, S=(0.5,1,0,0), D=(1,0,0,1). Ta sẽ có: 
    • Ra = 0.5*0.5+(1-0.5)*1=0.25+0.5 = 0.75
    • Rr = 0.5*1+(1-0.5)*0 = 0.5
    • Rg = 0.5*0+(1-0.5)*0 = 0
    • Rb = 0.5*0+(1-05)*1 = 0.5
                R = (0.75,0.5,0,0.5)



15/03/2013

Kiểm tra một số có là luỹ thừa của 2 hay không nhanh nhất

Thông thường để muốn kiểm tra một số có là luỹ thừa của 2 hay không thì chúng ta đem số này chia cho 2 như sau:

public boolean isPowerOfTwo(int n){
	if( 0 == n|| 1 == n ) return true;
	int x = n / 2;
	int y = n%2;
	if (1 == y) return false;
	return isPowerOfTwo(x);
}
Hoặc chúng ta không cần viết đệ qui như sau:

  public boolean isPowerOfTwo(int n){
    boolean ret;        
	if( 0 == n|| 1 == n ){
    	     ret = false;       
    }else{
        int x = n / 2;
        int y = n%2;
        while ( x > 0){
        	if (1 == y) {
            ret = false;
            break;
 		};
		x = x / 2;
        y = x%2;
	}
	ret = true;
	}
   return ret;
 } 

Sau đây là cách nhanh hơn sử dụng hàm logarit:

public boolean isPowerOfTwo(int n){
	double logn2 = Math.log(n)/Math.log(2);
	int logn2i = (int) (Math.floor(logn2));
	if(logn2-logn2i==0)
		return true;
	else
	return false;
}

Tuy nhiên nếu chúng ta để ý một chút chúng ta sẽ có cách kiểm tra nhanh nhất. Các số là luỹ thừa của 2 đều có 1 chữ số 1 trong biểu diễn nhị phân của chúng. Ví dụ số
1: 000001
2: 000010
4: 000100
8: 001000
16: 010000
32:     100000
Xét số n = 32 ( 100000) và n -1 = 31 (011111) và rõ ràng n&(n-1) = 0.
Ta có giải thuật như sau:

public boolean isPowerOfTwo(int n){
	return ((n!=0) && (n&(n-1))==0);
}

Thật ngắn gọn, đơn giản phải không các bạn!

16/02/2013

Android 4.2.2 (JDQ39) changelog

Google has release Android 4.2.2 (Jelly Bean). Nexus tablets ( Nexus 7 (non-3G), Nexus 10) and Galaxy Nexus (takju) can be updated the new version OS. Some changes:

  • More secured ADB.
  • Bug fix for bluetooth audio streaming
  • Download notification now shows remaining time
  • Quick Settings:Toggle WiFi and Bluetooth on/off by a long-touch 
  • Performance enhancements
  • New notification sounds (wireless charging and low battery)
Google vừa phát hành bản nân cấp Android 4.2.2. Các smartphone Nexus 4, Galaxy Nexus và máy tính bảng Nexus 7, Nexus 10 đã có thể cập nhật bản Android 4.2.2.
Một vài điểm mới trong bản nâng cấp Android 4.2.2:
  • An toàn hơn cho cầu nối ADB.
  • Vá lỗi âm thanh bị lắp khi dùng Bluetooth và lỗi tự khởi động lại thiết bị.
  • Thông báo (Notification) tải ứng dụng trình bày thông tin về thời gian còn lại cần để tải.
  • Thiết lập nhanh (Quick Settings):Người dùng có thể chạm vào và giữ lâu (long touch) lên biểu tượng Wi-Fi và Bluetooth để thay đổi thiết lập.
  • Âm báo mới cho chức sạc không dây và cảnh báo pin sắp hết.
  • Tốc độ hiển thị và lướt ảnh trong Gallery nhanh hơn.

29/12/2012

Chạy ứng dụng Android trên PC

Đọc các bài báo sau  trên báo Tuổi trẻ:

và đang suy nghĩ miên man về công nghệ mà Blue Stacks sử dụng.Ngoài ra liệu việc làm này sẽ làm cho Android mạnh lên hay sẽ thu hẹp tầm ảnh hưởng của nó?
Về công nghệ thì theo các bài báo có chút thông tin tóm tắt như sau:

  • BlueStacks sử dụng BlueStacks App Player (BAP) 
  • BAP thực hiện giải pháp chuyển đổi ảo hoá Windows/Mac OS nhanh chóng thông qua công nghệ đám mây BlueStack Cloud Connect 
  • Cho phép đồng bộ ứng dụng trên Android smartphone với PC.

21/12/2012

9 ỨNG DỤNG IN ẤN HÀNG ĐẦU TRÊN ANDROID

Hiện nay ở Việt Nam, điện thoại Android dần phổ biến. Một chiếc điện thoại Android thì không thể thiếu chiếc máy ảnh đi kèm. Khi chụp ảnh xong chúng ta thường tải lên các trang mạng xã hội như Facebook, Google Plus, ... Có bao giờ bạn muốn in những bức ảnh này ra máy in không? Làm cách nào để in?
Hiện nay theo F thì có các ứng dụng sau đây giúp bạn thực hiện được mong muốn này:

  1. StarPrint
    • Nội dung in: PDF, PS, văn bản trơn, nội dung trang Web, hình ảnh trong bộ sưu tập trên thiết bị, hình ảnh trên Instagram, SMS, sổ địa chỉ, thư điện tử.
    • Hỗ trợ in qua Bluetooth, Wi-Fi, USB.
    • Hỗ trợ hơn 3000 thiết bị in khác nhau của các hãng HP, Canon, Brothers, Epson, ...
  2. ePrint
    • Chỉ hỗ trợ các máy in Epson, Canon, HP.
    • Chỉ hỗ trợ Android 3.0 trở đi.
  3. Canon Easy PhotoPrint
    • Chỉ hỗ trợ máy in Canon
    • Hỗ trợ in PDF và hình tạo bởi "Canon equipment" 
  4. Epson iPrint (CyPria)
    • Chỉ hỗ trợ máy in Epson.
    • Hỗ trợ nhiều loại tập tin 
    • Có thể in từ Box, DropBox, Evernote và Google Docs.
  5. KODAK Document Print
    • Yêu cầu tài khoản "Google Cloud Print" và máy in không dây Kodak.
    • Hỗ trợ nhiều loại tập tin.
  6. Breezy-Print and Fax
    • Hỗ trợ cả iOS và Blackberry.
    • Yêu cầu "Breezy subscription".
  7. Office Max Print Center
    • Yêu cầu phải có "Office Max Network".
  8. Brother iPrint & Scan
    • Chỉ hỗ trợ máy in Brothers.
  9. HP ePrint Home & Biz
    • Chỉ hỗ trợ máy in HP. 

24/06/2012

Lập trình Qt cho Android

Nếu bạn đã có một chương trình Qt chạy khá tốt trên các nền tảng khác bây giờ bạn muốn chuyển nó qua Android mà bạn không muốn tốn nhiều công sức để viết lại từ đầu sử dụng Android SDK thì đây là bài viết phù hợp cho bạn.
Tôi cũng là một nhà phát triển phần mềm sử dụng Qt/QML. Tôi cũng có một mong muốn giống bạn. Tôi đã bắt đầu từ Android Lighthouse. Tuy nhiên gần đây tôi đã phát hiện ra Necessitas. Necessitas đã cung cấp cho người  dùng một bộ SDK khá hoàn chỉnh để phát triển chương trình Qt/QML cho Android. Necessitas sử dụng Android Lighthous, Qt Creator, Ministro. Tuy Necessitas chưa được ổn định nhưng đã phần nào đáp ứng nhu cầu của tôi.
Tôi đã thử phát triển chương trình QML và deploy trên Android phone. Chương trình chạy rất OK.

02/06/2012

PHP: Phân biệt Android Phone và Android Tablet

Đầu tiên lấy thông tin UA từ server:
$userAgent = $_SERVER['HTTP_USER_AGENT'];
Nếu chuỗi này có chứa từ Android thì client device đang chạy Android OS:
if (stripos($userAgent, 'Android') !== false){
//Cần xác định Android Phone hay Android Tablet ở đây.
Không có một cách nào chính xác để phân biệt giữa Android Phone và Android Tablet (chưa kể một số web browser cho phép người dùng thiết lập UA). Tuy nhiên có một số mẹo sau:
  • Android 3.x chỉ sử dụng cho các Tablet.
  • Google khuyên các nhà sản xuất bỏ chữ 'Mobile' ra khỏi chuỗi UA.
  • Một số thiết bị Kindle Android lại có chữ Mobile trong UA nhưng nó lại không có chữ Silk.
if (stripos($userAgent, 'Android') !== false){
if (stripos($userAgent, 'Android 3') !== false || 
 stripos($userAgent, 'Tablet') !== false || 
stripos($userAgent, 'Mobile') === false || 
 stripos($userAgent, 'Silk') !== false )
  {
  //Android Tablet  
}else{
//Android Phone
}
}

05/04/2012

Dịch ngược ứng dụng Android


Việc chuyển gói nhị phân apk của một ứng dụng Android thành dạng mà con người có thể đọc được gọi là quá trình dịch ngược (reverse engineering). Ở đây tôi không bàn đến tính hợp pháp của hành động này mà tôi chỉ bàn đến khía cạnh kỹ thuật của nó. Đồng tiền thì có hai mặt. Việc dịch ngược này cũng vậy tôi tin rằng nó cũng hữu ích cho bạn trong nhiều tình huống hoàn toàn hợp pháp. Để dịch ngược ứng dụng Android bạn cần thực hiện qua hai bước

Decompiling

  • Tải android-apktool từ đây.
  • Giải nén hay cài đặt (tuỳ theo gói mà bạn chọn tải về).
  • Thực hiện câu lệnh sau đây:
apktool d file.apk 
  • Bạn thu được các tập tin resource xml và mã nguồn smali. Tuy nhiên mã nguồn smali rất khó đọc (có thể chạy debug được). Chúng ta cần tiến hành bước kế tiếp để thu được mã nguồn Java.

Disassembling

  • Tải công cụ dex2jar tool tại đây.
  • Giải nén nó vào một thư mục bất kỳ.
  • Thực hiện câu lệnh sau đây để chuyển gói apk thành gói jar
dex2jar file.apk
  • Tải công cụ jd-gui  tại đây.
  • Sử dụng công cụ này để chuyển file class thành file java.
Đến đây chúng ta đã có mã nguồn, có các tập tin resource.

03/11/2011

Determin mp4 file is audio file or video file

If you receive mp4 file from server, you can determin it is audio file or video file by mime information which is sent by server. However, if mp4 file is in your Android terminal (internal or external storage device), how do you solve the problem? In this small post, I present a solution use MP4Parser library.

try{
//mp4 is path string of your mp4 file   

IsoBufferWrapper isoBufferWrapper = new IsoBufferWrapper(new File(mp4));
IsoFile isoFile = new IsoFile(isoBufferWrapper);
isoFile.parse();
//Get FileTypeBox   
    ArrayList boxes =( ArrayList) isoFile.getBoxes(FileTypeBox.class);
    FileTypeBox ftb =(FileTypeBox) boxes.get(0);
    String major =ftb.getMajorBrand().trim().toLowerCase();
    //The list of ftyps http://www.ftyps.com/
    if(major.equals("m4a") || //Apple iTunes AAC-LC (.M4A) Audio
       major.equals("msnv")|| //MPEG-4 (.MP4) for SonyPSP
       major.equals("ndas")|| //MP4 v2 [ISO 14496-14] Nero Digital AAC Audio
       major.equals("da1a")|| //DMB MAF audio with ER-BSAC audio, JPG/PNG/MNG images
       major.equals("f4a")|| //Audio for Adobe Flash Player 9+ (.F4A)
       major.equals("f4b")|| //Audio Book for Adobe Flash Player 9+ (.F4B)
       major.equals("m4b")|| //Apple iTunes AAC-LC (.M4B) Audio Book
       major.equals("m4p")|| //Apple iTunes AAC-LC (.M4P) AES Protected Audio
       major.equals("bsac")|| //MPEG-4 "Bit Sliced Arithmetic Coding" (audio)
       major.equals("mot slides") //Digital Audio Broadcasting (DAB) MOT slideshow (ETSI DAB  TR 101 497)
            ){
        //AUDIO FILE
    }else{
        //VIDEO FILE
    }
        }catch(IOException ex){
            ex.printStackTrace();
            //ERROR
        }