小编Cla*_*ssA的帖子

getAdapterPosition() 已弃用

我已将我targetSdkVersion的 28更新到 30,我注意到它getAdapterPosition()已被弃用(我不确定何时发生这种情况)。

文档中,他们说:

此方法已弃用。
当适配器嵌套其他适配器时,此方法会造成混淆。如果您在 Adapter 的上下文中调用它,您可能想要调用getBindingAdapterPosition()或者如果您想要 RecyclerView 看到的位置,您应该调用getAbsoluteAdapterPosition()

该文档还说明了以下内容:

请注意,如果您正在查询 RecyclerView 看到的位置,则应使用getAbsoluteAdapterPosition()(例如,您想使用它来保存滚动状态)。如果您要查询访问 RecyclerView.Adapter 内容的位置,则应使用getBindingAdapterPosition()

我的理解是:

  • getBindingAdapterPosition当您想要获取适配器位置时应该使用它(如果它仍然存在于适配器中)。如果它不再存在于适配器中,它将返回-1( NO_POSITION )。
  • getAbsoluteAdapterPosition应该用于获取位置,如RecyclerView所见。例如,如果某个项目已被删除,但尚未从ViewHolder.

换句话说,如果我的 中有4项目Adapter,我删除位置0和查询,getAbsoluteAdapterPosition并且getBindingAdapterPosition在项目从 中删除之前ViewHolder,然后getAbsoluteAdapterPosition将返回0(因为视图仍在 中ViewHolder)并getBindingAdapterPosition返回-1(因为它不再存在于适配器中)。


我通过记录以下内容测试了差异:

Log.e("difference", "getAdapterPosition = "+myHolder.getAdapterPosition()+" getBindingAdapterPosition = "+myHolder.getBindingAdapterPosition()+" getAbsoluteAdapterPosition = "+myHolder.getAbsoluteAdapterPosition()); …
Run Code Online (Sandbox Code Playgroud)

android android-adapter android-recyclerview

39
推荐指数
1
解决办法
9103
查看次数

MediaCodec - 处理丢帧的视频

这是一个很长的问题,但我必须解释我正在经历的问题才能正确地解决问题.希望我能找到像@fadden@mstorsjo这样的人来看看这个问题.

有关此问题的最新更新,请参阅编辑3.


我目前正在快速精确地寻求使用MediaCodec.我目前要逐帧跳过的是,我首先得到总帧数:

mediaInfo.totalFrames = videoTrack.getSamples().size();
Run Code Online (Sandbox Code Playgroud)

然后我得到视频文件的长度:

mediaInfo.durationUs = videoTrack.getDuration() * 1000 *1000 / timeScale;

//then calling:
public long getDuration() {
    if (mMediaInfo != null) {
        return (int) mMediaInfo.durationUs / 1000; // to millisecond
    }
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我想要获得下一帧时,我会调用以下内容:

mNextFrame.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            int frames = Integer.parseInt(String.valueOf(getTotalFrames));
            int intervals = Integer.parseInt(String.valueOf(mPlayer.getDuration() / frames));

            if (mPlayer.isPlaying()) {
                mPlayer.pause();
                mPlayer.seekTo(mPlayer.getCurrentPosition() + intervals);
            } else {
                mPlayer.seekTo(mPlayer.getCurrentPosition() + intervals);
            }

        }
    }); …
Run Code Online (Sandbox Code Playgroud)

android mediacodec android-mediacodec

17
推荐指数
0
解决办法
554
查看次数

CamcorderProfile.videoCodec返回错误的值

根据docs,您可以CamcorderProfile用来获取设备的默认视频编解码器格式,然后将其设置为MediaRecorder,如下所示:

CamcorderProfile mProfile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_HIGH);

//

mMediaRecorder.setVideoEncoder(mProfile.videoCodec);
Run Code Online (Sandbox Code Playgroud)

但是由于某种原因,它返回了错误的格式。

我正在使用CameraView库,并在FullVideoRecorder类中定义了以下内容:

switch (mResult.getVideoCodec()) {
    case H_263: mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); break;
    case H_264: mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); break;
    case DEVICE_DEFAULT: mMediaRecorder.setVideoEncoder(mProfile.videoCodec); break;
} 
Run Code Online (Sandbox Code Playgroud)

当我将视频编码器设置为时,遇到问题的设备可以很好地工作H_263,但是由于某种原因,当我将其设置为默认时,它会崩溃-在这种情况下,默认意味着CamcorderProfile应选择设备默认的视频编解码器格式。


