Line có bảo mật không có dấu chuông là gì năm 2024

Việc tăng cường tính bảo mật cho ứng dụng sẽ giúp bạn duy trì sự tin tưởng của người dùng và tính toàn vẹn của thiết bị.

Trang này trình bày một số phương pháp hay nhất có tác động tích cực đáng kể đến tính bảo mật của ứng dụng.

Thực thi hoạt động giao tiếp an toàn

Khi bảo vệ dữ liệu được trao đổi giữa ứng dụng của bạn và các ứng dụng khác hoặc giữa ứng dụng của bạn và một trang web, bạn sẽ cải thiện độ ổn định của ứng dụng cũng như bảo vệ dữ liệu mà bạn gửi và nhận.

Bảo vệ hoạt động giao tiếp giữa các ứng dụng

Để giao tiếp an toàn hơn giữa các ứng dụng, hãy dùng ý định ngầm ẩn cùng trình chọn ứng dụng, quyền dựa trên chữ ký và nhà cung cấp nội dung không được xuất.

Hiển thị trình chọn ứng dụng

Nếu một ý định ngầm ẩn có thể mở ít nhất hai ứng dụng trên thiết bị của người dùng, hãy hiển thị rõ ràng trình chọn ứng dụng. Chiến lược tương tác này cho phép người dùng chuyển thông tin nhạy cảm đến một ứng dụng mà họ tin tưởng.

Kotlin

val intent = Intent(Intent.ACTION_SEND) val possibleActivitiesList: List<ResolveInfo> =

    packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**val chooser = resources.getString(R.string.chooser_title).let { title ->**
Intent.createChooser(intent, title) } startActivity(chooser) } else if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}

Java

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

Thông tin liên quan:

  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <permission android:name="my_custom_permission_name"  
                android:protectionLevel="signature" />  
    
    3

Áp dụng các quyền dựa trên chữ ký

Khi bạn chia sẻ dữ liệu giữa hai ứng dụng mà bạn kiểm soát hoặc sở hữu, hãy sử dụng các quyền dựa trên chữ ký. Các quyền này không yêu cầu người dùng xác nhận và thay vào đó, hãy kiểm tra để đảm bảo rằng các ứng dụng truy cập vào dữ liệu đã được xác nhận bằng cùng một khoá ký. Do đó, các quyền này đem đến trải nghiệm người dùng an toàn và đơn giản hơn.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
Thông tin liên quan:

  • Ký ứng dụng

Không cho phép truy cập thông tin về các nhà cung cấp nội dung của ứng dụng

Không cho phép ứng dụng của các nhà phát triển khác truy cập vào các đối tượng

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
5 của ứng dụng một cách rõ ràng, trừ phi bạn có ý định gửi dữ liệu từ ứng dụng của mình đến một ứng dụng khác mà bạn không sở hữu. Chế độ cài đặt này rất quan trọng nếu ứng dụng của bạn có thể được cài đặt trên các thiết bị chạy Android 4.1.1 (API cấp 16) trở xuống, vì theo mặc định, thuộc tính của phần tử

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
7 là

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
8 trên các phiên bản Android đó.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<application ... >
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        ...
        **android:exported="false"**>
        <!-- Place child elements of <provider> here. -->
    </provider>
    ...
</application>
</manifest>

Yêu cầu thông tin xác thực trước khi hiện thông tin nhạy cảm

Khi bạn yêu cầu người dùng cung cấp thông tin xác thực để họ có thể truy cập vào thông tin nhạy cảm hoặc nội dung cao cấp trong ứng dụng, hãy yêu cầu mã PIN/mật khẩu/hình mở khoá hoặc thông tin xác thực sinh trắc học, chẳng hạn như tính năng nhận dạng khuôn mặt hoặc nhận dạng vân tay.

Để tìm hiểu thêm về cách yêu cầu thông tin xác thực sinh trắc học, hãy xem hướng dẫn về quy trình xác thực sinh trắc học.

Áp dụng các biện pháp bảo mật mạng

