Di chuyển ứng dụng người gửi CCL sang Khung ứng dụng truyền (CAF)

Quy trình sau đây cho phép bạn chuyển đổi ứng dụng dành cho người gửi Android từ Truyền SDK phiên bản 2 có CCL sang CAF. Tất cả chức năng của CCL đều được được triển khai trong CAF, nên sau khi di chuyển, bạn sẽ không cần sử dụng CCL nữa.

SDK gửi CAF của Cast sử dụng CastContext để quản lý GoogleAPIClient thay cho bạn. CastContext quản lý vòng đời, lỗi và lệnh gọi lại cho bạn, giúp bạn đơn giản hoá việc phát triển ứng dụng Truyền.

Giới thiệu

  • Do thiết kế CAF Sender chịu ảnh hưởng của Thư viện đồng hành Cast, Việc di chuyển từ CCL sang CAF Sender chủ yếu liên quan đến các lớp và phương thức của các lớp đó.
  • CAF Sender vẫn được phân phối như một phần của Dịch vụ Google Play bằng trình quản lý SDK Android.
  • Các gói mới (com.google.android.gms.cast.framework.*) đã được thêm vào CAF Sender, có chức năng tương tự như CCL, đảm nhận chịu trách nhiệm tuân thủ Danh sách kiểm tra Thiết kế Google Cast.
  • CAF Sender cung cấp các tiện ích tuân thủ các yêu cầu về Cast UX; các tiện ích này tương tự như các tiện ích do CCL cung cấp.
  • Trình gửi CAF cung cấp lệnh gọi lại không đồng bộ tương tự như CCL để theo dõi trạng thái và lấy dữ liệu. Không giống như CCL, CAF Sender không cung cấp bất kỳ hoạt động nào triển khai nhiều phương thức giao diện.

Trong các phần sau, chúng ta sẽ chủ yếu tập trung vào chủ đề video tập trung vào dựa trên VideoCastManager của CCL, nhưng trong nhiều trường hợp, cũng giống nhau các khái niệm này cũng áp dụng cho DataCastManager.

Phần phụ thuộc

CCL và CAF có cùng phần phụ thuộc trong thư viện hỗ trợ AppCompat, Thư viện hỗ trợ MediaRouter phiên bản 7 và Dịch vụ Google Play. Tuy nhiên, sự khác biệt là CAF phụ thuộc vào khung Truyền mới có sẵn trong Google Play các dịch vụ 9.2.0 trở lên.

Trong tệp build.gradle của bạn, hãy xoá các phần phụ thuộc trên com.google.android.gms:play-services-castcom.google.android.libraries.cast.companionlibrary:ccl, sau đó thêm khung Truyền mới:

dependencies {
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:mediarouter-v7:23.4.0'
    compile 'com.google.android.gms:play-services-cast-framework:9.4.0'
}

Bạn cũng có thể xoá siêu dữ liệu của Dịch vụ Google Play:

<meta‐data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>

Mọi dịch vụ, hoạt động và tài nguyên thuộc CAF sẽ tự động được hợp nhất với tệp kê khai và tài nguyên của ứng dụng.

Phiên bản SDK Android tối thiểu mà CAF hỗ trợ là 9 (Gingerbread); Phiên bản SDK Android tối thiểu của CCL là 10.

CCL cung cấp một phương thức thuận tiện, BaseCastManager.checkGooglePlayServices(activity), để xác minh rằng một ứng dụng phiên bản của Dịch vụ Google Play có sẵn trên thiết bị. CAF không hãy cung cấp dữ liệu này dưới dạng một phần của SDK truyền. Làm theo quy trình Đảm bảo thiết bị có APK Dịch vụ Google Play để đảm bảo rằng APK Dịch vụ Google Play được cài đặt trên vì bản cập nhật có thể không đến ngay tất cả người dùng.

Bạn vẫn bắt buộc phải sử dụng một biến thể của Chủ đề.AppCompat cho chủ đề.

