Android 程式碼範例
重要
2020 年 3 月之前發行的 Microsoft Rights Management Service SDK 版本已被取代;使用舊版的應用程式必須更新為使用 2020 年 3 月版本。 如需完整詳細資料,請參閱 淘汰通知。
Microsoft Rights Management Service SDK 沒有進一步的增強功能。 我們強烈建議採用Microsoft 資訊保護 SDK來分類、標記和保護服務。
本文示範如何針對 RMS SDK 的 Android 版本撰寫程式碼元素。
注意 本文中的 MSIPC (Microsoft Information Protection and Control) 一詞是指用戶端程序。
使用 Microsoft Rights Management SDK 4.2 - 重要案例
這些程式碼範例是採自較大的範例應用程式,代表對於此 SDK 定位相當重要的開發案例。 它們示範如何使用:
- Microsoft 保護的檔案格式,也稱為「受保護的檔案」。
- 自訂受保護的檔案格式
- 自訂使用者介面 (UI) 控制項
MSIPCSampleApp 範例應用程式可搭配 SDK 用於 Android 作業系統。 若要深入了解,請參閱 rms-sdk-ui-for-android。
案例︰取用 RMS 受保護的檔案
步驟 1︰建立 ProtectedFileInputStream。
來源︰MsipcAuthenticationCallback.java
描述:具現化 ProtectedFileInputStream 物件並實作服務驗證。 將 AuthenticationRequestCallback 的執行個體以參數 mRmsAuthCallback 傳遞至 MSIPC API,以便使用 AuthenticationRequestCallback 來取得權杖。 請參閱下列範例程式碼一節結尾附近的 ProtectedFileInputStream.create 呼叫。
public void startContentConsumptionFromPtxtFileFormat(InputStream inputStream) { CreationCallback<ProtectedFileInputStream> protectedFileInputStreamCreationCallback = new CreationCallback<ProtectedFileInputStream>() { @Override public Context getContext() { … } @Override public void onCancel() { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onSuccess(ProtectedFileInputStream protectedFileInputStream) { … … byte[] dataChunk = new byte[16384]; try { while ((nRead = protectedFileInputStream.read(dataChunk, 0, dataChunk.length)) != -1) { … } … protectedFileInputStream.close(); } catch (IOException e) { … } } }; try { … ProtectedFileInputStream.create(inputStream, null, mRmsAuthCallback, PolicyAcquisitionFlags.NONE, protectedFileInputStreamCreationCallback); } catch (com.microsoft.rightsmanagement.exceptions.InvalidParameterException e) { … } }
步驟 2︰使用 Active Directory Authentication Library (ADAL) 設定驗證。
來源: MsipcAuthenticationCallback.java。
描述︰此步驟使用 ADAL 以範例驗證參數來實作 AuthenticationRequestCallback。 若要深入了解,請參閱 Azure AD Authentication Library (ADAL)。
class MsipcAuthenticationCallback implements AuthenticationRequestCallback { … @Override public void getToken(Map<String, String> authenticationParametersMap, final AuthenticationCompletionCallback authenticationCompletionCallbackToMsipc) { String authority = authenticationParametersMap.get("oauth2.authority"); String resource = authenticationParametersMap.get("oauth2.resource"); String userId = authenticationParametersMap.get("userId"); final String userHint = (userId == null)? "" : userId; AuthenticationContext authenticationContext = App.getInstance().getAuthenticationContext(); if (authenticationContext == null || !authenticationContext.getAuthority().equalsIgnoreCase(authority)) { try { authenticationContext = new AuthenticationContext(App.getInstance().getApplicationContext(), authority, …); App.getInstance().setAuthenticationContext(authenticationContext); } catch (NoSuchAlgorithmException e) { … authenticationCompletionCallbackToMsipc.onFailure(); } catch (NoSuchPaddingException e) { … authenticationCompletionCallbackToMsipc.onFailure(); } } App.getInstance().getAuthenticationContext().acquireToken(mParentActivity, resource, mClientId, mRedirectURI, userId, mPromptBehavior, "&USERNAME=" + userHint, new AuthenticationCallback<AuthenticationResult>() { @Override public void onError(Exception exc) { … if (exc instanceof AuthenticationCancelError) { … authenticationCompletionCallbackToMsipc.onCancel(); } else { … authenticationCompletionCallbackToMsipc.onFailure(); } } @Override public void onSuccess(AuthenticationResult result) { … if (result == null || result.getAccessToken() == null || result.getAccessToken().isEmpty()) { … } else { // request is successful … authenticationCompletionCallbackToMsipc.onSuccess(result.getAccessToken()); } } } ); }
步驟 3︰透過 UserPolicy.accessCheck 方法,檢查此使用者是否存在此內容的編輯權限。
來源︰TextEditorFragment.java
//check if user has edit rights and apply enforcements if (!mUserPolicy.accessCheck(EditableDocumentRights.Edit)) { mTextEditor.setFocusableInTouchMode(false); mTextEditor.setFocusable(false); mTextEditor.setEnabled(false); … }
案例︰使用範本建立新的受保護檔案
此案例一開始會取得範本清單,選取第一個範本以建立原則,然後建立並寫入至新的受保護檔案。
步驟 1︰透過 TemplateDescriptor 物件取得範本清單。
來源︰MsipcTaskFragment.java
CreationCallback<List<TemplateDescriptor>> getTemplatesCreationCallback = new CreationCallback<List<TemplateDescriptor>>() { @Override public Context getContext() { … } @Override public void onCancel() { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onSuccess(List<TemplateDescriptor> templateDescriptors) { … } }; try { … mIAsyncControl = TemplateDescriptor.getTemplates(emailId, mRmsAuthCallback, getTemplatesCreationCallback); } catch (com.microsoft.rightsmanagement.exceptions.InvalidParameterException e) { … }
步驟 2︰使用清單中的第一個範本來建立 UserPolicy。
來源︰MsipcTaskFragment.java
CreationCallback<UserPolicy> userPolicyCreationCallback = new CreationCallback<UserPolicy>() { @Override public Context getContext() { … } @Override public void onCancel() { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onSuccess(final UserPolicy item) { … } }; try { … mIAsyncControl = UserPolicy.create((TemplateDescriptor)selectedDescriptor, mEmailId, mRmsAuthCallback, UserPolicyCreationFlags.NONE, userPolicyCreationCallback); … } catch (InvalidParameterException e) { … }
步驟 3︰建立 ProtectedFileOutputStream 並寫入內容。
來源︰MsipcTaskFragment.java
private void createPTxt(final byte[] contentToProtect) { … CreationCallback<ProtectedFileOutputStream> protectedFileOutputStreamCreationCallback = new CreationCallback<ProtectedFileOutputStream>() { @Override public Context getContext() { … } @Override public void onCancel() { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onSuccess(ProtectedFileOutputStream protectedFileOutputStream) { try { // write to this stream protectedFileOutputStream.write(contentToProtect); protectedFileOutputStream.flush(); protectedFileOutputStream.close(); … } catch (IOException e) { … } } }; try { File file = new File(filePath); outputStream = new FileOutputStream(file); mIAsyncControl = ProtectedFileOutputStream.create(outputStream, mUserPolicy, originalFileExtension, protectedFileOutputStreamCreationCallback); } catch (FileNotFoundException e) { … } catch (InvalidParameterException e) { … } }
案例︰開啟自訂受保護的檔案
步驟 1︰從 serializedContentPolicy 建立 UserPolicy。
來源︰MsipcTaskFragment.java
CreationCallback<UserPolicy> userPolicyCreationCallbackFromSerializedContentPolicy = new CreationCallback<UserPolicy>() { @Override public void onSuccess(UserPolicy userPolicy) { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onCancel() { … } @Override public Context getContext() { … } }; try { ... // Read the serializedContentPolicyLength from the inputStream. long serializedContentPolicyLength = readUnsignedInt(inputStream); // Read the PL bytes from the input stream using the PL size. byte[] serializedContentPolicy = new byte[(int)serializedContentPolicyLength]; inputStream.read(serializedContentPolicy); ... UserPolicy.acquire(serializedContentPolicy, null, mRmsAuthCallback, PolicyAcquisitionFlags.NONE, userPolicyCreationCallbackFromSerializedContentPolicy); } catch (com.microsoft.rightsmanagement.exceptions.InvalidParameterException e) { ... } catch (IOException e) { ... }
步驟 2︰使用步驟 1 的 UserPolicy 建立 CustomProtectedInputStream。
來源︰MsipcTaskFragment.java
CreationCallback<CustomProtectedInputStream> customProtectedInputStreamCreationCallback = new CreationCallback<CustomProtectedInputStream>() { @Override public Context getContext() { … } @Override public void onCancel() { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onSuccess(CustomProtectedInputStream customProtectedInputStream) { … byte[] dataChunk = new byte[16384]; try { while ((nRead = customProtectedInputStream.read(dataChunk, 0, dataChunk.length)) != -1) { … } … customProtectedInputStream.close(); } catch (IOException e) { … } … } }; try { ... // Retrieve the encrypted content size. long encryptedContentLength = readUnsignedInt(inputStream); updateTaskStatus(new TaskStatus(TaskState.Starting, "Consuming content", true)); CustomProtectedInputStream.create(userPolicy, inputStream, encryptedContentLength, customProtectedInputStreamCreationCallback); } catch (com.microsoft.rightsmanagement.exceptions.InvalidParameterException e) { ... } catch (IOException e) { ... }
步驟 3︰從 CustomProtectedInputStream 讀取內容到 mDecryptedContent,然後關閉。
來源︰MsipcTaskFragment.java
@Override public void onSuccess(CustomProtectedInputStream customProtectedInputStream) { mUserPolicy = customProtectedInputStream.getUserPolicy(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] dataChunk = new byte[16384]; try { while ((nRead = customProtectedInputStream.read(dataChunk, 0, dataChunk.length)) != -1) { buffer.write(dataChunk, 0, nRead); } buffer.flush(); mDecryptedContent = new String(buffer.toByteArray(), Charset.forName("UTF-8")); buffer.close(); customProtectedInputStream.close(); } catch (IOException e) { ... } }
案例︰使用自訂原則來建立自訂受保護的檔案
步驟 1︰使用使用者所提供的電子郵件地址來建立原則描述元。
來源︰MsipcTaskFragment.java
描述︰實際上會使用裝置介面的使用者輸入來建立下列物件:UserRights 和 PolicyDescriptor。
// create userRights list UserRights userRights = new UserRights(Arrays.asList("consumer@domain.com"), Arrays.asList( CommonRights.View, EditableDocumentRights.Print)); ArrayList<UserRights> usersRigthsList = new ArrayList<UserRights>(); usersRigthsList.add(userRights); // Create PolicyDescriptor using userRights list PolicyDescriptor policyDescriptor = PolicyDescriptor.createPolicyDescriptorFromUserRights( usersRigthsList); policyDescriptor.setOfflineCacheLifetimeInDays(10); policyDescriptor.setContentValidUntil(new Date());
步驟 2︰從原則描述元 selectedDescriptor 建立自訂 UserPolicy。
來源︰MsipcTaskFragment.java
mIAsyncControl = UserPolicy.create((PolicyDescriptor)selectedDescriptor, mEmailId, mRmsAuthCallback, UserPolicyCreationFlags.NONE, userPolicyCreationCallback);
步驟 3︰建立內容並將其寫入到 CustomProtectedOutputStream,然後關閉。
來源︰MsipcTaskFragment.java
File file = new File(filePath); final OutputStream outputStream = new FileOutputStream(file); CreationCallback<CustomProtectedOutputStream> customProtectedOutputStreamCreationCallback = new CreationCallback<CustomProtectedOutputStream>() { @Override public Context getContext() { … } @Override public void onCancel() { … } @Override public void onFailure(ProtectionException e) { … } @Override public void onSuccess(CustomProtectedOutputStream protectedOutputStream) { try { // write serializedContentPolicy byte[] serializedContentPolicy = mUserPolicy.getSerializedContentPolicy(); writeLongAsUnsignedIntToStream(outputStream, serializedContentPolicy.length); outputStream.write(serializedContentPolicy); // write encrypted content if (contentToProtect != null) { writeLongAsUnsignedIntToStream(outputStream, CustomProtectedOutputStream.getEncryptedContentLength(contentToProtect.length, protectedOutputStream.getUserPolicy())); protectedOutputStream.write(contentToProtect); protectedOutputStream.flush(); protectedOutputStream.close(); } else { outputStream.flush(); outputStream.close(); } … } catch (IOException e) { … } } }; try { mIAsyncControl = CustomProtectedOutputStream.create(outputStream, mUserPolicy, customProtectedOutputStreamCreationCallback); } catch (InvalidParameterException e) { … }