Các phần sau đây mô tả cách bạn có thể cải thiện tính bảo mật mạng của ứng dụng.

Sử dụng lưu lượng truy cập TLS (Bảo mật tầng truyền tải)

Nếu ứng dụng của bạn giao tiếp với một máy chủ web có chứng chỉ do một tổ chức phát hành chứng chỉ (CA) nổi tiếng và đáng tin cậy cấp, hãy sử dụng yêu cầu HTTPS như sau:

Kotlin

val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {

...
}

Java

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

Thêm một cấu hình bảo mật mạng

Nếu ứng dụng của bạn dùng các CA mới hoặc tuỳ chỉnh, thì bạn có thể khai báo chế độ cài đặt bảo mật mạng trong tệp cấu hình. Quá trình này cho phép bạn tạo cấu hình mà không cần sửa đổi bất kỳ mã ứng dụng nào.

Để thêm một tệp cấu hình bảo mật mạng vào ứng dụng, hãy làm theo các bước sau:

  1. Khai báo cấu hình trong tệp kê khai của ứng dụng:

<manifest ... >

<application
    **android:networkSecurityConfig="@xml/network_security_config"**
    ... >
    <!-- Place child elements of <application> element here. -->
</application>
</manifest>

  1. Thêm một tệp tài nguyên XML nằm tại <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <permission android:name="my_custom_permission_name"  
                android:protectionLevel="signature" />  
  2. Hãy chỉ định rằng tất cả lưu lượng truy cập đến các miền cụ thể đều phải sử dụng HTTPS bằng cách vô hiệu hoá dữ liệu chưa được mã hoá (clear-text): <network-security-config>
    <domain-config cleartextTrafficPermitted="false">  
        <domain includeSubdomains="true">secure.example.com</domain>  
        ...  
    </domain-config>  
    
    </network-security-config> Trong quá trình phát triển, bạn có thể sử dụng phần tử <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <application ... >  
        <provider  
            android:name="android.support.v4.content.FileProvider"  
            android:authorities="com.example.myapp.fileprovider"  
            ...  
            android:exported="false">  
            <! Place child elements of <provider> here. >  
        </provider>  
        ...  
    </application>  
    
    </manifest> 0 để cho phép rõ ràng các chứng chỉ do người dùng cài đặt. Phần tử này ghi đè các tuỳ chọn quan trọng về bảo mật của ứng dụng trong quá trình gỡ lỗi và kiểm thử mà không ảnh hưởng đến cấu hình phát hành của ứng dụng. Đoạn mã sau đây cho biết cách xác định phần tử này trong tệp XML cấu hình bảo mật mạng của ứng dụng: <network-security-config>
    <debug-overrides>  
        <trust-anchors>  
            <certificates src="user" />  
        </trust-anchors>  
    </debug-overrides>  
    
    </network-security-config>

Thông tin liên quan: Cấu hình bảo mật mạng

Tạo trình quản lý tin cậy của riêng bạn

Trình kiểm tra TLS của bạn không nên chấp nhận mọi chứng chỉ. Có thể bạn sẽ phải thiết lập một trình quản lý tin cậy và xử lý mọi cảnh báo TLS xảy ra nếu trường hợp sử dụng của bạn tuân theo một trong các điều kiện sau:

  • Bạn đang kết nối với một máy chủ web có chứng chỉ do một CA mới hoặc tuỳ chỉnh ký.
  • CA đó không đáng tin cậy đối với thiết bị bạn đang dùng.
  • Bạn không thể sử dụng .

Để tìm hiểu thêm về cách hoàn tất các bước này, hãy xem nội dung thảo luận về cách xử lý .

