Month: July 2023

  • Fake GPS location on Xcode

    Fake GPS location on Xcode

    Ở phần trước mình đã hướng dẫn các bạn các cách để fake GPS location trên Simulator của iPhone. Nếu các bạn muốn tìm hiểu thêm thông tin thì có thể tham khảo ở đường link: HƯỚNG DẪN CÁCH FAKE GPS TRÊN SIMULATOR

    Trong bài này mình sẽ hướng dẫn các bạn Fake GPS location on Xcode nhằm mục đích giúp các bạn có thêm các cách để giảm thời gian và dễ dàng test các ứng dụng liên quan tới GPS, location services. Đặc biệt hữu dụng với các ứng dụng yêu cầu người dùng phải di chuyển kiểu như app chạy bộ, đạp xe, chỉ đường, hướng dẫn … v.v.

    Giải thích về ý tưởng

    Để dễ dàng cho việc test các tính năng yêu cầu người dùng ứng dụng phải di chuyển, chúng ta sẽ sử dụng cách Fake GPS location bằng cách sử dụng GPX file trên Xcode. GPX file cho phép chúng ta thêm các vị trí và thời gian di chuyển đến vị trí đó, từ đó ta có thể tạo ra một danh sách các điểm cần di chuyển đến để thực hiện test ứng dụng mà không cần di chuyển thực tế. GPX file cho phép ta có thể tạo ra các kịch bản test di chuyển một cách dễ dàng và tiết kiệm thời gian và công sức. Ngoài ra ta có thể sử dụng lại được nhiều lần và dễ dàng chỉnh sửa theo các kịch bản test.

    Từ các tính năng như trên chúng ta có thể tạo ra một ứng dụng chuyên để Fake GPS Location từ đó giả lập vị trí của iPhone.

    NOTE

    Đây là fake GPS location của thiết bị luôn, và nó hoạt động và ảnh hưởng lên tất cả các ứng dụng đang sử dụng Map, Location Services. Vậy nên các bạn lưu ý khi sử dụng nha.

    Hướng dẫn Fake Location GPS trên XCode sử dụng GPX file

    Để tiện cho việc demo các bạn có thể tải xuống source ở link dưới đây:

    Bước 1: Tạo file GPX để fake GPS Location trên Xcode

    Sử dụng Xcode mở project DemoGPXMapKit lên -> Bấm chuột phải vào tạo new file…

    Fake GPS location on Xcode

    Khi của sổ mở lên, ở ô tìm kiếm bạn điền từ khoá “GPX” thì sẽ được kết quả như hình dưới đây

    Fake GPS location on Xcode

    Bấm Next và đặt tên cho file, ở ví dụ này mình sẽ đặt là mydinh-hanoi. Đặt tên xong Xcode sẽ tạo cho các bạn một file và có sẵn nội dung là một điểm.

    Các bạn có thể thay đổi file GPX tuỳ theo trường hợp mà bạn muốn. Ở đây mình muốn Fake GPS Location về Sân vận động Mỹ Đình nên mình sửa lại file như sau:

    <?xml version="1.0"?>
    <gpx version="1.1" creator="Xcode">
        <wpt lat="21.02025349623149" lon="105.76408736691972">
            <name>My-dinh</name>
            <time>2014-09-24T14:55:37Z</time>
        </wpt>
    </gpx>
    

    Về toạ độ lat, lon các bạn có thể sử dụng Google Map để lấy -> bấm chuột phải vào vị trí bạn muốn lấy vị trí sẽ hiển thị như hình và bạn chọn vào hàng có toạ độ là nó tự copy toạ độ cho các bạn, rồi các bạn paste vào file GPX để thay đổi vị trí một cách dễ dàng.

    Fake GPS location on Xcode

    Bước2: Chỉnh sửa scheme để file GPX fake GPS Location tự động ăn khi chạy ứng dụng

    Chọn Scheme -> Edit Scheme như hình dưới

    Fake GPS location on Xcode

    Một popup hiển thị lên, lúc này bạn chọn Run -> Options.
    – Ở mục CoreLocation tích vào Allow Location Simolation.
    – Ở mục Default Location chọn file gpx của các bạn, trường hợp này của mình là mydinh-hanoi. Nếu không chọn thì mặc định nó sẽ là None và khi đó nó sẽ ăn vào location của Simulator

    Fake GPS location on Xcode

    Thực hiện Build(Command + R) ứng dụng để ứng dụng sử dụng file GPX.

    Khi này ở thanh Debug chúng ta sẽ có thêm icon Location để cho phép chúng ta thay đổi vị trí Fake GPS location một cách dễ dàng và nhanh chóng hơn.

    Fake GPS location on Xcode

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

    Fake GPS location on Xcode

    Các bạn có thể tạo ra nhiều file GPX với nhiều vị trí khác nhau để thuận tiện cho việc test, hoặc có thể sửa trực tiếp file GPX rồi chọn lại mà không cần build lại ứng dụng.

    Fake GPS Location di chuyển theo đường đi bằng file GPX

    Chúng ta sẽ tạo mới một file như các bước mình đã hướng dẫn ở đầu bài. Nội dung thì sửa lại như sau:

    <?xml version="1.0"?>
    <gpx version="1.1" creator="Xcode">
        <wpt lat="21.02186996901372" lon="105.7645261741194">
            <name>Cupertino</name>
            <time>2014-09-24T14:05:30Z</time>
        </wpt>
        <wpt lat="21.021606653375308" lon="105.76616386527535">
            <name>Cupertino</name>
            <time>2014-09-24T14:05:40Z</time>
        </wpt>
        <wpt lat="21.019302621702572" lon="105.76618737280388">
            <name>Cupertino</name>
            <time>2014-09-24T14:05:50Z</time>
        </wpt>
    </gpx>

    Ở đây mình có thêm vào 3 waypoints để fake GPS location, nhằm giả lập việc di chuyển qua các điểm này. Các bạn để ý kỹ thì mình có thay đổi thời gian của các waypoint tăng dần và cách nhau 10s. Các bạn có thể tính toán vận tốc và quãng đường để thực hiện giả lập một cách chân thực nhất, ví dụ như tốc độ của ô tô với máy bay thì sẽ khác nhau vì vậy cùng quãng đường thời gian cũng sẽ khác nhau.

    Giờ khi các bạn chọn icon location sẽ hiển thị ra file bạn mới tạo và có thể thay đổi luôn mà không cần phải build lại nữa, như mình mới tạo file ride-mydinh-hanoi

    Kết quả chúng ta sẽ thu được như sau

    Tuy nhiên ta có thể thấy nó cứ lặp đi lặp lại vô hạn mà không dừng lại tại điểm cuối cùng. Để cho nó dừng lại ở điểm cuối cùng thì chúng ta sẽ sử dụng thêm một waypoint nữa và thay đổi vị trí không đáng kể và tăng thời gian di của điểm này cách xa so với điểm gần cuối như sau:

    <?xml version="1.0"?>
    <gpx version="1.1" creator="Xcode">
        <wpt lat="21.02186996901372" lon="105.7645261741194">
            <name>Cupertino</name>
            <time>2014-09-24T14:05:30Z</time>
        </wpt>
        <wpt lat="21.021606653375308" lon="105.76616386527535">
            <name>Cupertino</name>
            <time>2014-09-24T14:05:40Z</time>
        </wpt>
        <wpt lat="21.019302621702572" lon="105.76618737280388">
            <name>Cupertino</name>
            <time>2014-09-24T14:05:50Z</time>
        </wpt>
        <wpt lat="21.019302611702572" lon="105.76618737280388">
            <name>Cupertino</name>
            <time>2014-09-24T15:05:50Z</time>
        </wpt>
    </gpx>

    Bạn để ý kĩ chỗ mình bôi đậm sẽ hiểu rõ nguyên lý hoạt động của nó.

    Từ đây bạn có thể mở rộng ra bằng cách tạo thêm nhiều file GPX với các cung đường đa dạng để phục vụ cho việc test ứng dụng của các bạn khi cần.

    Mình hi vọng bài viết có thể giúp mọi người làm việc một cách dễ dàng và hiệu quả hơn.

  • How to enable UT Coverage on Xcode?

    How to enable UT Coverage on Xcode?

    You want to check your UT index?
    You want to display the coverage index on xcode to know if your code has reached the standard?
    How to show Coverage index on xcode?
    How to enable UT Coverage on XCode?
    Those are the questions I get asked often, but there aren’t many tutorials on the internet yet. So today I will guide you to enable Code Coverage on Xcode

    How to enable UT Coverage on Xcode 13.4.1 or below?

    For projects using Xcode 13 or below to create, we do the following:

    Step 1: Select Scheme -> edit Scheme -> a popup is displayed

    Step 2: In the left menu of the popup select Test, then in the upper menu of the popup select option -> tick Code Coverage for

    Step 3: Run test app (command + U)

    How to enable UT Coverage on Xcode 14.0 or later?

    For projects using Xcode 14 or later to create, we do the following:

    Step 1: Select Scheme -> edit Scheme -> a popup is displayed

    How to enable UT Coverage on XCode

    Step 2: In the left menu of Popup select Test, then hover on Test Plan as shown and then click the button to go to settings.

    How to enable UT Coverage on XCode

    Step 3: Change code coverage to On

    How to enable UT Coverage on XCode

    If you don’t need to test UI, you can remove the test plan for UI to make Unit tests run faster

    How to enable UT Coverage on XCode

    Step 4: Run test (command + U), ta thu được kết quả như sau

    How to enable UT Coverage on XCode

    I hope it can help!

  • Testing SCD Loại 1 trong ETL validator

    Testing SCD Loại 1 trong ETL validator

    Xin chào mọi người, ở bài viết SCD (Slowly Changing Dimension) là gì? Các loại SCD và ví dụ cụ thể (https://magz.techover.io/2023/07/03/scd-slowly-changing-dimension-la-gi-cac-loai-scd-va-vi-du-cu-the/) chúng ta đã nắm được sơ lược về SCD type 1. Hôm nay chúng ta cùng đi tìm hiểu kỹ hơn về SCD type 1 và các test cases cần thiết trong quá trình kiểm thử nhé!

    1. Tìm hiểu về SCD type 1 (Ghi đè – Overwrite)

    Ở SCD1 các dữ liệu mới sẽ ghi đè dữ liệu cũ, không theo dõi dữ liệu lịch sử.

    Ví dụ:

    Original Record – Dữ liệu gốc

    Cust_ID Name City
    1001 Nguyễn Văn A HCM
    1002 Nguyễn Văn B Nam Định

    Updated Record – Dữ liệu được thay đổi

    Cust_ID Name City
    1001 Nguyễn Văn A Hà Nội
    1002 Nguyễn Văn B Nam Định

    Ưu điểm: Dễ bảo trì.

    Nhược điểm: Không kiểm tra được dữ liệu lịch sử.

    2. SCD1 validation test cases

    image

    Kiểm tra SCD Loại 1 khá đơn giản vì chúng ta có thể đạt được kết quả bằng cách so sánh đơn giản giữa dữ liệu nguồn và dữ liệu đích. Ví dụ chúng ta có bẳng nguồn và bảng đích như sau:

    Employee table – bảng nguồn với các cột:

    Cust_ID
    Name
    City

    EMPLOYEE_DIM SCD Type 1 – bảng đích với các cột dưới đây:

    Cust_ID
    Name
    City
    Partition_date

    2.1 Test case 1: Chúng ta sẽ đi kiểm tra số lượng cột, tên cột và data type từng cột có đúng với yêu cầu document không?

    VD: Cus_ID có type là bigint, thì trên bảng đích data type cũng là bigint.

    Target Query: Describe Table_Name; or Desc Table_Name

    2.2 Test case 2: Kiểm tra số lượng records.

    Source Query: Select count (*) from db.Emlpoyee

    Target Query: Select count (*) from db.Employee_Dim

    2.3 Test case 3: Kiểm tra logic insert

    1. Insert thêm records mới ở bảng nguồn:

    Chúng ta sẽ thêm các records mới tại bảng nguồn, rồi khởi chạy job ETL. Sau khi job chạy thành công thì kiểm tra dữ liệu ở bảng đích có lên đúng và đủ so với bảng nguồn không.

    1. Delete records ở bảng nguồn

    Ngược lại với thêm mới, chúng ta sẽ xóa bớt dữ liệu ở bảng nguồn rồi chạy job ETL. Sau khi job chạy thành công thì kiểm tra dữ liệu ở bảng đích và bảng nguồn có mapping với nhau không.

    2.4 Test case 4: Kiểm tra logic update

    Tại bảng nguồn chúng ta sẽ update các bản ghi trước đó, rồi chạy job ETL. Sau khi job chạy thành công, kiểm tra dữ liệu bảng đích có lên đúng so với bảng nguồn không.

    2.5 Test case 5: Kiểm tra dữ liệu có bị duplicate không? – Xác minh tính duy nhất của dữ liệu

    Target Query:

    Select Cust_ID, Name, City, Partition_date, count(*) from db.Employee_Dim group by Cust_ID, Name, City, Partition_date having count(*) > 1 ;

    Select Cust_ID, count(Cust_ID) from db.Employee_Dim group by Cust_ID having count(Cust_ID) > 1;

    2.6 Test case 6: Kiểm tra dữ liệu null

    Target Query:

    Select * from db.Employee_Dim where Cust_ID is not null;

    Kết luận

    • SCD1: các dữ liệu mới sẽ ghi đè dữ liệu cũ, không theo dõi dữ liệu lịch sử
    • Kiểm tra số lượng bản ghi bảng đích so với bảng nguồn
    • Sau khi thay đổi dữ liệu bảng nguồn (insert, delete, update) phải thực hiện quy trình ETL để EMPLOYEE_DIM có dữ liệu mới nhất
    • Sửa đổi một vài bản ghi trong bảng nguồn bằng cách cập nhật các giá trị trong các cột chính (key columns) để kiểm tra logic update
    • Xác minh tính duy nhất của dữ liệu
    • Xác minh rằng sự khác biệt là như mong đợi

    Trên đây là những chia sẻ của mình về testing SCD type 1 trong ETL testing, mong rằng bài viết này sẽ giúp ích được cho các bạn. Nếu mọi người có thắc mắc hay câu hỏi gì đừng ngần ngại comment và cùng nhau giải đáp nhé!

    Hẹn gặp lại mọi người trong bài viết tiếp theo.

  • Hướng dẫn cách Fake GPS trên Simulator

    Hướng dẫn cách Fake GPS trên Simulator

    Hi, trong quá trình phát triển các ứng dụng iOS, đôi khi chúng ta sẽ được phát triển các tính năng liên quan tới bản đồ, một số ứng dụng còn cần phải sử dụng Location Service để hiển thị vị trí của người dùng. Vì vậy khi phát triển ứng dụng bạn sẽ cần phải kiểm tra ứng dụng của mình xem nó chạy đúng chưa, hiển thị đúng vị trí trên bản đồ chưa? Nếu chúng ta cầm thiết bị chạy đi chạy lại thì thật quá tốn công, tốn sức. Thấu hiểu nỗi khổ của các iOS developers Apple đã phát triển tính năng Fake GPS trên Simulator giúp cho việc kiểm tra ứng dụng của mình một cách dễ dàng và đỡ mất công mất sức hơn.

    Fake GPS trên Simulator – Di chuyển đến trụ sở chính của Apple

    Để bật tính năng này chúng ta mở Simulator lên, trên Menu bar của Simulator chọn Features -> Location -> Apple như hình dưới đây

    fake gps on simulator

    Kết quả chúng ta sẽ được vị trí GPS ở trụ sở của Apple.

    Fake GPS trên Simulator – Di chuyển đến vị trí bất kì trên bản đồ

    Việc fake GPS trên Simulator đến vị trí trung tâm Apple không giúp ích nhiều cho việc kiểm tra ứng dụng của bạn, vì vậy mình sẽ hướng dẫn các bạn cách để Fake GPS trên Simulator đến vị trí bất kì trên bản đồ. Để làm được điều này chúng ta cần Kinh độ và Vĩ độ của điểm chúng ta cần fake GPS. Các bạn có thể lên Google Map để lấy toạ độ nhá. Ví dụ mình sẽ lấy toạ độ của Đền Ngọc Sơn trên Hồ Hoàn Kiếm ở Hà Nội.

    Để ý hình mình có khoanh, Ta sẽ lấy toạ độ (lat, long) theo thứ tự từ trái qua phải là Latitude và Longitude ở trên URL của google map. Trong ví dụ này Latitude: 21.0298318Longitude: 105.8532851.

    Khi lấy được toạ độ cần fake GPS trên Simulator rồi thì ta sẽ làm như sau:
    Trên Menu bar của Simulator -> chọn Features -> Location -> Custom Location… -> Điền Latitude và Longitude vào và bấm OK như hình dưới.

    Vậy là chúng ta đã có thể fake GPS đên mọi nơi mà chúng ta cần để kiểm tra ứng dụng của mình.

    NOTE: Có một lưu ý là khi các bạn copy Latitude và Longitude từ Google đôi khi ngôn ngữ không giống với simulator nên simulator nó không nhận, bạn hãy để ý và thay dấu chấm “.” <-> thành dấu phẩy “,” hoặc ngược lại nhé.

    Fake GPS trên Simulator – Fake trường hợp vị trí chuyển động liên tục.

    Trong thực tế có một số ứng dụng yêu cầu ta phải hiển thị vị trí của người dùng chính xác và liên tục, tuy nhiên để kiểm tra trường hợp này một cách mượt mà thì sử dụng các cách phía trên là bất khả thi và tốn rất nhiều thời gian, vì vậy apple đã cung cấp một số cách để thuận tiện cho việc kiểm tra vị trí di chuyển đó là: City Run, City Bicycle Ride và Freeway Drive.
    Trên Menu bar của Simulator -> chọn Features -> Location -> City Run hoặc City Bicycle Ride hoặc Freeway Drive.

    Vậy là bạn đã có thể ngồi 1 chỗ và test được việc di chuyển trên ứng dụng của mình mà không tốn một giọt mồ hôi nào.

    Hiện tại Apple chỉ hỗ trợ 3 loại di chuyển như trên vì vậy nó khá hạn chế trong việc kiểm thử, trong trường hợp các bạn cần linh hoạt hơn thì chúng ta có thể sử dụng file GPX để fake GPS trên Simulator chủ động hơn, tuy nhiên cách này sẽ phức tạp hơn một chút. Vì vậy mình sẽ hướng dẫn các bạn ở bài viết tiếp theo nhé!

  • Accessibility in Android and Usage

    1. Accessibility là gì

    • Điện thoại di động đã và đang trở thành một vật bất ly thân với mỗi người chúng ta. Tuy nhiên trong nhiều trường hợp, mọi người sẽ cảm thấy khó khăn trong việc sử dụng điện thoại di động. Điều này bao gồm một người bị mù bẩm sinh hoặc mất kỹ năng vận động trong một tai nạn. Điều này cũng bao gồm cả những người không thể sử dụng tay vì họ đang bế một đứa trẻ. Bạn có thể gặp khó khăn khi sử dụng điện thoại khi đeo găng tay khi trời lạnh. Có thể bạn gặp khó khăn trong việc phân biệt các mục trên màn hình khi trời sáng.
    • Trong những trường hợp này, thứ họ cần chính là những hỗ trợ từ những chiếc điện thoại thông minh. Accessibility từ đó được sinh ra để hỗ trợ chúng ta.
    • Dịch vụ trợ năng (Accessibility) là một tính năng của Android Framework được thiết kế để cung cấp phản hồi điều hướng thay thế cho người dùng thay mặt cho các ứng dụng được cài đặt trên thiết bị Android. Dịch vụ trợ năng có thể thay mặt ứng dụng giao tiếp với người dùng, chẳng hạn như bằng cách chuyển đổi văn bản thành giọng nói hoặc cung cấp phản hồi xúc giác khi người dùng di chuột trên một khu vực quan trọng của màn hình. Phòng học mã này chỉ cho bạn cách tạo một dịch vụ trợ năng rất đơn giản.

    2. Ứng dụng của Accessibility trong Android

    • Switch Access: cho phép các người dùng android bị hạn chế vận động tương tác với điện thoại qua một hoặc nhiều nút.
    • Voice Access (beta): cho phép các người dùng Android bị hạn chế vận động điều khiển thiết bị bằng cử chỉ giọng nói.
    • Talkback: một trình đọc màn hình thường được người khiếm thị hoặc người mù sử dụng.

    3. Hướng dẫn cài đặt Accessibility Service

    Cách cài đặt Accessibility Service trong project Android

    • Accessibility yêu cầu các điện thoại chạy chúng phải có phiên bản từ Android 7 trở lên
    • Cùng xem chúng ta cần những gì trong file AndroidManifest của service này
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <application>
            <service
                android:name=".HelperService"
                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:exported="true">
                <intent-filter>
                    <action android:name="android.accessibilityservice.AccessibilityService"/>
                </intent-filter>
                <meta-data
                    android:name="android.accessibilityservice"
                    android:resource="@xml/helper_service"/>
            </service>
        </application>
    </manifest>
    • Để có thể chạy service này ta cần thêm quyền android:permission=”android.permission.BIND_ACCESSIBILITY_SERVICE”
    • Sau đó ta thêm file metadata vào service: @xml/helper_service
    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:accessibilityFeedbackType="feedbackGeneric"
        android:accessibilityFlags="flagDefault"
        android:canPerformGestures="true"
        android:canRetrieveWindowContent="true" />
    • Để thực hiện thao tác vuốt, android:canPerformGesture được đặt thành true
    • Để truy cập nội dung cửa sổ, android:canRetrieveWindowContent được đặt thành true.

    Sau đó, để triển khai các chức năng của AccessibilityService, chúng ta phải tạo một Service kế thừa AccessibilityService

    public class HelperService extends AccessibilityService {
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
        }
        @Override
        public void onInterrupt() {
        }
    }
    • Chúng ta sẽ tạo một view để hiển thị các nút bấm chức năng hỗ trợ trong service này
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:gravity="start"
            android:id="@+id/power"
            android:text="@string/power"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/volume_up"
            android:text="@string/volume_up"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/volume_down"
            android:text="@string/volume_down"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/swipe_down"
            android:text="@string/swipe_down"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/swipe_right"
            android:text="@string/swipe_right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    • Kết quả chúng ta sẽ có được một view như sau:
    • Trong hàm onServiceConnected() của HelperService, chúng ta có thể khởi tạo một giao diện sử dụng quyền WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY – thứ sẽ giúp chúng ta vẽ lên trên màn hình.
        @Override
        protected void onServiceConnected() {
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            mLayout = new FrameLayout(this);
            WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
            lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
            lp.format = PixelFormat.TRANSLUCENT;
            lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
            lp.gravity = Gravity.TOP;
            LayoutInflater inflater = LayoutInflater.from(this);
            inflater.inflate(R.layout.action_bar, mLayout);
        }

    Thiết lập các chức năng cho AccessibilityService

    • Từ các quá trình cài đặt trên chúng ta đã có giao diện cho service của mình, giờ là lúc chúng ta thêm các chức năng cho các nút bấm này
    • Ví dụ về chức năng tắt nguồn
        private void configurePowerButton() {
            Button powerButton = mLayout.findViewById(R.id.power);
            powerButton.setOnClickListener(view -> performGlobalAction(GLOBAL_ACTION_POWER_DIALOG));
        }
    • Ví dụ về chức năng tăng âm lượng:
        private void configureVolumeButtonUp() {
            Button volumeUpButton = mLayout.findViewById(R.id.volume_up);
            volumeUpButton.setOnClickListener(view -> {
                AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
                audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
                        AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
            });
        }
    • Ví dụ về chức năng vuốt màn hình:
        private void configureSwipeButtonDown() {
            Button swipeButton = (Button) mLayout.findViewById(R.id.swipe_down);
            swipeButton.setOnClickListener(view -> {
                Path swipePath = new Path();
                swipePath.moveTo(100, 1000);
                swipePath.lineTo(100, 100);
                GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
                gestureBuilder.addStroke(new GestureDescription.StrokeDescription(swipePath, 0, 500));
                dispatchGesture(gestureBuilder.build(), null, null);
            });
        }

    4. Chạy thử trên thiết bị thật

    • Để chạy service này trên thiết bị thật, chúng ta phải chỉnh sửa phần configurations của mục run, chọn Launch OptionsNothing
    • Khi service đã được chạy thành công từ Android Studio, chúng ta phải vào phần Settings -> Additional settings -> Accessibility, chọn đến phần Downloaded Apps chúng ta sẽ thấy tên service của chúng ta (HelperService), ấn chọn vào service và bật service lên. Giao diện các chức năng hỗ trợ của chúng ta sẽ hiển thị lên.
    • Demo trên thiết bị thật

    5. Những hiểm nguy từ Accessibility Service

    • Accessibility Service được sinh ra với một mục đích rất tốt, đó là hộ trỡ những người khuyết tật hoặc những người hạn chế, khó trong các vận động. Tuy nhiên với các khả năng có thể đọc được các dữ liệu trên màn hình, điều khiển điện thoại,… nếu như chúng được sử dụng vào mục đích xấu thì sẽ rất dễ gây nguy hiểm, rủi ro bảo mật thông tin đến cho chủ sở hữu điện thoại.

    Để phòng tránh những rủi ro tiềm ẩn này thì chúng ta nên có những biện pháp phòng tránh như là:

    • Chỉ cài đặt các ứng dụng trên các chợ chính chủ của các hệ điều hành. Accessibility Service được đánh giá là một quyền nguy hiểm. Vậy nên việc kiểm duyệt các ứng dụng này diễn ra rất nghiêm ngặt.
    • Không tải/ cài app từ các nguồn không chính thống, trên các đường link lạ
    • Với các ứng dụng có yêu cầu quyền này, hãy đọc kỹ các điều khoản dịch vụ.

    Author: LamNT59
    References: https://codelabs.developers.google.com/codelabs/developing-android-a11y-service#0
    Github Demo: https://github.com/lamdev99/HelperService

  • SCD (Slowly Changing Dimension) là gì? Các loại SCD và ví dụ cụ thể

    SCD (Slowly Changing Dimension) là gì? Các loại SCD và ví dụ cụ thể

    Xin chào mọi người, ở bài viết trước mình đã chia sẻ về ETL testing và trong quá trình test ETL mình có nhắc đến việc chúng ta sẽ đi kiểm tra, theo dõi cách ghi/thay đổi dữ liệu trong bảng đích đã đúng yêu cầu hay chưa? Vậy cách ghi/thay đổi dữ liệu đó là gì nhỉ? Hôm nay chúng ta sẽ đi tìm hiểu về Slowly Changing Dimension (SCD) nhé!


    1. Slowly Changing Dimension (SCD) là gì?

    image

    SCD (Slowly Changing Dimension) có thể hiểu một cách đơn giản nhất đó là: so sánh dữ liệu nguồn với dữ liệu bảng đích hiện có bằng cách sử dụng Khóa nghiệp vụ – Business key (Khóa duy nhất – Unique Key).

    Nếu không có bản ghi nào khớp thì sẽ coi là Bản ghi mới hoặc Nếu bản ghi khớp thì sẽ so sánh các thuộc tính với các thuộc tính đã thay đổi nếu dữ liệu có vẻ được cập nhật thì nó cập nhật bản ghi hoặc nếu không thì nó để nguyên như không thay đổi.

    Slowly Changing Dimension sẽ kiểm tra các thuộc tính cho ba trường hợp: Bản ghi mới, đã thay đổi hoặc chưa thay đổi.

    2. Tại sao cần Slowly Changing Dimension?

    Trong thế giới Datawarehouse, đôi khi việc theo dõi sự thay đổi kích thước theo thời gian là rất quan trọng. Điều này giúp chúng ta theo dõi dữ liệu tốt hơn và cũng tạo ra các sản phẩm hiệu quả tùy thuộc vào các trường hợp sử dụng.

    3. Tại sao lại gọi là Slowly Changing Dimension?

    Slowly Chaning Dimension – gọi như trên có nghĩa là chúng ta sẽ phải sử dụng thành phần này chỉ cho các bảng không được cập nhật thường xuyên.

    Lưu ý: Không áp dụng cho bảng thường xuyên thay đổi, chỉ áp dụng trên các bảng kích thước (Dimension table) thay đổi chậm.

    4. Các loại SCD – Ví dụ về Slowly Changing Dimensions trong data warehouse (High-Level)

    Các loại SCD (High-Level)

    Sau đây là các loại SCD, mỗi loại đều có một số ưu điểm và nhược điểm riêng.

    1. Type – 0 Giữ lại dữ liệu gốc
    2. Type – 1 Ghi đè lên dữ liệu hiện có
    3. Type – 2 Thêm các bản ghi mới trên cùng một bảng
    4. Type – 3 Thêm cột mới trên cùng một bảng
    5. Type – 4 Sử dụng bảng lịch sử
    6. Type – 6 Phương pháp kết hợp (Loại 1 + Loại 2 + Loại 3)

    image

    SCD type 1 (Ghi đè)

    Loại hành động SCD đầu tiên có thể thực hiện được là ghi đè. Ở đây, các giá trị kích thước được ghi đè bởi các giá trị mới.

    Ví dụ: Khách hàng Nguyễn Văn A chuyển từ HCM đến Hà Nội, thì thành phố của anh ấy sẽ được cập nhật với giá trị mới nhất, tức là Hà Nội

    Original Record – Dữ liệu gốc

    Cust_ID Name City
    1001 Nguyễn Văn A HCM
    1002 Nguyễn Văn B Nam Định

    Updated Record – Dữ liệu được thay đổi

    Cust_ID Name City
    1001 Nguyễn Văn A Hà Nội
    1002 Nguyễn Văn B Nam Định

    Trong ví dụ trên, khách hàng đã di chuyển từ nơi này sang nơi khác và địa chỉ gần đây đã được ghi đè lên các bản ghi hiện có.

    Nhược điểm: chúng ta không thể truy xuất thông tin địa chỉ trước đây của anh ấy từ tình huống này.

    SCD type 2

    • Thêm bản ghi mới
    • Chúng ta có thể nắm bắt thay đổi thuộc tính bằng cách thêm một cột mới làm khóa thay thế (VD: IsActive)

    Khi giá trị của bản ghi hiện tại thay đổi, bản ghi hiện tại được đánh dấu là không hoạt động (inactive – 0) và bản ghi mới được insert vào.

    Kết quả, sẽ có 2 bản ghi được liên kết với Nguyễn Văn A trong bảng được cập nhật, nhưng chỉ có phiên bản mới nhất được đánh dấu là hoạt động (active – 1).

    Original Record – Dữ liệu gốc

    Cust_ID Name City IsActive
    1001 Nguyễn Văn A HCM 1
    1002 Nguyễn Văn B Nam Định 1

    Updated Record – Dữ liệu được thay đổi

    Cust_ID Name City IsActive
    1001 Nguyễn Văn A HCM 0
    1001 Nguyễn Văn A Hà Nội 1
    1002 Nguyễn Văn B Nam Định 1

    Ưu điểm: thỏa mãn điểm trừ trước đó theo dõi dữ liệu lịch sử bằng cách tạo mục nhập mới trên cùng một bảng.

    Nhược điểm: mặc dù nó nắm bắt dữ liệu lịch sử, nhưng nó có thể dẫn đến hoạt động tốn kém ở phía cơ sở dữ liệu.

    SCD Type 3 (Thêm cột giá trị trước đó)

    Loại SCD phổ biến thứ ba là thêm một cột giá trị trước đó. Ở đây, các phiên bản trước và hiện tại được duy trì trong một hàng.

    Hạn chế của phương pháp này là nó sẽ chỉ có hiện tại/trước đó chứ không phải toàn bộ lịch sử

    Original Record – Dữ liệu gốc

    Cust_ID Name City
    1001 Nguyễn Văn A HCM
    1002 Nguyễn Văn B Nam Định

    Updated Record – Dữ liệu được thay đổi

    Cust_ID Name Current City Previous City
    1001 Nguyễn Văn A Hà Nội HCM
    1002 Nguyễn Văn B Nam Định

    SCD Type 4: Thêm bảng mới (Bảng lịch sử)

    • Sử dụng bảng Lịch sử
    • Trong cách tiếp cận này, bảng lịch sử riêng biệt được tạo ra để theo dõi các thay đổi.
    • Bảng chính sẽ chỉ có dữ liệu mới nhất
    • Ưu điểm: Phản hồi nhanh hơn đối với các truy vấn yêu cầu dữ liệu mới nhất. Dễ quản lý và viết mã, thuận lợi cho các thuộc tính có tính biến động cao hoặc được sử dụng thường xuyên ở kích thước rất lớn.
    • Nhược điểm: Đôi khi tổng hợp/tham gia giữa dữ liệu hoạt động và lịch sử có thể mất thời gian và trở nên phức tạp

    Customer Table

    Cust_ID Name City
    1001 Nguyễn Văn A Hà Nội
    1002 Nguyễn Văn B Nam Định

    Customer History Table

    Cust_ID Name City Last_updated_date
    1001 Nguyễn Văn A HCM 11-03-2023
    1001 Nguyễn Văn A Hà Nam 11-05-2023
    1001 Nguyễn Văn A Bắc Ninh 11-06-2023

    SCD Type 6

    Phương pháp kết hợp (Loại 1 + Loại 2 + Loại 3)

    • Ưu điểm: Mọi bản chụp thay đổi dữ liệu đều có trong cùng một bảng
    • Nhược điểm: Phức tạp, khó quản lý, bảng lớn.
    Cust_ID Name City EffectiveFrom EffectiveTo IsActive
    1001 Nguyễn Văn A HCM 11-03-2023 11-05-2023 0
    1001 Nguyễn Văn A Hà Nam 11-05-2023 11-06-2023 0
    1001 Nguyễn Văn A Bắc Ninh 11-06-2023 03-07-2023 0
    1001 Nguyễn Văn A Hà Nội 03-07-2023 1
    1002 Nguyễn Văn B Nam Định 22-02-2023 1

    Ở ví dụ trên, dữ liệu lịch sử được theo dõi trong hàng mới được xác định bởi các trường ngày bắt đầu và ngày kết thúc. Ngoài ra, chúng ta có thể có trường cờ isActive để xác định bản ghi hiện tại từ danh sách. Chúng ta có thể duy trì lịch sử của tất cả các thay đổi đồng thời cập nhật giá trị hiện tại trên các bản ghi hiện có.


    Trên đây là những kiến thức về SCD (Slowly Changing Dimension), Các loại SCD và kịch bản kiểm thử, bài viết cũng khá dài rồi, nếu có cơ hội, bài viết tới mình sẽ chia sẻ chi tiết hơn về SCD type 2. Mong rằng bài viết này sẽ giúp ích được cho mọi người trong quá trình tìm hiểu về SCD. Nếu mọi người có thắc mắc hay câu hỏi gì đừng ngần ngại comment và cùng nhau giải đáp nhé!

    Hẹn gặp lại mọi người trong bài viết tiếp theo.

    Tài liệu tham khảo:

    https://www.expressanalytics.com/blog/what-is-a-slowly-changing-dimension-and-the-logic-in-implementation/

    https://www.learnmsbitutorials.net/slowly-changing-dimensions-ssis.php