美文网首页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