Thông tin liên quan:

  • Bảo mật bằng giao thức mạng
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <application ... >  
        <provider  
            android:name="android.support.v4.content.FileProvider"  
            android:authorities="com.example.myapp.fileprovider"  
            ...  
            android:exported="false">  
            <! Place child elements of <provider> here. >  
        </provider>  
        ...  
    </application>  
    
    </manifest> 1
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <application ... >  
        <provider  
            android:name="android.support.v4.content.FileProvider"  
            android:authorities="com.example.myapp.fileprovider"  
            ...  
            android:exported="false">  
            <! Place child elements of <provider> here. >  
        </provider>  
        ...  
    </application>  
    
    </manifest> 2
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <application ... >  
        <provider  
            android:name="android.support.v4.content.FileProvider"  
            android:authorities="com.example.myapp.fileprovider"  
            ...  
            android:exported="false">  
            <! Place child elements of <provider> here. >  
        </provider>  
        ...  
    </application>  
    
    </manifest> 3

Cẩn trọng khi sử dụng các đối tượng WebView

Các đối tượng

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<application ... >
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        ...
        **android:exported="false"**>
        <!-- Place child elements of <provider> here. -->
    </provider>
    ...
</application>
</manifest>

4 trong ứng dụng không nên cho phép người dùng chuyển đến những trang web nằm ngoài tầm kiểm soát của bạn. Bất cứ khi nào có thể, hãy dùng danh sách cho phép để hạn chế nội dung mà đối tượng

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<application ... >
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        ...
        **android:exported="false"**>
        <!-- Place child elements of <provider> here. -->
    </provider>
    ...
</application>
</manifest>

5 của ứng dụng tải.

Ngoài ra, bạn không bao giờ được bật trừ phi bạn hoàn toàn nắm quyền kiểm soát và tin tưởng nội dung trong các đối tượng

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<application ... >
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        ...
        **android:exported="false"**>
        <!-- Place child elements of <provider> here. -->
    </provider>
    ...
</application>
</manifest>

5 của ứng dụng.

Sử dụng các kênh thư HTML

Nếu ứng dụng của bạn cần sử dụng chế độ hỗ trợ giao diện JavaScript trên các thiết bị chạy Android 6.0 (API cấp 23) trở lên, hãy sử dụng các kênh thư HTML thay vì việc giao tiếp giữa một trang web và ứng dụng, như bạn có thể thấy trong đoạn mã sau:

Kotlin

val myWebView: WebView = findViewById(R.id.webview) // channel[0] and channel[1] represent the two ports. // They are already entangled with each other and have been started. val channel: Array<out WebMessagePort> = myWebView.createWebMessageChannel() // Create handler for channel[0] to receive messages. channel[0].setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {

override fun onMessage(port: WebMessagePort, message: WebMessage) {
    Log.d(TAG, "On port $port, received this message: $message")
}
}) // Send a message from channel[1] to channel[0]. channel[1].postMessage(WebMessage("My secure message"))

Java

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

0

Thông tin liên quan:

  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <application ... >  
        <provider  
            android:name="android.support.v4.content.FileProvider"  
            android:authorities="com.example.myapp.fileprovider"  
            ...  
            android:exported="false">  
            <! Place child elements of <provider> here. >  
        </provider>  
        ...  
    </application>  
    
    </manifest> 7
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <application ... >  
        <provider  
            android:name="android.support.v4.content.FileProvider"  
            android:authorities="com.example.myapp.fileprovider"  
            ...  
            android:exported="false">  
            <! Place child elements of <provider> here. >  
        </provider>  
        ...  
    </application>  
    
    </manifest> 8

Cấp các quyền phù hợp

Chỉ yêu cầu số lượng quyền tối thiểu cần thiết để ứng dụng hoạt động bình thường. Nếu được, ứng dụng của bạn nên từ bỏ một số quyền không cần dùng nữa.

Sử dụng ý định để trì hoãn các quyền

Bất cứ khi nào có thể, không nên thêm quyền vào ứng dụng của bạn để thực hiện một hành động mà ứng dụng khác có thể hoàn thành. Thay vào đó, hãy dùng ý định để trì hoãn yêu cầu này cho một ứng dụng khác đã có quyền cần thiết.

Ví dụ sau đây cho biết cách sử dụng ý định để hướng người dùng chuyển đến một ứng dụng danh bạ thay vì yêu cầu các quyền

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<application ... >
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        ...
        **android:exported="false"**>
        <!-- Place child elements of <provider> here. -->
    </provider>
    ...
