Code chức năng đồng bộ hóa trên android năm 2024

Trình duyệt nhân Chromium này cũng giới thiệu Flow để chia sẻ các đường dẫn, video, ghi chú giữa điện thoại và trình duyệt máy tính.

Code chức năng đồng bộ hóa trên android năm 2024

Opera bổ sung 3 tính năng hữu dụng trong bản cập nhật mới

Theo Engadget, trình duyệt Opera đang giúp việc đồng bộ dữ liệu giữa máy tính và thiết bị Android dễ dàng hơn. Bản cập nhật mới nhất (phiên bản 71 trên máy tính và 60 trên Android) đi kèm một tính năng mới tên là Sync, không yêu cầu bạn phải có email và mật khẩu để sử dụng.

Bạn chỉ cần vào opera.com/connect trên máy tính, quét mã QR được hiển thị bằng công cụ đọc mã QR tích hợp sẵn trong trình duyệt Opera của Android. Khi đã xong, tất cả trang web đã đánh dấu, trang yêu thích, lịch sử... từ máy tính sẽ được đưa lên điện thoại.

Opera nói ý tưởng này bắt nguồn từ việc mọi người “khó chịu khi phải gõ lại thông tin đăng nhập và mật khẩu dài dòng”. Lưu ý, bạn vẫn có thể đồng bộ dữ liệu bằng tài khoản email và mật khẩu như trước nếu muốn.

Ngoài ra, Opera cũng giới thiệu tính năng khác là Flow cho phép bạn chia sẻ đường dẫn, video YouTube, hình ảnh và ghi chú cá nhân giữa điện thoại và máy tính. Bạn có thể làm điều này dễ dàng bằng cách highlight đường dẫn, văn bản hoặc hình ảnh rồi chọn “send to flow”. Flow giúp người dùng dán (paste) và tải lên tập tin có dung lượng tối đa 10 MB.

Cuối cùng, Opera trình làng tính năng “Suggested Sites” hỗ trợ người dùng xác định trang web họ thường ghé thăm và hiển thị chúng ở phần truy cập nhanh. Rõ ràng, những tính năng này khiến Opera trở nên hữu ích hơn.

DataItem xác định giao diện mà hệ thống sử dụng để đồng bộ hoá dữ liệu giữa thiết bị cầm tay và thiết bị đeo. DataItem thường bao gồm các thành phần sau:

  • Tải trọng: Một mảng byte mà bạn có thể thiết lập bằng dữ liệu, cho phép bạn thực hiện quá trình chuyển đổi tuần tự hoặc quá trình huỷ chuyển đổi tuần tự đối tượng riêng. Kích thước tải trọng được giới hạn ở 100 KB.
  • Đường dẫn: Một chuỗi duy nhất phải bắt đầu bằng dấu gạch chéo xuôi, chẳng hạn như "/path/to/data".

Lưu ý: API Lớp dữ liệu chỉ có thể gửi thông báo và đồng bộ hoá dữ liệu với điện thoại Android hoặc đồng hồ Wear OS. Nếu thiết bị Wear OS của bạn được ghép nối với thiết bị iOS, thì API Lớp dữ liệu sẽ không hoạt động.

Vì lý do này, đừng nên sử dụng API Lớp dữ liệu làm phương thức chính để giao tiếp với mạng. Thay vào đó, hãy dùng cùng một mẫu như ứng dụng dành cho thiết bị di động, với một số điểm khác biệt nhỏ.

Bạn thường không triển khai DataItem trực tiếp. Thay vào đó, bạn sẽ làm như sau:

  1. Tạo đối tượng PutDataRequest, chỉ định một đường dẫn chuỗi để nhận dạng duy nhất mục đó.
  2. Gọi để đặt trọng tải.
  3. Nếu sự chậm trễ trong quá trình đồng bộ hoá gây ảnh hưởng không tốt đến trải nghiệm người dùng, hãy gọi .
  4. Sử dụng phương thức public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";  
    private DataClient dataClient;  
    private int count = 0;  
    ...  
    // Create a data map and put data in it  
    private void increaseCounter() {  
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");  
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);  
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();  
        Task putDataTask = dataClient.putDataItem(putDataReq);  
    }  
    
    ... } 1 của lớp public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";  
    private DataClient dataClient;  
    private int count = 0;  
    ...  
    // Create a data map and put data in it  
    private void increaseCounter() {  
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");  
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);  
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();  
        Task putDataTask = dataClient.putDataItem(putDataReq);  
    }  
    
    ... } 2 để yêu cầu hệ thống tạo mục dữ liệu.

