美文网首页Android
使用Intent启动Activity

使用Intent启动Activity

作者: JaedenKil | 来源:发表于2017-12-27 17:05 被阅读24次

这里以Exoplayer 2.5.4为例。
源码里面我们主要关注这两个java文件:

SampleChooserActivity
PlayerActivity

SampleChooserActivity界面我们可以选择流播放,PlayerActivity界面播放流。
然而选择不同的流, 有不同的播放, 但是播放界面都共用一个activity, 是因为每次点击播放的时候会传递不同的参数

public Intent buildIntent(Context context) {
      return super.buildIntent(context)
          .setData(Uri.parse(uri))
          .putExtra(PlayerActivity.EXTENSION_EXTRA, extension)
          .putExtra(PlayerActivity.AD_TAG_URI_EXTRA, adTagUri)
          .setAction(PlayerActivity.ACTION_VIEW);
}

通过这个, SampleChooserActivity可以把流地址, 流后缀, 广告地址等等添加到Intent来传递到PlayerActivity播放界面, 而后PlayerActivity对数据接收。
例如对格式的接收:

public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid"
       if (intent.getExtras().getString(DRM_SCHEME_UUID_EXTRA) != null) {
          switch (intent.getExtras().getString(DRM_SCHEME_UUID_EXTRA)) {
            case "widevine":
              drmSchemeUuid = UUID.fromString(String.valueOf(C.WIDEVINE_UUID));
              break;
            case "playready":
              drmSchemeUuid = UUID.fromString(String.valueOf(C.PLAYREADY_UUID));
              break;
            case "cenc":
              drmSchemeUuid = UUID.fromString(String.valueOf(C.PLAYREADY_UUID));
              break;
            default:
              Log.w(TAG, "Unsupported drm style!!!");
        }

参数的传递, 无论是通过app直接启动下一个activity, 还是通过am start, 都是以键值对来传递的。

public static final String EXTENSION_EXTRA = "extension";

intent.putExtra(PlayerActivity.EXTENSION_EXTRA, extension);
am start -W -a com.google.android.exoplayer.demo.action.VIEW -c android.intent.category.DEFAULT \
...
-e extension "mpd" \
"com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity"

PlayerActivity会对不同的参数进行解析, 实现流的播放。
从源码里面的AndroidManifest看:

<activity android:name="com.google.android.exoplayer2.demo.PlayerActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
        android:launchMode="singleTop"
        android:label="@string/application_name"
        android:theme="@style/PlayerTheme">
      <intent-filter>
        <action android:name="com.google.android.exoplayer.demo.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="http"/>
        <data android:scheme="https"/>
        <data android:scheme="content"/>
        <data android:scheme="asset"/>
        <data android:scheme="file"/>
      </intent-filter>
      <intent-filter>
        <action android:name="com.google.android.exoplayer.demo.action.VIEW_LIST"/>
        <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
    </activity>

PlayerActivity会接受两种不同的intent

<action android:name="com.google.android.exoplayer.demo.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>

 <action android:name="com.google.android.exoplayer.demo.action.VIEW_LIST"/>
<category android:name="android.intent.category.DEFAULT"/>

可以简单的认为,前者是播放单个流的intent, 后者是播放多个混合流的intent。
如果我们以am start在串口敲命令,可以有一下两种情况:

am start -W -a com.google.android.exoplayer.demo.action.VIEW -c android.intent.category.DEFAULT \
-e link "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd" \
-e drm_scheme_uuid "widevine" \
-e drm_license_url "https://proxy.uat.widevine.com/proxy?provider=widevine_test" \
-e extension "mpd" \
"com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity"
am start -W -a com.google.android.exoplayer.demo.action.VIEW_LIST -c android.intent.category.DEFAULT \
--esa link "https://html5demos.com/assets/dizzy.mp4"\,\
"https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"\,\
"https://html5demos.com/assets/dizzy.mp4"\,\
"https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"\,\
"https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd" \
-e drm_scheme_uuid "widevine" \
-e drm_license_url "https://proxy.uat.widevine.com/proxy?provider=widevine_test" \
"com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity"

其中, 在串口输入am有以下提示:

<INTENT> specifications include these flags and arguments:
    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
    [-c <CATEGORY> [-c <CATEGORY>] ...]
    [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
    [--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
        (mutiple extras passed as List<Float>)
    [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
        (mutiple extras passed as String[]; to embed a comma into a string,
         escape it using "\,")
    [--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
        (mutiple extras passed as List<String>; to embed a comma into a string,
         escape it using "\,")
    [<URI> | <PACKAGE> | <COMPONENT>]

其中键值都是以String传入的, 要加上""来识别。
流的相应信息,在此例中,都是保存在media.exolist.json文件中, 例如:

{
        "name": "WV: Secure SD (cbc1,MP4,H264)",
        "uri": "https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1_sd.mpd",
        "drm_scheme": "widevine",
        "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
}

但是局限也很多:

  • 如果我们需要启动的activity不需要传入参数,那很简单,知道activity的名字就行,找源码,或者串口输入
logcat | grep cmp

就可以找到相应的activity.

  • 如果我们需要启动的activity需要传入参数, 那我们就只能从源码入手了。
    此例,代码中我加入了判断:
public static final String STREAM_URL = "link";

if (intent.getExtras().getString(STREAM_URL) != null
            || intent.getStringArrayExtra(STREAM_URL) != null) {
      //Run exoplayer from command line
      Log.i(TAG, "Run exoplayer from command line");
      ...
} else {
      //Run exoplayer from internal app
      Log.i(TAG, "Run exoplayer from internal app");
}

“link”这个键名是串口输入指令时独有的, 在app内部启动这个PlayerActivity不会输入这个参数。
这样的话,安装上此代码编译出的apk,无论是内部启动播放流,还是外部指令播放流,不会有冲突了。

相关文章

网友评论

    本文标题:使用Intent启动Activity

    本文链接:https://www.haomeiwen.com/subject/xvsugxtx.html