建立筆記應用程式

筆記是 Android 的核心功能,可以提高使用者在大螢幕裝置上的工作效率。筆記應用程式可讓使用者在浮動視窗或全螢幕中撰寫和素描、擷取螢幕畫面內容並加上註解,以及儲存筆記供日後查看和修改。

使用者可以從螢幕鎖定畫面或執行其他應用程式期間存取記事應用程式。

支援使用觸控筆做筆記,可提供卓越的使用者體驗。

記事角色

RoleManager.ROLE_NOTES 角色可識別筆記應用程式,並授予 LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE 權限。

如要取得應用程式的附註角色,請按照下列步驟操作:

  1. 如要查看角色狀態,請呼叫 isRoleAvailable()
  2. 如果可以使用筆記角色,請呼叫 createRequestRoleIntent() 來取得附註特定意圖。
  3. 使用附註意圖呼叫 startActivityForResult(),提示使用者為應用程式授予附註角色。

只有一個應用程式擁有記事角色。

應用程式會為了回應隱含的 ACTION_CREATE_NOTE 意圖動作而開啟。如果從裝置螢幕鎖定畫面叫用,應用程式會開啟全螢幕;如果在螢幕解鎖狀態下叫用,則會在浮動視窗中啟動。

應用程式資訊清單

應用程式必須在應用程式資訊清單中加入下列宣告,才能符合記事角色的使用資格:

<activity
    android:name="YourActivityName"
    android:exported="true"
    android:showWhenLocked="true"
    android:turnScreenOn="true">
    <intent-filter>
        <action android:name="android.intent.action.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

這個宣告可讓使用者將筆記角色指派給您的應用程式,使其成為預設的筆記應用程式:

應用程式功能

大螢幕具有差異化優勢的應用程式,能夠與記事應用程式完美搭配。

觸控筆支援

使用設為 trueEXTRA_USE_STYLUS_MODE 意圖額外項目叫用應用程式時,應用程式應開啟附註,接受以觸控筆 (或手指觸控) 輸入的內容。

如果意圖 Extra 設為 false,應用程式應開啟接受鍵盤輸入的附註。

螢幕鎖定存取權

應用程式必須提供全螢幕活動,以便在透過裝置螢幕鎖定畫面開啟應用程式時執行。

只有在使用者已同意 (處於解鎖的裝置狀態) 以顯示過往附註的情況下,應用程式才應顯示歷史附註。否則,當您從螢幕鎖定畫面開啟時,應用程式一律會建立新記事。

您可以使用 KeyguardManager#isKeyguardLocked(),檢查應用程式是否已從螢幕鎖定畫面啟動。 如要要求使用者驗證及解鎖裝置,請呼叫 KeyguardManager#requestDismissKeyguard()

Kotlin

val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager

keyguardManager.requestDismissKeyguard(
    this,
    object : KeyguardDismissCallback() {

    override fun onDismissError() {
        // Unlock failed. Dismissing keyguard is not feasible.
    }

    override fun onDismissSucceeded() {
        // Unlock succeeded. Device is now unlocked.
    }

    override fun onDismissCancelled() {
        // Unlock failed. User cancelled operation or request otherwise cancelled.
    }
})

Java

KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);

boolean isLocked = keyguardManager.isKeyguardLocked();

keyguardManager.requestDismissKeyguard(
    this,
    new KeyguardManager.KeyguardDismissCallback() {

  @Override
  public void onDismissError() {
      // Unlock failed. Dismissing keyguard is not feasible.
  }

  @Override
  public void onDismissSucceeded() {
      // Unlock succeeded. Device is now unlocked.
  }

  @Override
  public void onDismissCancelled() {
      // Unlock failed. User cancelled operation or request otherwise cancelled.
  }
});

浮動式視窗

針對上下文的筆記,您的應用程式必須提供當其他應用程式執行時,在浮動視窗中開啟的活動。

您的應用程式應支援 multi-instance 模式,如此一來,即使筆記應用程式以全螢幕或分割畫面模式啟動,使用者也能在多個浮動視窗中建立多則記事。

內容擷取

內容擷取是筆記應用程式的重要功能。透過內容擷取功能,使用者可以擷取筆記應用程式浮動視窗背後的螢幕螢幕截圖。使用者可以拍攝完整或部分螢幕畫面,將內容貼到記事中,以及標註或醒目顯示擷取的內容。

筆記應用程式應提供 UI 預設用途,以便啟動 registerForActivityResult() 建立的 ActivityResultLauncher。系統會直接或透過 ActivityResultContractACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE 意圖動作提供給啟動器。

系統活動會擷取內容並儲存在裝置上,然後在 registerForActivityResult() 的回呼引數中將內容 URI 傳回應用程式。

以下範例使用一般的 StartActivityForResult 合約:

Kotlin

private val startForResult = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()) {
        result: ActivityResult ->
            if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
                val uri = result.data?.data
                // Use the URI to paste the captured content into the note.
            }
    }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        NotesTheme {
            Surface(color = MaterialTheme.colorScheme.background) {
                CaptureButton(
                    onClick = {
                        Log.i("ContentCapture", "Launching intent...")
                        startForResult.launch(Intent(ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE))
                    })
            }
        }
    }
}

@Composable
fun CaptureButton(onClick: () -> Unit) {
    Button(onClick = onClick)
    {Text("Capture Content")}
}

Java

private final ActivityResultLauncher<Intent> startForResult = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
            Uri uri = result.getData() != null ? result.getData().getData() : null;
            // Use the URI to paste the captured content into the note.
        }
    });

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button captureButton = findViewById(R.id.capture_button);

    captureButton.setOnClickListener(
        view -> {
            Log.i("ContentCapture", "Launching intent...");
            startForResult.launch(new Intent(ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE));
        });
}

應用程式應處理所有結果代碼:

內容擷取成功後,請將擷取的圖片貼到記事,例如:

Kotlin

registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    result: ActivityResult ->
        if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
            val uri = result.data?data
            // Use the URI to paste the captured content into the note.
        }
}

Java

registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
            Uri uri = result.getData() != null ? result.getData().getData() : null;
            // Use the URI to paste the captured content into the note.
        }
    });

只有筆記應用程式是在浮動視窗中執行 (而非透過裝置螢幕鎖定畫面啟動),才應透過 UI 預設用途顯示內容擷取功能。(使用者可以針對筆記應用程式本身擷取螢幕截圖,前提是應用程式必須支援裝置螢幕截圖功能)。

如要判斷應用程式是否位於浮動視窗 (或對話框中),請呼叫以下方法:

  • isLaunchedFromBubble(),確認記事應用程式並未在裝置螢幕鎖定畫面中以全螢幕模式啟動
  • isRoleHeld(RoleManager.ROLE_NOTES) 可驗證應用程式是否為預設的筆記應用程式 (如果應用程式不具備筆記角色,應用程式可在對話或其他類型的對話框中執行)

其他資源