Khởi chạy

Đối với CCL, VideoCastManager.initialize() cần phải được gọi trong Phương thức onCreate() của thực thể Ứng dụng. Logic này phải là đã xoá khỏi mã Lớp ứng dụng của bạn.

Trong CAF, bạn cũng cần phải thực hiện một bước khởi chạy rõ ràng cho dữ liệu Truyền khung. Quá trình này bao gồm việc khởi tạo singleton CastContext, sử dụng một OptionsProvider thích hợp để chỉ định ID ứng dụng của dịch vụ nhận và các tuỳ chọn chung khác. CastContext có vai trò tương tự như CCL VideoCastManager bằng cách cung cấp một singleton mà khách hàng tương tác. OptionsProvider tương tự như CastConfiguration của CCL để cho phép bạn để định cấu hình các tính năng của khung Truyền.

Nếu CastConfiguration.Builder CCL hiện tại của bạn có dạng như sau:

VideoCastManager.initialize(
   getApplicationContext(),
   new CastConfiguration.Builder(context.getString(R.string.app_id))
       .enableWifiReconnection()
       .enableAutoReconnect()
       .build());

Sau đó, trong CAF, CastOptionsProvider sau đây sử dụng CastOptions.Builder sẽ tương tự:

public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(
            Context context) {
        return null;
    }
}

Hãy xem ứng dụng mẫu của chúng tôi để triển khai hoàn chỉnh OptionsProvider.

Khai báo OptionsProvider trong "application" (ứng dụng) của phần tử Tệp AndroidManifest.xml:

<application>
...
    <meta-data
        android:name=
          "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.google.sample.cast.refplayer.CastOptionsProvider"    
    />
</application>

Khởi chạy từng phần CastContext trong mỗi phương thức onCreate của Activity (chứ không phải thực thể Application):

private CastContext mCastContext;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.video_browser);
    setupActionBar();

    mCastContext = CastContext.getSharedInstance(this);
}

Để truy cập vào singleton CastContext, hãy sử dụng:

mCastContext = CastContext.getSharedInstance(this);

Khám phá thiết bị

VideoCastManager incrementUiCounterdecrementUiCounter của CCL phải sẽ bị xoá khỏi phương thức onResumeonPause của Activities.

Trong CAF, quá trình khám phá được bắt đầu và dừng tự động bằng khi ứng dụng chạy trên nền trước và chuyển sang chạy ở chế độ nền, .

Nút Truyền và hộp thoại Truyền

Cũng giống như CCL, các thành phần này được cung cấp bởi khả năng hỗ trợ MediaRouter v7 thư viện của bạn.

Nút Truyền vẫn được MediaRouteButton triển khai và có thể được thêm vào vào hoạt động của bạn (sử dụng ActionBar hoặc Toolbar) dưới dạng một mục trong trình đơn trong trình đơn của mình.

Khai báo MediaRouteActionProvider trong xml của trình đơn cũng giống như với CCL:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

Tương tự như CCL, hãy ghi đè phương thức onCreateOptionMenu() của từng Activity, nhưng thay vì sử dụng CastManager.addMediaRouterButton, hãy sử dụng CastButtonFactory của CAF để kết nối MediaRouteButton với khung Truyền:

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
                                                menu,
                                                R.id.media_route_menu_item);
    return true;
}

Điều khiển thiết bị

Tương tự như CCL, trong CAF, việc kiểm soát thiết bị phần lớn do khung xử lý. Ứng dụng của người gửi không cần xử lý (và không nên cố gắng xử lý) kết nối với thiết bị và khởi chạy ứng dụng nhận bằng GoogleApiClient.

Hoạt động tương tác giữa người gửi và người nhận giờ được biểu thị dưới dạng một "phiên". Chiến lược phát hành đĩa đơn Lớp SessionManager xử lý vòng đời phiên và tự động bắt đầu và dừng phiên đó theo cử chỉ của người dùng: một phiên được bắt đầu khi người dùng chọn một thiết bị Truyền trong hộp thoại Truyền và được kết thúc khi người dùng nhấn "Dừng truyền" trong hộp thoại Truyền hoặc khi chính ứng dụng gửi chấm dứt.