</application>
</manifest>

9 và

val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {

...
}

0:

Kotlin

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

1

Java

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

2

Ngoài ra, nếu ứng dụng của bạn cần thực hiện thao tác I/O dựa trên tệp, chẳng hạn như truy cập vào bộ nhớ hoặc chọn tệp, thì ứng dụng không cần các quyền đặc biệt vì hệ thống có thể hoàn thành những thao tác này thay cho ứng dụng. Tốt hơn hết, sau khi người dùng chọn nội dung tại một URI cụ thể, ứng dụng thực hiện lệnh gọi sẽ được cấp quyền đối với tài nguyên đã chọn.

Thông tin liên quan:

  • Ý định phổ biến
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">  
    <permission android:name="my_custom_permission_name"  
                android:protectionLevel="signature" />  
    
    3

Hãy làm theo những phương pháp hay nhất dưới đây để chia sẻ nội dung ứng dụng của bạn với các ứng dụng khác theo cách an toàn hơn:

  • Thực thi quyền chỉ đọc hoặc quyền chỉ ghi khi cần.
  • Cung cấp cho khách hàng quyền truy cập một lần vào dữ liệu bằng cách sử dụng cờ val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {
    ...  
    
    } 2 và val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {
    ...  
    
    } 3.
  • Khi chia sẻ dữ liệu, hãy dùng các URI val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {
    ...  
    
    } 4, không phải URI val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {
    ...  
    
    } 5. Các thực thể của val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {
    ...  
    
    } 6 sẽ giúp bạn thực hiện việc này.

Đoạn mã sau đây cho biết cách sử dụng cờ cấp quyền URI và quyền của nhà cung cấp nội dung để hiển thị tệp PDF của ứng dụng trong một ứng dụng trình xem PDF riêng:

Kotlin

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

3

Java

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

4

Lưu ý: Việc thực thi các tệp trong thư mục gốc có thể ghi của ứng dụng bị coi là một lỗi vi phạm W^X. Vì lý do này, các ứng dụng không đáng tin cậy nhắm đến Android 10 (API cấp 29) trở lên không thể gọi

val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {

...
}

7 trên các tệp trong thư mục gốc của ứng dụng. Chỉ mã nhị phân được nhúng trong tệp APK của ứng dụng mới có thể làm như vậy. Ngoài ra, các ứng dụng nhắm đến Android 10 trở lên không thể sửa đổi mã có thể thực thi trong bộ nhớ từ các tệp đã mở bằng

val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {

...
}

8. Các tệp này bao gồm mọi tệp đối tượng được chia sẻ (

val url = URL("https://www.google.com") val urlConnection = url.openConnection() as HttpsURLConnection urlConnection.connect() urlConnection.inputStream.use {

...
}

  1. có hình thức chuyển vị trí văn bản.

Thông tin liên quan:

Lưu trữ dữ liệu một cách an toàn

Mặc dù ứng dụng của bạn có thể yêu cầu quyền truy cập vào thông tin nhạy cảm của người dùng, nhưng người dùng sẽ chỉ cấp cho ứng dụng quyền truy cập vào dữ liệu nếu họ tin rằng bạn có biện pháp bảo vệ đúng cách.

Lưu trữ dữ liệu riêng tư vào bộ nhớ trong

Bộ nhớ trong của thiết bị được đặt trong hộp cát cho mỗi ứng dụng sẽ lưu trữ tất cả dữ liệu riêng tư của người dùng. Ứng dụng của bạn không cần yêu cầu quyền xem các tệp này và các ứng dụng khác cũng không thể truy cập vào tệp. Khi người dùng gỡ cài đặt một ứng dụng, thiết bị sẽ xoá tất cả tệp mà ứng dụng đó đã lưu vào bộ nhớ trong như một biện pháp bảo mật bổ sung.

Đoạn mã sau đây minh hoạ một cách để ghi dữ liệu vào bộ nhớ trong:

Kotlin

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

5

Java

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

6

Đoạn mã sau đây cho thấy hoạt động đảo ngược, đọc dữ liệu từ bộ nhớ trong:

Kotlin

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

7

Java

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

8

Thông tin liên quan:

  • Tổng quan về lưu trữ dữ liệu và tệp
  • URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 1
  • URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 2
  • URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); 3