Khi yêu cầu các mục dữ liệu, hệ thống sẽ trả về các đối tượng giúp triển khai giao diện DataItem đúng cách. Tuy nhiên, thay vì thao tác với các byte thô bằng setData(), bạn nên để biết một mục dữ liệu có giao diện giống với

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

5.

Để biết thêm thông tin, hãy xem ứng dụng Mẫu DataLayer.

Đồng bộ hoá dữ liệu với bản đồ dữ liệu

Hãy sử dụng lớp

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

6 khi có thể. Phương pháp này cho phép bạn xử lý các mục dữ liệu dưới dạng Android

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

5, nhờ đó hệ thống sẽ thực hiện quá trình chuyển đổi tuần tự hoặc quá trình huỷ chuyển đổi tuần tự đối tượng cho bạn, đồng thời bạn có thể thao tác dữ liệu với các cặp khoá-giá trị.

Để sử dụng bản đồ dữ liệu:

  1. Tạo một đối tượng public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";  
    private DataClient dataClient;  
    private int count = 0;  
    ...  
    // Create a data map and put data in it  
    private void increaseCounter() {  
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");  
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);  
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();  
        Task putDataTask = dataClient.putDataItem(putDataReq);  
    }  
    
    ... } 8, đặt đường dẫn của mục dữ liệu. Lưu ý: Chuỗi đường dẫn là giá trị nhận dạng duy nhất cho mục dữ liệu, cho phép bạn truy cập mục đó từ một trong hai bên của kết nối. Đường dẫn phải bắt đầu bằng một dấu gạch chéo xuôi. Nếu bạn đang sử dụng dữ liệu phân cấp trong ứng dụng, hãy tạo một lược đồ đường dẫn khớp với cấu trúc của dữ liệu.
  2. Gọi để lấy bản đồ dữ liệu mà bạn có thể đặt các giá trị.
  3. Đặt giá trị cho bản đồ dữ liệu bằng các phương thức private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener {
    private var count = 0  
    override fun onResume() {  
        super.onResume()  
        Wearable.getDataClient(this).addListener(this)  
    }  
    override fun onPause() {  
        super.onPause()  
        Wearable.getDataClient(this).removeListener(this)  
    }  
    override fun onDataChanged(dataEvents: DataEventBuffer) {  
        dataEvents.forEach { event ->  
            // DataItem changed  
            if (event.type == DataEvent.TYPE_CHANGED) {  
                event.dataItem.also { item ->  
                    if (item.uri.path.compareTo("/count") == 0) {  
                        DataMapItem.fromDataItem(item).dataMap.apply {  
                            updateCount(getInt(COUNT_KEY))  
                        }  
                    }  
                }  
            } else if (event.type == DataEvent.TYPE_DELETED) {  
                // DataItem deleted  
            }  
        }  
    }  
    // Method to update the count  
    private fun updateCount(int: Int) { ... }  
    ...  
    
    } 0, chẳng hạn như .
  4. Nếu độ trễ trong quá trình đồng bộ hoá ảnh hưởng tiêu cực đến trải nghiệm người dùng, hãy gọi .
  5. Gọi để lấy đối tượng PutDataRequest.
  6. Sử dụng phương thức public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";  
    private DataClient dataClient;  
    private int count = 0;  
    ...  
    // Create a data map and put data in it  
    private void increaseCounter() {  
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");  
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);  
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();  
        Task putDataTask = dataClient.putDataItem(putDataReq);  
    }  
    
    ... } 1 của lớp public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";  
    private DataClient dataClient;  
    private int count = 0;  
    ...  
    // Create a data map and put data in it  
    private void increaseCounter() {  
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");  
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);  
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();  
        Task putDataTask = dataClient.putDataItem(putDataReq);  
    }  
    
    ... } 2 để yêu cầu hệ thống tạo mục dữ liệu. Lưu ý: Nếu thiết bị cầm tay và thiết bị đeo bị ngắt kết nối, dữ liệu sẽ được lưu vào bộ đệm và đồng bộ hoá khi kết nối được thiết lập lại.

Phương thức

private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener {

private var count = 0
override fun onResume() {
    super.onResume()
    Wearable.getDataClient(this).addListener(this)
}
override fun onPause() {
    super.onPause()
    Wearable.getDataClient(this).removeListener(this)
}
override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents.forEach { event ->
        // DataItem changed
        if (event.type == DataEvent.TYPE_CHANGED) {
            event.dataItem.also { item ->
                if (item.uri.path.compareTo("/count") == 0) {
                    DataMapItem.fromDataItem(item).dataMap.apply {
                        updateCount(getInt(COUNT_KEY))
                    }
                }
            }
        } else if (event.type == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private fun updateCount(int: Int) { ... }
...
}

7 trong ví dụ sau cho biết cách tạo bản đồ dữ liệu và đặt dữ liệu vào bản đồ đó.

Kotlin

private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity() {

private lateinit var dataClient: DataClient
private var count = 0
...
// Create a data map and put data in it
private fun increaseCounter() {
    val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run {
        dataMap.putInt(COUNT_KEY, count++)
        asPutDataRequest()
    }
    val putDataTask: Task = dataClient.putDataItem(putDataReq)
}
...
}

Java

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

Để biết thêm thông tin về cách xử lý

private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener {

private var count = 0
override fun onResume() {
    super.onResume()
    Wearable.getDataClient(this).addListener(this)
}
override fun onPause() {
    super.onPause()
    Wearable.getDataClient(this).removeListener(this)
}
override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents.forEach { event ->
        // DataItem changed
        if (event.type == DataEvent.TYPE_CHANGED) {
            event.dataItem.also { item ->
                if (item.uri.path.compareTo("/count") == 0) {
                    DataMapItem.fromDataItem(item).dataMap.apply {
                        updateCount(getInt(COUNT_KEY))
                    }
                }
            }
        } else if (event.type == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private fun updateCount(int: Int) { ... }
...
}

8, hãy xem tài liệu tham khảo.

Đặt mức độ ưu tiên của DataItem

API

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

2 cho phép sử dụng các yêu cầu khẩn cấp để đồng bộ hoá đối tượng DataItem. Thông thường, hệ thống trì hoãn việc phân phối các mục dữ liệu đến mạng Wear OS để cải thiện thời lượng pin cho thiết bị của người dùng. Tuy nhiên, nếu độ trễ trong việc đồng bộ hoá các mục dữ liệu ảnh hưởng tiêu cực đến trải nghiệm người dùng, bạn có thể đánh dấu các mục đó là khẩn cấp. Ví dụ: trong một ứng dụng điều khiển từ xa mà người dùng muốn các thao tác của mình được phản ánh ngay lập tức, bạn có thể gọi để hệ thống đồng bộ hoá ngay các mục dữ liệu.

Nếu bạn không gọi

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

0, hệ thống có thể trì hoãn tối đa 30 phút trước khi đồng bộ hoá các mục dữ liệu không khẩn cấp, mặc dù thời gian trễ thường chỉ là vài phút. Mức độ khẩn cấp mặc định là không khẩn cấp, vì vậy, bạn phải sử dụng

public class MainActivity extends Activity {

private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
    PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
    putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
    Task putDataTask = dataClient.putDataItem(putDataReq);
}
... }

0 nếu cần giữ lại hành vi đồng bộ hoá tức thì từ các phiên bản trước của API Wear OS.

Theo dõi sự kiện mục dữ liệu

Nếu một bên của kết nối lớp dữ liệu thay đổi một mục dữ liệu, hãy thông báo cho người dùng về mọi thay đổi ở phía bên kia của kết nối. Bạn có thể thực hiện việc này bằng cách triển khai trình nghe sự kiện mục dữ liệu.

Đoạn mã trong ví dụ sau sẽ thông báo cho ứng dụng khi giá trị của bộ đếm được xác định trong ví dụ trước thay đổi:

Kotlin

private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener {

private var count = 0
override fun onResume() {
    super.onResume()
    Wearable.getDataClient(this).addListener(this)
}
override fun onPause() {
    super.onPause()
    Wearable.getDataClient(this).removeListener(this)
}
override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents.forEach { event ->
        // DataItem changed
        if (event.type == DataEvent.TYPE_CHANGED) {
            event.dataItem.also { item ->
                if (item.uri.path.compareTo("/count") == 0) {
                    DataMapItem.fromDataItem(item).dataMap.apply {
                        updateCount(getInt(COUNT_KEY))
                    }
                }
            }
        } else if (event.type == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private fun updateCount(int: Int) { ... }
...
}

Java

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

private static final String COUNT_KEY = "com.example.key.count";
private int count = 0;
@Override
protected void onResume() {
    super.onResume();
    Wearable.getDataClient(this).addListener(this);
}
@Override
protected void onPause() {
    super.onPause();
    Wearable.getDataClient(this).removeListener(this);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED) {
            // DataItem changed
            DataItem item = event.getDataItem();
            if (item.getUri().getPath().compareTo("/count") == 0) {
                DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                updateCount(dataMap.getInt(COUNT_KEY));
            }
        } else if (event.getType() == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private void updateCount(int c) { ... }
...
}

Hoạt động này sẽ triển khai giao diện

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

private static final String COUNT_KEY = "com.example.key.count";
private int count = 0;
@Override
protected void onResume() {
    super.onResume();
    Wearable.getDataClient(this).addListener(this);
}
@Override
protected void onPause() {
    super.onPause();
    Wearable.getDataClient(this).removeListener(this);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED) {
            // DataItem changed
            DataItem item = event.getDataItem();
            if (item.getUri().getPath().compareTo("/count") == 0) {
                DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                updateCount(dataMap.getInt(COUNT_KEY));
            }
        } else if (event.getType() == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private void updateCount(int c) { ... }
...
}

4. Hoạt động này tự thêm nó làm trình nghe sự kiện mục dữ liệu bên trong phương thức

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

private static final String COUNT_KEY = "com.example.key.count";
private int count = 0;
@Override
protected void onResume() {
    super.onResume();
    Wearable.getDataClient(this).addListener(this);
}
@Override
protected void onPause() {
    super.onPause();
    Wearable.getDataClient(this).removeListener(this);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED) {
            // DataItem changed
            DataItem item = event.getDataItem();
            if (item.getUri().getPath().compareTo("/count") == 0) {
                DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                updateCount(dataMap.getInt(COUNT_KEY));
            }
        } else if (event.getType() == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private void updateCount(int c) { ... }
...
}

5 và xoá trình nghe trong phương thức

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

private static final String COUNT_KEY = "com.example.key.count";
private int count = 0;
@Override
protected void onResume() {
    super.onResume();
    Wearable.getDataClient(this).addListener(this);
}
@Override
protected void onPause() {
    super.onPause();
    Wearable.getDataClient(this).removeListener(this);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED) {
            // DataItem changed
            DataItem item = event.getDataItem();
            if (item.getUri().getPath().compareTo("/count") == 0) {
                DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                updateCount(dataMap.getInt(COUNT_KEY));
            }
        } else if (event.getType() == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}
// Method to update the count
private void updateCount(int c) { ... }
...
}

6. Để xem cách triển khai bằng hình ảnh, mô hình khung hiển thị và dịch vụ, hãy xem ứng dụng Mẫu DataLayer.

Bạn cũng có thể triển khai trình nghe ở dạng dịch vụ. Để biết thêm thông tin, hãy xem phần .

Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.

Cập nhật lần gần đây nhất: 2024-01-05 UTC.

[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Thiếu thông tin tôi cần" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Quá phức tạp/quá nhiều bước" },{ "type": "thumb-down", "id": "outOfDate", "label":"Đã lỗi thời" },{ "type": "thumb-down", "id": "translationIssue", "label":"Vấn đề về bản dịch" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Vấn đề về mẫu/mã" },{ "type": "thumb-down", "id": "otherDown", "label":"Khác" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Dễ hiểu" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Giúp tôi giải quyết được vấn đề" },{ "type": "thumb-up", "id": "otherUp", "label":"Khác" }]