Trong CCL, bạn phải mở rộng lớp VideoCastConsumerImpl để theo dõi quá trình truyền trạng thái phiên:

private final VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {
  public void onApplicationConnected(ApplicationMetadata appMetadata, 
                                     String sessionId,
                                     boolean wasLaunched) {}
  public void onDisconnectionReason(int reason) {}
  public void onDisconnected() {}
}

Trong CAF, ứng dụng của người gửi có thể được thông báo về các sự kiện trong vòng đời của phiên bằng cách đăng ký SessionManagerListener bằng SessionManager. Chiến lược phát hành đĩa đơn Lệnh gọi lại SessionManagerListener xác định phương thức gọi lại cho tất cả các phiên các sự kiện trong vòng đời.

Các phương thức SessionManagerListener sau đây được liên kết từ các CCL Giao diện VideoCastConsumer:

  • VideoCastConsumer.onApplicationConnected -> SessionManagerListener.onSessionStarted
  • VideoCastConsumer.onDisconnected -> SessionManagerListener.onSessionEnded

Khai báo một lớp giúp triển khai giao diện SessionManagerListener và di chuyển logic VideoCastConsumerImpl cho các phương thức so khớp:

private class CastSessionManagerListener implements SessionManagerListener<CastSession> {
  public void onSessionEnded(CastSession session, int error) {}
  public void onSessionStarted(CastSession session, String sessionId) {}
  public void onSessionEnding(CastSession session) {}
  ...
}

Lớp CastSession biểu thị một phiên có Thiết bị truyền. Lớp có để kiểm soát âm lượng thiết bị và trạng thái tắt tiếng mà CCL thực hiện trong BaseCastManager.

Thay vì sử dụng VideoCastManager CCL để thêm người tiêu dùng:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Bây giờ, hãy đăng ký SessionManagerListener của bạn:

mCastSessionManager = 
    CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
                  CastSession.class);

Cách dừng nghe sự kiện trong CCL:

VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);

Bây giờ, hãy sử dụng SessionManager để dừng nghe các sự kiện trong phiên:

mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
                    CastSession.class);

Để ngắt kết nối một cách rõ ràng khỏi Thiết bị truyền, CCL đã sử dụng:

VideoCastManager.disconnectDevice(boolean stopAppOnExit, 
            boolean clearPersistedConnectionData,
            boolean setDefaultRoute)

Đối với CAF, hãy sử dụng SessionManager:

CastContext.getSharedInstance(this).getSessionManager()
                                   .endCurrentSession(true);

Để xác định xem người gửi có được kết nối với người nhận hay không, CCL sẽ cung cấp VideoCastManager.getInstance().isConnected(), nhưng trong CAF, hãy sử dụng SessionManager:

public boolean isConnected() {
    CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                  .getSessionManager()
                                  .getCurrentCastSession();
    return (castSession != null && castSession.isConnected());
}

Trong CAF, thông báo về việc thay đổi trạng thái âm lượng/tắt tiếng vẫn được gửi qua lệnh gọi lại các phương thức trong Cast.Listener; Những trình nghe này được đăng ký bằng CastSession Tất cả thông báo về trạng thái thiết bị còn lại đều được gửi qua Các lệnh gọi lại CastStateListener; Những trình nghe này được đăng ký bằng CastSession Đảm bảo bạn vẫn huỷ đăng ký trình nghe khi các mảnh, hoạt động hoặc ứng dụng sẽ được đưa vào nền.

Logic kết nối lại

