离陌lm 2023-04-03 22:38 采纳率: 50%
浏览 23
已结题

关于#android#的问题:我需要开发一个更换头像的功能,需要申请访问相册,跟着up敲了代码,但是我在点击时提示没有权限,去设置里面开权限时发现根本没有相册这一权限

我需要开发一个更换头像的功能,需要申请访问相册,跟着up敲了代码,但是我在点击时提示没有权限,去设置里面开权限时发现根本没有相册这一权限,求问怎么解决

img

img

  • 写回答

3条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-04-07 14:30
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:
    • 你可以看下这个问题的回答https://ask.csdn.net/questions/215331
    • 除此之外, 这篇博客: 视频播放基础控件与无缝技术介绍中的 以无缝转场播放为例 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

         关于Activity等共享元素过渡动画的介绍,谷歌官方文档上已经做了比较详细的介绍,直接看

      共享元素过渡动画

         在 PlayerBase 中,过渡动画实现如下:

      Intent intent = new Intent(this, ShareAnimationActivityB.class);
      intent.putExtra(ShareAnimationActivityB.KEY_DATA, mData);
      if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
          // 过渡动画,mLayoutContainer表示共享元素
          ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
                  this, mLayoutContainer, "videoShare");
          ActivityCompat.startActivity(this, intent, options.toBundle());
      }else{
          startActivity(intent);
      }
      
      public class ShareAnimationActivityB extends AppCompatActivity {
      
          public static final String KEY_DATA = "data_source";
      
          @BindView(R.id.top_container)
          RelativeLayout mTopContainer;
      
          @Override
          protected void onCreate(@Nullable Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_share_animation_b);
              ButterKnife.bind(this);
      
              getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
      
              DataSource dataSource = (DataSource) getIntent().getSerializableExtra(KEY_DATA);
      
              DataSource useData = null;
              DataSource playData = ShareAnimationPlayer.get().getDataSource();
              boolean dataChange = playData!=null && !playData.getData().equals(dataSource.getData());
              if(!ShareAnimationPlayer.get().isInPlaybackState() || dataChange){
                  useData = dataSource;
              }
             //  动画结束后,将播放器绑定到新界面上的viewgroup,实现播放。
              ShareAnimationPlayer.get().play(mTopContainer, useData);
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
              ShareAnimationPlayer.get().destroy();
          }
      }
      
      
      

         看完过渡动画,那是如何保证播放的不中断呢?我们一起来看看。

         以 TextureView 为例。在前面,我们介绍过,TextureView 其内部是通过封装 SurfaceTexture 来实现内容呈现的。下面我们再看看其监听方法。

          private SurfaceTexture mOldSurfaceTexture;
          private TextureView vTextureView;
      
          TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
      
              @Override
              public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
                  // 当TextureView的画面出现时会回调
                  LogUtils.d(TAG, "onSurfaceTextureAvailable" + " width = " + width + " height = " + height);
                  if (mOldSurfaceTexture == null) {
                      mOldSurfaceTexture = surfaceTexture;
                      Surface surface = new Surface(mOldSurfaceTexture);
                      //创建surface并绑定mediaplayer
                      mMediaPlayer.setSurface(surface);
                  } else {
                      vTextureView.setSurfaceTexture(mOldSurfaceTexture);
                      // 开始播放
                      mMediaPlayer.start();
                  }
      
              }
      
              @Override
              public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                  LogUtils.d(TAG, "onSurfaceTextureSizeChanged" + " width = " + width + " height = " + height);
              }
      
              @Override
              public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                  LogUtils.d(TAG, "onSurfaceTextureDestroyed");
                  // 当TextureView的画面丢失时会回调,此时保存原来的画面
                  mOldSurfaceTexture = surface;
                  return false;
              }
      
              @Override
              public void onSurfaceTextureUpdated(SurfaceTexture surface) {
                  // do nothing
              }
          };
      

         根据上面的注释说明,首次绑定 Mediaplayer 时,会将 SurfaceTexture 创建的 Surface 与其绑定,这样就能正常展示播放内容。而在进行转场过渡页面时,播放器会重新绑定到新的父 View 上。此时 SurfaceTexture 会回调 onSurfaceTextureDestroyed 并且把与当前画面绑定的 SurfaceTexture 回调出来,而再重新绑定到父 View 后又会回调 onSurfaceTextureAvailable。

         正是利用这个实现,PlayerBase 将上一个画面的 SurfaceTexture 保存,再下一次 onSurfaceTextureAvailable 时重新设置给了 TextureView, 而此时 Mediaplayer 只是暂停而没有释放,重新启动播放就可以实现无缝衔接播放了。

         总结起来,就是不同的渲染视图使用同一个解码实例即可。可以简单比作一个 MediaPlayer 去不断设置不同的 Surface 呈现播放,但这个过程如果自己实现就比较复杂。PlayerBase 中的 RelationAssist 就是为了简化这个过程而设计的,在不同的页面或视图切换播放时,只需要提供并传入对应位置的视图容器(ViewGroup类型)即可。内部复杂的设置项和关联由 RelationAssist 完成。

    • 您还可以看一下 曾妙根老师的我从程序员到项目经理课程中的 培训期间学习误区与学习方法小节, 巩固相关知识点

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月18日
  • 已采纳回答 4月10日
  • 创建了问题 4月3日

悬赏问题

  • ¥15 关于大棚监测的pcb板设计
  • ¥20 sim800c模块 at指令及平台
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计