我的问题:

有什么原因CamcorderProfile.videoCodec会返回错误的值,如何解决?


编辑 -添加更多信息

我实现了以下内容,以确保是否CamcoderProfile返回了错误的值:

//In onCreate
CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);

//getVideoCodec method below
String profileCodec = getVideoCodec(camcorderProfile.videoCodec);    

//Log the result I get
Log.e("Video Codec =", profileCodec);


private String getVideoCodec(int videoCodec){
    switch(videoCodec){
        case MediaRecorder.VideoEncoder.H263:
            return …
Run Code Online (Sandbox Code Playgroud)

java android android-camera android-mediarecorder

11
推荐指数
1
解决办法
278
查看次数

为不同的架构生成APK - FFmpegMediaMetadataRetriever

请看编辑1


我正在忙于将FFmpegMediaMetadataRetriever预构建.aar文件添加到我的项目中以减少每个体系结构的Apk文件大小.

这篇帖子为他增加了以下内容Gradle:

android {
splits {
        // Configures multiple APKs based on ABI.
        abi {
            // Enables building multiple APKs per ABI.
            enable true

            // By default all ABIs are included, so use reset() and include to specify that we only
            // want APKs for x86, armeabi-v7a, and mips.
            reset()

            // Specifies a list of ABIs that Gradle should create APKs for.
            include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"

            // Specifies that we want …
Run Code Online (Sandbox Code Playgroud)

java android apk

9
推荐指数
1
解决办法
1163
查看次数

在SurfaceView上捏缩放

请阅读编辑3 ..

我正试图在a上实现捏缩放SurfaceView.我已经做了很多关于此的研究,我发现这个类实现了捏缩放.这是我如何修改它:

public class ZoomLayout extends FrameLayout implements ScaleGestureDetector.OnScaleGestureListener {

private SurfaceView mSurfaceView;

private enum Mode {
    NONE,
    DRAG,
    ZOOM
}

private static final String TAG = "ZoomLayout";
private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 4.0f;

private Mode mode;
private float scale = 1.0f;
private float lastScaleFactor = 0f;

// Where the finger first  touches the screen
private float startX = 0f;
private float startY = 0f;

// How …
Run Code Online (Sandbox Code Playgroud)

android surfaceview pinchzoom

8
推荐指数
1
解决办法
1986
查看次数

从视频中获取多个缩略图

我正在使用MediaMetadataRetriever视频中特定时间检索缩略图.这就是我实现这个目标的方法:

MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
    try {
        metadataRetriever.setDataSource(MainActivity.this, Uri.parse("android.resource://packageName/raw/"+"test"));
        String duration=metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        long time = Long.valueOf(duration)/3;
        Bitmap bitmap1 = metadataRetriever.getFrameAtTime(time,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        imgone.setImageBitmap(bitmap1);

    }catch (Exception ex) {
        Toast.makeText(MainActivity.this, String.valueOf(ex), Toast.LENGTH_SHORT).show();
        }
Run Code Online (Sandbox Code Playgroud)

这会返回一个预期的位图/缩略图,问题是如果我想在视频中的不同时间获得多个缩略图,如下所示:

MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
    try {
        metadataRetriever.setDataSource(MainActivity.this, Uri.parse("android.resource://packageName/raw/"+"test"));
        String duration=metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        long time = Long.valueOf(duration)/3;
        long time2 = time+time;
        long time3 = time+time+time;
        Bitmap bitmap1 = metadataRetriever.getFrameAtTime(time,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        Bitmap bitmap2 = metadataRetriever.getFrameAtTime(time2,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        Bitmap bitmap3 = metadataRetriever.getFrameAtTime(time3,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        imgone.setImageBitmap(bitmap1);
        imgtwo.setImageBitmap(bitmap2);
        imgthree.setImageBitmap(bitmap3);

    }catch (Exception ex) {
        Toast.makeText(MainActivity.this, String.valueOf(ex), Toast.LENGTH_SHORT).show();
        }
Run Code Online (Sandbox Code Playgroud)

然后它仍然只返回相同的缩略图,我不确定它是否是因为只有一个缩略图可用于视频或什么,但我尝试了不同的视频文件具有相同的结果.

我已尝试更改 …

android mediametadataretriever android-thumbnail

8
推荐指数
1
解决办法
193
查看次数

检测视频是否以人像/风景拍摄

我想确认一下,我所做的确实是正确的方法,因为某些元素的行为异常。

首先,据我了解,我有一个横向和纵向布局,这样做会自动检测手机是否处于纵向/横向模式:

- layout
   - activity_video_player.xml
 - layout-land
   - activity_video_player.xml
Run Code Online (Sandbox Code Playgroud)

然后,当用户从图库中选择一个视频时,我通过执行以下操作(在中OnCreate)来检查该视频是横向拍摄还是纵向拍摄:

int w;
int h;

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(this, videoURI);
String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
w = Integer.parseInt(width);
h = Integer.parseInt(height);

if (w > h) {  
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Run Code Online (Sandbox Code Playgroud)

我已经对此进行了测试,并且工作正常,但是我注意到我的某些xml元素(播放按钮)放置不正确。

所以我的应用程序流程是:

MainActivity --> SelectvidButton --> Gallery Intent --> VideoPlayActivity
Run Code Online (Sandbox Code Playgroud)

我的问题

这是这样做的正确方法吗?如果是,是否有某些原因导致某些xml元素放置不正确?


编辑1:

我注意到,只有在首次启动活动时才会发生这种情况,如果我按“后退”按钮并再次选择相同的视频,则布局完全像我想要的那样。


编辑2:

我还注意到,只有在上一个活动(MainActivity)与所选视频的方向相同时,才会发生这种情况。

android android-layout android-orientation

5
推荐指数
1
解决办法
572
查看次数

getExternalFilesDir权限

我的应用程序在Play商店上发布,我注意到在调用时我没有询问权限:

File savedImagesDirectory = getBaseContext.getExternalFilesDir("SavedImages");
if(savedImagesDirectory != null) {
    if (!savedImagesDirectory.exists()) {
        if (savedImagesDirectory.mkdir()) ; //directory is created;
    }
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,在没有运行时权限的情况下调用它时我没有遇到任何崩溃.我在运行Nougat的设备上进行了测试,文件已经创建,我没有遇到任何崩溃.

我只有我的清单中的权限,但我不问运行时权限.

我已经看到很多关于SO的答案,说在外部文件目录中创建文件夹/文件时应该询问运行时权限.


我的问题:

在调用上述内容时我应该询问运行时权限吗?如果是的话,为什么我没有遇到任何崩溃?

如果有人可以提供我可以阅读的链接,也会有所帮助.

java android android-permissions

5
推荐指数
1
解决办法
394
查看次数

从库中复制文件时显示ProgressDialog

目前

我打开与画廊Intent,用户可以接着从后将该文件复制到指定文件夹的画廊视频.一切正常.

我希望ProgressBar在用户选择视频(在图库中)之后显示一个权限,然后progresbar.dismiss在文件完成复制后显示.

这是类似的问题,但没有答案(没有任何效果):

这就是我称之为画廊的方式:

public void selectVideoFromGallery()
{

    Intent intent;
    if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
    {
        intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
    }
    else
    {
        intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.INTERNAL_CONTENT_URI);
    }

    intent.setType("video/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.putExtra("return-data", true);
    startActivityForResult(intent,SELECT_VIDEO_REQUEST);
}
Run Code Online (Sandbox Code Playgroud)

我在progressbar.show();这里试过(上图),但显然它会在选择视频之前开始显示.

这是我的OnActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(requestCode == SELECT_VIDEO_REQUEST && resultCode == RESULT_OK)
    {
        if(data.getData()!=null)
        {


            //copy file to new folder
            Uri selectedImageUri = data.getData();
            String sourcePath = getRealPathFromURI(selectedImageUri); …
Run Code Online (Sandbox Code Playgroud)

android progressdialog android-gallery android-asynctask

1
推荐指数
1
解决办法
648
查看次数

无法访问public void方法

我有这个方法 RecyclerView.Adapter

public void filter(String text) {
    mDataSet.clear();
    if(text.isEmpty()){
        mDataSet.addAll(mDataSet);
    } else{
        text = text.toLowerCase();
        for(AppInfo item: mDataSet){
            if(item.getAppName().toLowerCase().contains(text)){
                mDataSet.add(item);
            }
        }
    }
    notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)

我试图Activity通过调用来访问它:

search_view.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            //Here is where I'm trying to call the method
            mAdapter.filter(query);
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            return true;
        }
    });
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,我无法访问该方法.有人可以向我解释为什么会这样吗?

java android

1
推荐指数
1
解决办法
184
查看次数