CAF cố gắng thiết lập lại kết nối mạng bị mất do đến tình trạng mất tín hiệu Wi-Fi tạm thời hoặc các lỗi mạng khác. Việc này hiện được thực hiện tại cấp phiên hoạt động; một phiên có thể chuyển sang trạng thái "bị tạm ngưng" trạng thái khi kết nối là bị mất và sẽ chuyển về trạng thái "đã kết nối" trạng thái khi kết nối là đã khôi phục. Khung này sẽ đảm nhận việc kết nối lại với ứng dụng nhận rồi kết nối lại mọi kênh Truyền trong quá trình này.

CAF cung cấp dịch vụ kết nối lại riêng để bạn có thể xoá ReconnectionService CCL trong tệp kê khai của bạn:

<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>

Bạn cũng không cần các quyền sau đây trong tệp kê khai đối với logic kết nối lại:

<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Dịch vụ kết nối lại CAF được bật theo mặc định nhưng có thể bị tắt bằng cách sử dụng CastOptions.

Ngoài ra, CAF cũng thêm quá trình tự động tiếp tục phiên, được bật bằng cách mặc định (và có thể huỷ kích hoạt được qua CastOptions). Nếu ứng dụng của người gửi là được gửi ở chế độ nền hoặc bị chấm dứt (bằng cách vuốt sang bên hoặc do xảy ra sự cố) khi một phiên Truyền đang diễn ra, khung sẽ cố gắng tiếp tục phiên đó phiên hoạt động khi ứng dụng của người gửi quay lại nền trước hoặc được chạy lại; việc này sẽ do SessionManager xử lý tự động, sẽ đưa ra các lệnh gọi lại thích hợp trên mọi thực thể SessionManagerListener đã đăng ký.

Đăng ký kênh tuỳ chỉnh

CCL cung cấp hai cách để tạo kênh thông báo tuỳ chỉnh cho người nhận:

  • CastConfiguration cho phép bạn chỉ định nhiều không gian tên và CCL sẽ thì hãy tạo kênh cho bạn.
  • DataCastManager tương tự như VideoCastManager nhưng tập trung vào nội dung không phải nội dung nghe nhìn các trường hợp sử dụng.

CAF không hỗ trợ cả hai cách này để tạo kênh tuỳ chỉnh - bạn phải thực hiện theo quy trình Thêm kênh tuỳ chỉnh cho ứng dụng của người gửi.

Tương tự như CCL, đối với ứng dụng đa phương tiện, không cần thiết phải thể hiện rõ ràng hãy đăng ký kênh điều khiển nội dung đa phương tiện.

Điều khiển phương tiện

Trong CAF, lớp RemoteMediaClient tương đương với VideoCastManager phương tiện truyền thông. RemoteMediaClient.Listener tương đương với VideoCastConsumer. Cụ thể, onRemoteMediaPlayerMetadataUpdatedonRemoteMediaPlayerStatusUpdated phương thức của VideoCastConsumer ánh xạ tới onMetadataUpdatedonStatusUpdated của RemoteMediaClient.Listener tương ứng:

private class CastMediaClientListener implements RemoteMediaClient.Listener {

    @Override
    public void onMetadataUpdated() {
        setMetadataFromRemote();
    }

    @Override
    public void onStatusUpdated() {
        updatePlaybackState();
    }

    @Override
    public void onSendingRemoteMediaRequest() {
    }

    @Override
    public void onQueueStatusUpdated() {
    }

    @Override
    public void onPreloadStatusUpdated() {
    }
}

Bạn không cần khởi chạy hoặc đăng ký RemoteMediaClient một cách rõ ràng object; khung này sẽ tự động tạo thực thể cho đối tượng và đăng ký kênh truyền thông cơ bản tại thời điểm bắt đầu phiên nếu ứng dụng receiver đang kết nối để hỗ trợ không gian tên đa phương tiện.

Bạn có thể truy cập RemoteMediaClient dưới dạng phương thức getRemoteMediaClient của đối tượng CastSession.

CastSession castSession = CastContext.getSharedInstance(mAppContext)
                                     .getSessionManager()
                                     .getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();

