安卓手机读取单反数码相机的图片

文章來源

接到一个项目需求,要求安卓手机通过usb线连接单反相机,读取其拍摄的照片及视频。

初步百度了解使用的技术、最快捷是看博客找到源码,能实现出功能的项目源码更是为妙。

GitHub - ynyao/cameraphoto: 通过mtp获取单反相机中的照片来自仓库的一个源码分享,接下来我将详细讲解源码内容的实现。

目錄結構


项目内app文件夹的展开图


项目内photoview文件夹的展开图

先忽略图中每个文件的红色叉叉,原因是笔者使用了非安卓开发软件打开了项目,之后会换一台电脑继续编写,注意:项目是用AndroidStudio3.0打开的,低版本可能出错。

看了一下目录,app文件夹是项目的启动项目,而photoview则是以libaray形式存在于项目中,相当于一个jar包吧,这种方式称为把别的项目当成lib导入项目中,就可以使用其项目的一些方法,接口。

導包情況

在观察一下build.grade中的依赖情况

dependencies {

    implementation fileTree(include: ['*.jar'], dir: 'libs')

    implementation 'com.android.support:appcompat-v7:26.1.0'

    implementation 'com.android.support.constraint:constraint-layout:1.1.2'

    implementation 'com.android.support:support-v4:26.1.0'

    implementation 'com.android.support:recyclerview-v7:26+'

    implementation 'com.squareup.picasso:picasso:2+'

    implementation 'io.reactivex.rxjava2:rxjava:2+'

    implementation 'io.reactivex.rxjava2:rxandroid:2+'

    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'com.android.support.test:runner:1.0.1'

    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

    implementation project(':photoview')

}

当中引入了RxJava的RxAndroid包是为了解决异步操作问题,类似于AsyncTask

implementation 'io.reactivex.rxjava2:rxjava:2+'

implementation 'io.reactivex.rxjava2:rxandroid:2+'

RxAndroid2.0使用概述 - CSDN博客

Android响应式编程框架---RxJava&RxAndroid2.0使用笔记 - CSDN博客

啟動運行流程

说一下程序运行流程,先是启动MainActivity-->在活动中检查权限、是否用相机插入等,并先显示英特空的Fraggment界面。透过函数mService=new MTPService(this);实例化具体的操作对象,mtp是一种多媒体传输协议的简写,在MtpService实例化的同时,条件满足则构造方法里startScanPic开始做进一步的读取图片操作。

實現功能的核心代碼段

public void startScanPic(){ disposable = interval(8, TimeUnit.SECONDS) .onBackpressureDrop() .map(new Function() {

                    @Override

                    public List apply(Long aLong) throws Exception {

                        Log.d(TAG,"start1===" + aLong);

                        List list = new ArrayList();

                        if (mMtpDevice != null) {

                            MtpDeviceInfo mtpDeviceInfo = mMtpDevice.getDeviceInfo();

                            String deviceSeriNumber = null;

                            if (mtpDeviceInfo != null)

                                deviceSeriNumber = mtpDeviceInfo.getSerialNumber();

                            else

                                deviceSeriNumber = "xx";

                            int[] storageIds = mMtpDevice.getStorageIds();

                            if (storageIds == null) {

                                showToast(mContext,"获取相机存储空间失败");

                                return list;

                            }

                            for (int storageId : storageIds) {

                                //把儲存空間每個id對應的圖片數據賦值給 objectHandles 

                                int[] objectHandles = mMtpDevice.getObjectHandles(storageId, MtpConstants.FORMAT_EXIF_JPEG, 0);

                                if(objectHandles==null){

                                    showToast(mContext,"获取照片失败");

                                    return list;

                                }

                                for (int objectHandle : objectHandles) {

                                    MtpObjectInfo mtpobj = mMtpDevice.getObjectInfo(objectHandle);

                                    if (mtpobj == null) {

                                        continue;

                                    }

                                    long dateCreated=mtpobj.getDateCreated();

                                //最後通過  mMtpDevice.getThumbnail(objectHandle)獲得照片的比特流,後續就是將比特流轉文件File并保存在指定地址

                                    byte[] bytes = mMtpDevice.getThumbnail(objectHandle);

                                    filePath.setLength(0);

                                    filePath.append(Environment.getExternalStorageDirectory().getAbsolutePath())

                                            .append(File.separator)

                                            .append("thumbCache")

                                            .append(File.separator)

                                            .append(String.valueOf(dateCreated))

                                            .append(".jpg");

                                    File fileJpg = new File(filePath.toString());

                                    if (!fileJpg.exists() && bytes != null)

                                        FileUtils.bytes2File(bytes, filePath.toString());

                                    PicInfo info = new PicInfo();

                                    info.setObjectHandler(objectHandle);

                                    info.setmThumbnailPath(fileJpg.getAbsolutePath());

                                    info.setmDateCreated(dateCreated);

                                    info.setmImagePixWidth(mtpobj.getImagePixWidth());

                                    info.setmImagePixHeight(mtpobj.getImagePixHeight());

                                    info.setmImagePixDepth(mtpobj.getImagePixDepth());

                                    info.setmThumbPixHeight(mtpobj.getThumbPixHeight());

                                    info.setmThumbPixWidth(mtpobj.getThumbPixWidth());

                                    info.setSequenceNumber(mtpobj.getSequenceNumber());

                                    info.setKeyWords(mtpobj.getKeywords());

                                    info.setmSerialNumber(deviceSeriNumber);

                                    //                                        if(Long.toString(mtpobj.getDateCreated()).startsWith("15")){

                                    //                                            mMtpDevice.deleteObject(objectHandle);

                                    //                                        }

                                    list.add(info);

                                }

                            }

                        }

                        return list;

                    }

                }).subscribeOn(Schedulers.io())              //线程调度器,将发送者运行在子线程

                .observeOn(AndroidSchedulers.mainThread())          //接受者运行在主线程

                .subscribe((Consumer) mContext);

    }

//過程用了RxJava,return list到MainActivity中,再由活動中的方法實現圖片列表等

至此,PhotoView沒提過,其實就是一些自定義的View

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,577评论 25 707
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    wgl0419阅读 6,136评论 1 9
  • 第一天用新手机,手感很好,颇为欣喜。更多的是因为老公的送的生日礼物。 而原来的手机,已经伴随我两年七个月了...
    大树一班阅读 111评论 0 1
  • 花开花落,又是一年。突然想到这一年应该再提笔写写我们的故事,其实也就是两句闲言碎语,却应当记录下来,日后也好留个念...
    小凡同学呀阅读 230评论 0 0
  • 如果你认同管理者运用教练模式更科学,你已经成功了一半,很快你的员工会断奶,能够独挡一面,而你也能够从繁琐重复的简单...
    关键姐阅读 978评论 0 1