Lưu trữ dữ liệu trong bộ nhớ ngoài dựa trên trường hợp sử dụng

Hãy sử dụng bộ nhớ ngoài đối với những tệp có kích thước lớn, không chứa thông tin nhạy cảm, dành riêng cho ứng dụng của bạn cũng như những tệp mà ứng dụng của bạn chia sẻ với các ứng dụng khác. Các API cụ thể mà bạn dùng phụ thuộc vào việc ứng dụng của bạn được thiết kế để truy cập vào các tệp dành riêng cho ứng dụng hay truy cập vào các tệp được chia sẻ.

Nếu một tệp không chứa thông tin riêng tư hoặc nhạy cảm mà chỉ cung cấp giá trị cho người dùng trong ứng dụng, hãy lưu trữ tệp đó trong một .

Nếu ứng dụng của bạn cần truy cập hoặc lưu trữ một tệp cung cấp giá trị cho các ứng dụng khác, hãy sử dụng một trong những API sau đây tuỳ theo trường hợp sử dụng của bạn:

  • Tệp nội dung nghe nhìn: Để lưu trữ và truy cập vào tệp hình ảnh, tệp âm thanh và video được chia sẻ giữa các ứng dụng, hãy sử dụng API Media Store (API Kho nội dung nghe nhìn).
  • Các tệp khác: Để lưu trữ và truy cập vào các loại tệp được chia sẻ khác, kể cả những tệp đã tải xuống, hãy sử dụng Khung truy cập bộ nhớ.

Kiểm tra dung lượng lưu trữ có sẵn

Nếu ứng dụng của bạn tương tác với thiết bị lưu trữ bên ngoài có thể tháo rời, hãy lưu ý rằng người dùng có thể tháo thiết bị lưu trữ khi ứng dụng đang cố gắng truy cập. Bao gồm logic để .

Kiểm tra tính hợp lệ của dữ liệu

Nếu ứng dụng của bạn sử dụng dữ liệu trong bộ nhớ ngoài, hãy đảm bảo rằng nội dung của dữ liệu không bị hỏng hoặc bị sửa đổi. Bao gồm logic để xử lý các tệp không còn ở định dạng ổn định.

Đoạn mã sau đây cho thấy ví dụ về trình xác minh hàm băm:

Kotlin

Intent intent = new Intent(Intent.ACTION_SEND); List<ResolveInfo> possibleActivitiesList = getPackageManager()

    .queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device // can handle the intent. Otherwise, start the intent only if an app // on the user's device can handle the intent. if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
**String title = getResources().getString(R.string.chooser_title);**
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); } else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

9

Java

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
0

Chỉ lưu trữ dữ liệu không nhạy cảm trong các tệp bộ nhớ đệm

Để truy cập nhanh hơn vào dữ liệu không nhạy cảm của ứng dụng, hãy lưu dữ liệu đó trong bộ nhớ đệm của thiết bị. Đối với các bộ nhớ đệm có dung lượng từ 1 MB trở lên, hãy sử dụng

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

4. Đối với các bộ nhớ đệm có dung lượng từ 1 MB trở xuống, hãy sử dụng

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

5. Cả hai phương thức đều cung cấp cho bạn đối tượng

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

6 có chứa dữ liệu đã lưu vào bộ nhớ đệm của ứng dụng.

Đoạn mã sau đây cho biết cách lưu tệp vào bộ nhớ đệm mà ứng dụng của bạn đã tải xuống gần đây:

Kotlin

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
1

Java

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.myapp">
<permission android:name="my_custom_permission_name"
            **android:protectionLevel="signature"** />
2

Lưu ý: Nếu bạn sử dụng

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