Thay vì CCL:

VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);

Bây giờ, hãy sử dụng CAF:

mRemoteMediaClient.addListener(mRemoteMediaClientListener);

Có thể đăng ký số lượng trình nghe bất kỳ bằng RemoteMediaClient, cho phép nhiều thành phần người gửi dùng chung một phiên bản của RemoteMediaClient được liên kết với phiên hoạt động.

VideoCastManager của CCL cung cấp các phương thức để xử lý việc phát nội dung đa phương tiện:

VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
    manager.pause();
    mCurrentPosition = (int) manager.getCurrentMediaPosition();
}

Các thao tác này hiện được RemoteMediaClient triển khai trong CAF:

if (mRemoteMediaClient.hasMediaSession()) {
    mRemoteMediaClient.pause();
    mCurrentPosition = 
        (int)mRemoteMediaClient.getApproximateStreamPosition();
}

Trong CAF, tất cả yêu cầu nội dung nghe nhìn được đưa ra trên RemoteMediaClient sẽ trả về một giá trị RemoteMediaClient.MediaChannelResult qua lệnh gọi lại PendingResult để theo dõi tiến trình và kết quả cuối cùng của yêu cầu.

Cả CCL và CAF đều sử dụng các lớp MediaInfoMediaMetadata để biểu thị mục nội dung nghe nhìn và tải nội dung nghe nhìn.

Để tải nội dung nghe nhìn trong CCL, VideoCastManager được sử dụng:

VideoCastManager.getInstance().loadMedia(media, autoPlay, mCurrentPosition, customData);

Trong CAF, RemoteMediaClient được dùng để tải nội dung nghe nhìn:

mRemoteMediaClient.load(media, autoPlay, mCurrentPosition, customData);

Để nhận thông tin và trạng thái Media của phiên phát nội dung nghe nhìn hiện tại trên bộ thu, CCL sử dụng VideoCastManager:

MediaInfo mediaInfo = VideoCastManager.getInstance()
                                      .getRemoteMediaInformation();
int status = VideoCastManager.getInstance().getPlaybackStatus();
int idleReason = VideoCastManager.getInstance().getIdleReason();

Trong CAF, hãy dùng RemoteMediaClient để nhận thông tin tương tự:

MediaInfo mediaInfo = mRemoteMediaClient.getMediaInfo();
int status = mRemoteMediaClient.getPlayerState();
int idleReason = mRemoteMediaClient.getIdleReason();

Lớp phủ giới thiệu

Tương tự như CCL, CAF cung cấp khung hiển thị tuỳ chỉnh IntroductoryOverlay để làm nổi bật nút Truyền khi hiển thị lần đầu với người dùng.

Thay vì sử dụng phương thức VideoCastConsumer onCastAvailabilityChanged của CCL biết thời điểm hiện lớp phủ, hãy khai báo CastStateListener để xác định khi nút Truyền hiển thị sau khi phát hiện thấy Thiết bị truyền trên mạng cục bộ qua MediaRouter:

private IntroductoryOverlay mIntroductoryOverlay;
private MenuItem mMediaRouteMenuItem;

protected void onCreate(Bundle savedInstanceState) {
    ...
    mCastStateListener = new CastStateListener() {
        @Override
        public void onCastStateChanged(int newState) {
            if (newState != CastState.NO_DEVICES_AVAILABLE) {
                showIntroductoryOverlay();
            }
        }
    };
    mCastContext = CastContext.getSharedInstance(this);
    mCastContext.registerLifecycleCallbacksBeforeIceCreamSandwich(this, 
        savedInstanceState);
}

protected void onResume() {
    mCastContext.addCastStateListener(mCastStateListener);
    ...
}

protected void onPause() {
    mCastContext.removeCastStateListener(mCastStateListener);
    ...
}

Theo dõi thực thể MediaRouteMenuItem:

public boolean onCreateOptionsMenu(Menu menu) {
   super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    mMediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(
            getApplicationContext(), menu,
            R.id.media_route_menu_item);
    showIntroductoryOverlay();
    return true;
}

Kiểm tra xem MediaRouteButton có xuất hiện để lớp phủ giới thiệu hay không có thể hiển thị:

private void showIntroductoryOverlay() {
    if (mIntroductoryOverlay != null) {
        mIntroductoryOverlay.remove();
    }
    if ((mMediaRouteMenuItem != null) && mMediaRouteMenuItem.isVisible()) {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                mIntroductoryOverlay = new IntroductoryOverlay.Builder(
                        VideoBrowserActivity.this, mMediaRouteMenuItem)
                        .setTitleText(getString(R.string.introducing_cast))
                        .setOverlayColor(R.color.primary)
                        .setSingleTime()
                        .setOnOverlayDismissedListener(
                                new IntroductoryOverlay
                                    .OnOverlayDismissedListener() {
                                        @Override
                                        public void onOverlayDismissed() {
                                            mIntroductoryOverlay = null;
                                        }
                                })
                        .build();
                mIntroductoryOverlay.show();
            }
        });
    }
}

Hãy xem ứng dụng mẫu để biết mã hoàn chỉnh hoạt động để hiện lớp phủ giới thiệu.

Để tuỳ chỉnh kiểu của lớp phủ giới thiệu, hãy làm theo quy trình Tuỳ chỉnh lớp phủ giới thiệu.

Tay điều khiển mini

Thay vì MiniController của CCL, hãy sử dụng MiniControllerFragment của CAF trong tệp bố cục ứng dụng của các hoạt động mà bạn muốn hiển thị hình thu nhỏ bộ điều khiển:

<fragment
        android:id="@+id/cast_mini_controller"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:castShowImageThumbnail="true"
        android:visibility="gone"
        class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment" />

CAF không hỗ trợ cấu hình thủ công mà MiniController của CCL hỗ trợ và cũng không hỗ trợ tính năng Autoplay.

Để tuỳ chỉnh kiểu và các nút trên tay điều khiển mini, hãy làm theo quy trình Tuỳ chỉnh Tay điều khiển thu nhỏ.

Thông báo và màn hình khoá

Tương tự như VideoCastNotificationService của CCL, CAF cung cấp MediaNotificationService để quản lý chế độ hiển thị thông báo về nội dung nghe nhìn khi truyền.

Bạn cần xoá các nội dung sau khỏi tệp kê khai:

  • VideoIntentReceiver
  • VideoCastNotificationService

CCL hỗ trợ cung cấp dịch vụ thông báo tuỳ chỉnh với CastConfiguration.Builder; không được CAF hỗ trợ.

Hãy cân nhắc việc khởi chạy CastManager sau đây bằng CCL:

VideoCastManager.initialize(
   getApplicationContext(),
   new CastConfiguration.Builder(
           context.getString(R.string.app_id))
       .addNotificationAction(
           CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE,true)
       .addNotificationAction(
           CastConfiguration.NOTIFICATION_ACTION_DISCONNECT,true)
       .build());

Đối với cấu hình tương đương trong CAF, SDK sẽ cung cấp NotificationsOptions.Builder để giúp bạn tạo các chế độ kiểm soát nội dung nghe nhìn cho và màn hình khoá vào ứng dụng của người gửi. Thông báo và khoá bạn có thể bật các chế độ điều khiển màn hình bằng CastOptions khi khởi chạy CastContext.

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = 
        new NotificationOptions.Builder()
            .setActions(Arrays.asList(
                MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
                MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{0, 1})
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
             .setNotificationOptions(notificationOptions)
             .build();
    return new CastOptions.Builder()
             .setReceiverApplicationId(context.getString(R.string.app_id))
             .setCastMediaOptions(mediaOptions)
             .build();
}

Các thông báo và chế độ kiểm soát màn hình khoá luôn bật trong CAF. Ngoài ra, xin lưu ý rằng các nút phát/tạm dừng và dừng truyền được cung cấp theo mặc định. CAF sẽ tự động theo dõi chế độ hiển thị của Hoạt động để đưa ra quyết định thời điểm hiển thị thông báo về nội dung nghe nhìn, ngoại trừ Gingerbread. (Đối với Bánh gừng, hãy xem ghi chú trước đó trên sử dụng registerLifecycleCallbacksBeforeIceCreamSandwich(); CCL VideoCastManager cuộc gọi incrementUiCounterdecrementUiCounter cần được loại bỏ.)

Để tuỳ chỉnh các nút hiển thị trong thông báo, hãy làm theo quy trình Thêm chế độ điều khiển nội dung nghe nhìn vào thông báo và màn hình khoá.

Đã mở rộng bộ điều khiển

CCL cung cấp VideoCastControllerActivityVideoCastControllerFragment để hiển thị bộ điều khiển mở rộng khi truyền nội dung đa phương tiện.

Bạn có thể xoá nội dung khai báo VideoCastControllerActivity trong tệp kê khai.

Trong CAF, bạn phải mở rộng ExpandControllerActivity và thêm nút Truyền.

Để tuỳ chỉnh kiểu và nút hiển thị trong màn hình mở rộng đơn vị kiểm soát, làm theo quy trình Tuỳ chỉnh Bộ điều khiển mở rộng.

Tập trung âm thanh

Giống như CCL, quyền phát âm thanh được quản lý tự động.

Điều chỉnh âm lượng

Đối với Gingerbread, dispatchKeyEvent là bắt buộc như với CCL. Trong ICS trở lên đối với cả CCL và CAF điều khiển âm lượng đều được xử lý tự động.

CAF cho phép kiểm soát âm lượng truyền thông qua nút âm lượng cứng trên điện thoại bên trong các hoạt động ứng dụng của bạn và cũng hiển thị thanh âm lượng trực quan khi truyền trên các phiên bản được hỗ trợ. CAF cũng xử lý thay đổi về khối lượng thông qua âm lượng cố định ngay cả khi ứng dụng của bạn không ở phía trước, bị khoá hoặc ngay cả khi màn hình đang bật tắt.

Phụ đề

Trên Android KitKat trở lên, bạn có thể tuỳ chỉnh phụ đề thông qua tính năng Phụ đề Cài đặt > Cài đặt > Hỗ trợ tiếp cận. Các phiên bản Android cũ hơn, tuy nhiên, không có tính năng này. CCL xử lý vấn đề này bằng cách cung cấp các tuỳ chỉnh các chế độ cài đặt cho các phiên bản cũ và uỷ quyền cho chế độ cài đặt hệ thống trên KitKat trở lên.

CAF không cung cấp chế độ cài đặt tuỳ chỉnh để thay đổi lựa chọn ưu tiên về phụ đề. Bạn nên xoá các tham chiếu CaptionsPreferenceActivity trong tệp kê khai của bạn và XML tuỳ chọn của bạn.

Không còn cần TracksChooserDialog của CCL nữa vì đã thay đổi phụ đề sẽ do giao diện người dùng của trình điều khiển mở rộng xử lý.

API phụ đề chi tiết trong CAF tương tự như phiên bản 2.

Ghi nhật ký gỡ lỗi

CAF không cung cấp chế độ cài đặt ghi nhật ký gỡ lỗi.

Khác

Các tính năng CCL sau đây không được hỗ trợ trong CAF:

  • Yêu cầu uỷ quyền trước khi phát bằng cách cung cấp MediaAuthService
  • Thông báo có thể định cấu hình trên giao diện người dùng

Ứng dụng mẫu

Hãy xem điểm khác biệt về việc di chuyển ứng dụng mẫu Universal Music Player cho Android (uamp) từ CCL sang CAF.

Ngoài ra, chúng tôi còn có các hướng dẫn của lớp học lập trìnhcác ứng dụng mẫu sử dụng CAF.