4 để đặt bộ nhớ đệm của ứng dụng trong bộ nhớ dùng chung, thì người dùng có thể tháo phương tiện chứa bộ nhớ này trong khi ứng dụng của bạn đang chạy. Bao gồm logic để xử lý linh hoạt tình trạng thiếu bộ nhớ đệm xảy ra khi người dùng thực hiện hành vi trên.

Chú ý: Không có chế độ bảo mật nào áp dụng cho các tệp này. Do đó, mọi ứng dụng nhắm đến Android 10 (API cấp 29) trở xuống và có quyền

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

8 có thể truy cập vào nội dung của bộ nhớ đệm này.

Thông tin liên quan: Tổng quan về lưu trữ dữ liệu và tệp

Sử dụng SharedPreferences ở chế độ riêng tư

Khi sử dụng

URL url = new URL("https://www.google.com"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream();

9 để tạo hoặc truy cập vào các đối tượng

<manifest ... >

<application
    **android:networkSecurityConfig="@xml/network_security_config"**
    ... >
    <!-- Place child elements of <application> element here. -->
</application>
</manifest>

0 của ứng dụng, hãy sử dụng

<manifest ... >

<application
    **android:networkSecurityConfig="@xml/network_security_config"**
    ... >
    <!-- Place child elements of <application> element here. -->
</application>
</manifest>

1. Bằng cách đó, chỉ có ứng dụng của bạn có thể truy cập thông tin trong tệp về lựa chọn chia sẻ ưu tiên.

Nếu bạn muốn chia sẻ dữ liệu trên nhiều ứng dụng thì đừng sử dụng đối tượng

<manifest ... >

<application
    **android:networkSecurityConfig="@xml/network_security_config"**
    ... >
    <!-- Place child elements of <application> element here. -->
</application>
</manifest>

2. Thay vào đó, hãy làm theo các bước .

Thư viện bảo mật cũng cung cấp lớp EncryptedSharedPreferences giúp bao bọc lớp SharedPreferences cũng như tự động mã hoá các khoá và giá trị.

Thông tin liên quan:

  • Tổng quan về lưu trữ dữ liệu và tệp

Luôn cập nhật các dịch vụ và phần phụ thuộc

Hầu hết ứng dụng đều sử dụng thư viện bên ngoài và thông tin hệ thống của thiết bị để hoàn thành các nhiệm vụ chuyên biệt. Bằng cách cập nhật các phần phụ thuộc của ứng dụng, bạn sẽ khiến các điểm giao tiếp này trở nên an toàn hơn.

Kiểm tra nhà cung cấp dịch vụ bảo mật của Dịch vụ Google Play

Lưu ý: Phần này chỉ áp dụng cho những ứng dụng nhắm đến các thiết bị đã cài đặt Dịch vụ Google Play.

Nếu ứng dụng của bạn sử dụng Dịch vụ Google Play, hãy đảm bảo dịch vụ được cập nhật trên thiết bị cài đặt ứng dụng. Thực hiện quy trình kiểm tra không đồng bộ bên ngoài luồng giao diện người dùng. Nếu thiết bị chưa được cập nhật, hãy kích hoạt lỗi uỷ quyền.

Để xác định xem Dịch vụ Google Play đã được cập nhật trên thiết bị cài đặt ứng dụng của bạn hay chưa, hãy làm theo các bước trong hướng dẫn Cập nhật trình cung cấp dịch vụ bảo mật để chống khai thác SSL.

Thông tin liên quan:

  • <manifest ... >
    <application  
        android:networkSecurityConfig="@xml/network_security_config"  
        ... >  
        <! Place child elements of <application> element here. >  
    </application>  
    
    </manifest> 3
  • <manifest ... >
    <application  
        android:networkSecurityConfig="@xml/network_security_config"  
        ... >  
        <! Place child elements of <application> element here. >  
    </application>  
    
    </manifest> 4

Cập nhật tất cả phần phụ thuộc ứng dụng

Trước khi triển khai ứng dụng, hãy đảm bảo rằng bạn đã cập nhật tất cả các thư viện, SDK và các phần phụ thuộc khác: