android google map中我做了一个google...

亲爱的谷歌 别把安卓给搞砸了 - 开源中国社区
当前访客身份:游客 [
当前位置:
亲爱的谷歌 别把安卓给搞砸了
安卓的历史离不开一个词,那就是“繁多”。从2008年搭载在T-Mobile G1手机里的初代开始,谷歌的这一移动操作系统已经提供了太强的功能,太高的规格,更支持了太多设备。每次安卓发布更新,都会有很大提升,不过也多少会有 些“残酷无情”。因为安卓的崛起尽管可以为消费者带来了性能卓越的手机,但是用户却要么不得不摒弃掉原来老版本的软件,要么就得再购买一款新设备,而且, 这款设备说不定还不是市面上最好的。为了解决上述问题,去年末谷歌推出了Android 4.4 ,重点就是要“化繁为简”。
KitKat一统江湖
KitKat简化了操作界面,最低规格标准也降低了不少,它专注在提供优秀的用户体验上面,而且让谷歌的合作伙伴可以便捷、快速的更新自己的设备。 这样的结果,就是安卓的包容性和连续性比以往更强。不过,谷歌之所以这么做,一部分原因是为了解决的安卓不断演变所带来的碎片化效应。但在即将召开的上,很可能会出现新的安卓版本。
KitKat背后的巨大动力来自谷歌的“野心”。目前安卓的设备激活量已经突破了10亿,而这家互联网巨头可能再拥有10亿个智能手机用户。安卓可 以说是全球最受欢迎的移动平台,但对价格异常敏感的发展中国家市里,依然充斥着过时的安卓机,许多廉价的安卓设备甚至无法访问应用商店。对于谷歌而言,这 种状况会带来两个问题,对于刚刚接触安卓系统的新手来说,他们对这个操作系统的体验很差,而对曾经喜欢安卓的用户而言,他们不会在谷歌生态系统里花费时间 和金钱。麻烦的是,好的安卓和差的安卓完全是两码事儿。
摩托罗拉负责软件业务的副总裁Steve Horowitz认为,KitKat的低配置需求让价格极低的手机Moto E成为可能。Moto E是少数体验好,价格又低的安卓机。摩托罗拉之前推出过179美元的Moto G,而129美元的Moto E的市场应该会更大。如果说Moto G对欧洲和美国市场来说算是低价手机,那么Moto E对全世界来说都算得上是低价。
Moto E是KitKat理念的体现
Moto E可以说是把谷歌KitKat散播到全世界的“传教士”,它证明了最好最新的安卓系统可以在任何设备上运行,这与设备大小、价格都无关系。印度是智能手机 增长最快的市场之一,那里对Moto E的需求非常大,甚至一度出现了缺货现象。虽然在印度诺基亚和黑莓有着很高的声誉,但是借助于更高级的用户体验和更宽泛的生态系统,全新的谷歌手机正在吸 引更多买家。之前,在一些发展中国家,安卓虽然是主流移动操作系统,但被认为不中用,有些安卓系统的主搜索引擎还是百度。但现在,谷歌有了低价安卓手机, 可以在这些市场里提供更好的服务。
而在高端手机方面,如今甚至连奢华手机商Vertu都开始销售搭载最新版安卓系统的手机了,他们将安卓4.4作为默认操作系统。目前,所有大型安卓 制造商都已经在他们的设备中搭载了KitKat。在降低安卓生态系统碎片化方面,谷歌的KitKat获得了巨大的成功。但是相对于统一的iOS,谷歌还是 任重道远。当然,和过去相比谷歌算是好多了。如今,谷歌正在准备推出下一波安卓升级。
谷歌要重蹈覆辙?
最近出现了一些报道,说谷歌还会推出全新的“”计划,设立一个高规格的最低标准。随着Android Silver的出现,谷歌会将相关需求标准化,让部分机型软件更新的速度变得更快。不过此举也预示着谷歌在战略上的回归,也就是说他们会开始专注于高端设备了。
在安卓未来发展的道路上,无论谷歌选择走哪条路,在下一波大规模更新出现之前,KitKat应该还是能够成为市场上最主要的安卓系统版本。另外,从 硬件的角度来看,今年安卓手机还是保持了版本连贯性。高通最新的处理器几乎统治了各级市场,正是其高效的性能,让安卓系统能够在多款手机设备上运行。这一 点,无论今年的谷歌开发者大会上有任何推陈出新,都不会改变。
实际上,直至今日,安卓在体验一致性上才有所起色。无论你购买Vertu、摩托罗,还是索尼,基本的用户体验、性能以及各项功能都非常相似,让人感 觉他们都是属于同一软件家族的一部分。现在,谷歌似乎要像最初那样带来更多的创新了,如果这些创新做的不错,还是值得期待的。现在的手机再不会出现倒退, 功能也不会衰减,但是安卓的碎片化可能再次崛起。谷歌的挑战是不断前进,又不落下任何用户。
Android 的详细介绍:
Android 的下载地址:
想通过手机客户端(支持 Android、iPhone 和 Windows Phone)访问开源中国:
旧一篇: 2年前
新一篇: 2年前
相关讨论话题
你也许会喜欢
mbd,不是百度还能是什么?Google又用不了。写文章的人还能再sb一点么?
2楼:yyszh0 来自
这是谷歌的问题么?
3楼:李师叔 来自
感觉说了通废话。
4楼:jun4rui
Google对Android的发展还是不遗余力,从1.5到现在的进步之巨大可谓有目共睹。能把Android搞砸了的只有国产厂商、各种“拥有自主版权”的Android Clone之类的玩意,希望大家坚决抵制,别让他们把Android搞砸了。
5楼:mySweet 来自
引用来自“袁国涛”的评论mbd,不是百度还能是什么?Google又用不了。写文章的人还能再sb一点么? +1024
6楼:Nekojara 来自
这文章是神马玩意儿啊?!
不知道作者要说啥,
8楼:SeeleScheider 来自
我是只看到对设备要求越来越高了……
9楼:梁选 来自
引用来自“jun4rui”的评论Google对Android的发展还是不遗余力,从1.5到现在的进步之巨大可谓有目共睹。能把Android搞砸了的只有国产厂商、各种“拥有自主版权”的Android Clone之类的玩意,希望大家坚决抵制,别让他们把Android搞砸了。呵呵
10楼:嗨酷网 来自
这算是什么黑
11楼:剑麟
要是谷歌能够规定android的屏幕尺寸、系统版本,那该多好。。。。像ios那样
12楼:xesam 来自
引用来自“剑麟”的评论要是谷歌能够规定android的屏幕尺寸、系统版本,那该多好。。。。像ios那样其他厂商不跟着走,白搭。。。
13楼:sdfs
12:25 (非会员)
引用来自“jun4rui”的评论Google对Android的发展还是不遗余力,从1.5到现在的进步之巨大可谓有目共睹。能把Android搞砸了的只有国产厂商、各种“拥有自主版权”的Android Clone之类的玩意,希望大家坚决抵制,别让他们把Android搞砸了。还没毕业了吧。
14楼:jun4rui
回楼上,我78年的初中家里就有PC开始自学了,大学计算机应用毕业不过我大学前那点东西就自学完8成了。不过确实,人生哪里有毕业一说?
15楼:自由建客 来自
從未好過談何砸?
16楼:梵蒂冈空军飞行员
引用来自“jun4rui”的评论Google对Android的发展还是不遗余力,从1.5到现在的进步之巨大可谓有目共睹。能把Android搞砸了的只有国产厂商、各种“拥有自主版权”的Android Clone之类的玩意,希望大家坚决抵制,别让他们把Android搞砸了。+1024
17楼:huodon
21:18 (非会员)
可怜的幻灯片系统连个像样的模拟器都没.
18楼:霍小平 来自
设备厂商太多,中国山寨太强大,再说了谷歌来源,这一切都形成不了一个良好的发展环境。唉,可悲
19楼:马克西马
引用来自“Nekojara”的评论这文章是神马玩意儿啊?! 你是多啦A梦!
与内容无关的评论将被删除,严重者禁用帐号
本周热点资讯
本站最新资讯扫描或点击关注中金在线客服
下次自动登录
其它账号登录:
||||||||||||||||||||||||
&&&&>> &正文
已经有了安卓,为何谷歌会做一个全新的操作系统?
来源:腾讯科技&&&
作者:佚名&&&
中金在线微博
扫描二维码
中金在线微信
扫描或点击关注中金在线客服
  《快公司》网站日前发表文章,对谷歌开发一个全新操作系统的原因进行了分析,解释了现有操作系统存在的问题,并对谷歌此举的动机进行了推测。
  腾讯科技编者按 《快公司》网站日前发表文章,对谷歌开发一个全新操作系统的原因进行了分析,解释了现有操作系统存在的问题,并对谷歌此举的动机进行了推测,以下为原文:
  上周,谷歌一个团队做了一件很奇怪的事情:他们悄悄透露自己在构建一个新的操作系统,名叫Fuchsia。从理论上说,Fuchsia是谷歌Android的竞争对手。
  Fuchsia是一个正在开发中的开源操作系统。它可以在各种设备上运行,无论是单一用途的设备(比如自动取款机ATM和GPS单元),还是桌面电脑,都是它的用武之地。但是,与Android不同的是,Fuchsia并不是一个基于Linux的系统,也没有以其他支柱型软件为基础。它是从零开始构建的。
  Fuchsia仍处在构建的早期阶段,而且有可能是个实验性项目。谷歌目前尚未提及它将如何使用Fuchsia。软件发展已经有数十年的历史,为什么谷歌要从零开始构建操作系统呢?它的理由有很多。
  内核的问题
  对于你的手机、平板电脑和笔记本电脑,有一些事情可能你还不知道:大多数时候,它们使用的都是稍加改动过的古老软件“内核”。 Android使用Linux内核是1991年开发的,Mac OS X、iOS和苹果的其他平台是基于Unix系统的,那是AT&T贝尔实验室在1969年启动的一个项目。Windows计算机则是基于Windows NT内核,其历史可追溯到1993年。
  内核的目的是管理操作系统最底层一些活动。它处理来自硬件设备(比如键盘)的请求、安排日程任务,对文件和存储器进行管理。在这个过程中,它对操作系统的复杂活动进行了抽象。这么做有很多好处,比如让开发人员无需了解打印机的具体型号,就可以令app执行打印操作。
  Unix、Linux和Windows NT这样的老式内核一直在挑大梁,似乎与科技业一向求新求变的风尚相矛盾,但行业分析师贺拉斯 德度(Horace Dediu)认为,从最底层的角度来看,计算基本上是相同的,和几十年前区别不大。举例来说,如今Windows计算机上使用的芯片,就是首台IBM PC上英特尔处理器的嫡传后裔。从这个意义上说,内核不过是一种通用产品。
  “我们使用的仍然是完全相同的架构,完全相同的计算方式——寄存器、逻辑门、晶体管——出于这个原因,我们没有必要开发一个更好的内核,”德度说。 “内核我们已经搞定了。”
  可能是我们以为已经搞定了。现如今,我们正在把传感器和计算能力塞进更多的设备里面,比如把普通住宅改装为智能住宅,让所有东西都能联网(也就是物联网)的时候。谷歌之所以开发Fuchsia,可能是觉得Linux这样的老式内核不适用于这一代新的设备。因此他们想为新的世代研发出一个新的内核。 (内核本身被称为Magenta,它以谷歌近期的另一个实验性项目LittleKernel为基础)。
  扎克 苏帕拉(Zach Supalla)在硬件开发工具和物联网服务提供商Particle公司工作。他指出,Linux用在小型计算设备上时有些问题。
  首先,对于这类设备来说,Linux过于庞大了。尽管Linux内核是模块化的,开发者可以去除多余的部分,但它还是会占用大量空间。这意味着要把Linux内核塞到一个价格便宜的微控制器里比较困难,你必须选用更大、价格更高,更加耗电的处理器。
  “整个供应链本来可以以远远更低的成本制造品质更高的东西,”苏帕拉说。
  另一个问题是,Linux不是“实时”的。自动取款机、医疗产品和其他单一用途设备采用了嵌入式操作系统,和它们不一样的是,Linux是靠一个时间表来处理多任务的。虽然这可以最大限度地发挥通用计算机的性能,但却也会给那些需要精确定时的设备带来麻烦。像3D打印机,汽车内部的很多电动控制装置等等,都对精确定时有很高的要求。
  “如果你想确保这些设备在某个微秒准时启动,你真的不希望由一个进程来决定运行时间,”苏帕拉说。
  对于物联网应用来说,像Linux这种通用的操作系统可能会不太安全,苏帕拉说。它的代码更多,这也就意味着需要防范的漏洞也会更多,你必须使用防火墙或者VPN来解决或封堵这些安全漏洞。
  “使用实时操作系统(嵌入式系统)的优点之一,就是不需要封堵任何东西,”苏帕拉说。 “你不需要运行一堆你必须小心留神的东西。它只运行你写的软件,不会运行其他任何东西。”
  但在软硬件通信方面,Linux仍然有很大的优势。苏帕拉认为,谷歌开发Fuchsia是希望把Linux和嵌入式系统这两者的长处结合起来。当今主流的嵌入式系统包括FreeRTOS和ThreadX等,
  “他们可能想要开发一个抽象程度达到Linux水平,但性能、体量和实时性与RTOS相当的操作系统,”苏帕拉说。 “这样的操作系统有很大的价值,我觉得从理论上说是可以办到的。只是以前从来没有人这么做过。”
  扩展性问题
  如果Fuschia针对的只是小型设备,它可能没有那么引人瞩目。但是Fuchsia的开发人员有更远大的雄心,他们声称该操作系统可以扩展到智能手机和台式电脑上。从理论上讲,Fuchsia可以直接替代谷歌的Android和Chrome OS。
  谷歌为什么要这么做?苏帕拉认为,从零开始或许可以构建出更高效的操作系统,从而获得更高效的服务器——谷歌一向都对这方面很感兴趣。他还指出,兼容台式机有助于模拟大量小型设备同时运行,确保它们可以在大规模使用的时候正常运行。
  “和开动一千台服务器,每台同时运行一千个同样的程序相比,启动一百万个小型设备远远麻烦得多,不有利于开展测试,”苏帕拉说。
  德度的看法与苏帕拉不同,他认为谷歌Android受到了知识产权方面的限制,而一个全新的操作系统则没有这样的问题。 “因为这是一个全新的设计,在知识产权方面它没有任何麻烦,”他说。 “这可能是一个合理的假设,因为Linux确实存在一些难缠的知识产权问题。”
  别忘了,这可能纯粹是个学术研究。Fuchsia的开发人员表示,最终他们会发布这个操作系统,但可能还有很长的路要走,而且目前也不清楚谷歌是否会支持这个项目。 Android生态系统已经是十分庞大(而且正在开始和Chromebook合并)。而且谷歌还在开发一个嵌入式的轻量级物联网操作系统Brillo,它是Android的一个简化版本——Brillo正在形成一个成熟的平台,而不仅仅是一个基础性的操作系统。
共 2 页&& 1
责任编辑:cnfol001
我来说两句
24小时热门文章
栏目最新文章博客访问: 1003715
博文数量: 121
博客积分: 3526
博客等级: 中校
技术积分: 1800
注册时间:
认证徽章:
记录总结自己的工作
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Android平台
& & & 最近项目有个需求要对录制的视频进行分割,查了很多资料,看到ffmpeg可以对视频进行分割。上网找到别人基于android的开源ffmpeg,终于编译成功ffmpeg.so。但是要使用的话还要查ffmpeg的api,并且写jni的调用接口,非常麻烦。偶然情况下发现了开源软件mp4parser:&&一款非常棒的开源软件,可以对视频进行分割、组合等操作,而且使用起来非常简单。通过svn对其下载后可以看到里面带着视频分割的例子,但是是用java实现,将其稍微修改一下就可以用在Android上了。
& & &&首先将例子中的代码修改为一个工具类,通过接口传进视频文件的路径和截取视频的开始、结束时间。需要注意的是,如果传的开始时间是10s,视频一般不会刚好是从10s开始的,要根据视频的关键帧做一下调整。截取出来的视频会放到存储卡的Clip目录下。代码如下:
package com.example.mp4clip;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import android.os.Environment;
import android.util.Log;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.CroppedTrack;
public class ClipUtil {
&&&&private static final String TAG = "ClipUtil";
&&&& * 截取指定时间段的视频
&&&& * @param path 视频的路径
&&&& * @param begin 需要截取的开始时间
&&&& * @param end 截取的结束时间
&&&& * @throws IOException
&&&&public static void clipVideo(String path, double begin, double end)
&&&&&&&&&&&&throws IOException {
&&&&&&&&File mSdCardDir = Environment.getExternalStorageDirectory();
&&&&&&&&File f = new File(mSdCardDir.getAbsolutePath() + File.separator
&&&&&&&&&&&&&&&&+ Util.SAVE_PATH);
&&&&&&&&if (!f.exists()) {
&&&&&&&&&&&&f.mkdir();
&&&&&&&&// Movie movie = new MovieCreator().build(new
&&&&&&&&// RandomAccessFile("/home/sannies/suckerpunch-distantplanet_h1080p/suckerpunch-distantplanet_h1080p.mov",
&&&&&&&&// "r").getChannel());
&&&&&&&&Movie movie = MovieCreator.build(path);
&&&&&&&&List<Track> tracks = movie.getTracks();
&&&&&&&&movie.setTracks(new LinkedList<Track>());
&&&&&&&&// remove all tracks we will create new tracks from the old
&&&&&&&&double startTime1 = begin;
&&&&&&&&double endTime1 = end;
&&&&&&&&// double startTime2 = 30;
&&&&&&&&// double endTime2 = 40;
&&&&&&&&boolean timeCorrected = false;
&&&&&&&&// Here we try to find a track that has sync samples. Since we can only
&&&&&&&&// start decoding
&&&&&&&&// at such a sample we SHOULD make sure that the start of the new
&&&&&&&&// fragment is exactly
&&&&&&&&// such a frame
&&&&&&&&for (Track track : tracks) {
&&&&&&&&&&&&if (track.getSyncSamples() != null
&&&&&&&&&&&&&&&&&&&&&& track.getSyncSamples().length > 0) {
&&&&&&&&&&&&&&&&if (timeCorrected) {
&&&&&&&&&&&&&&&&&&&&// This exception here could be a false positive in case we
&&&&&&&&&&&&&&&&&&&&// have multiple tracks
&&&&&&&&&&&&&&&&&&&&// with sync samples at exactly the same positions. E.g. a
&&&&&&&&&&&&&&&&&&&&// single movie containing
&&&&&&&&&&&&&&&&&&&&// multiple qualities of the same video (Microsoft Smooth
&&&&&&&&&&&&&&&&&&&&// Streaming file)
&&&&&&&&&&&&&&&&&&&&Log.e(TAG,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&"The startTime has already been corrected by another track with SyncSample. Not Supported.");
&&&&&&&&&&&&&&&&&&&&throw new RuntimeException(
&&&&&&&&&&&&&&&&&&&&&&&&&&&&"The startTime has already been corrected by another track with SyncSample. Not Supported.");
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&startTime1 = correctTimeToSyncSample(track, startTime1, false);
&&&&&&&&&&&&&&&&endTime1 = correctTimeToSyncSample(track, endTime1, true);
&&&&&&&&&&&&&&&&// startTime2 = correctTimeToSyncSample(track, startTime2,
&&&&&&&&&&&&&&&&// false);
&&&&&&&&&&&&&&&&// endTime2 = correctTimeToSyncSample(track, endTime2, true);
&&&&&&&&&&&&&&&&timeCorrected = true;
&&&&&&&&&&&&}
&&&&&&&&for (Track track : tracks) {
&&&&&&&&&&&&long currentSample = 0;
&&&&&&&&&&&&double currentTime = 0;
&&&&&&&&&&&&double lastTime = 0;
&&&&&&&&&&&&long startSample1 = -1;
&&&&&&&&&&&&long endSample1 = -1;
&&&&&&&&&&&&// long startSample2 = -1;
&&&&&&&&&&&&// long endSample2 = -1;
&&&&&&&&&&&&for (int i = 0; i < track.getSampleDurations().length; i++) {
&&&&&&&&&&&&&&&&long delta = track.getSampleDurations()[i];
&&&&&&&&&&&&&&&&if (currentTime > lastTime && currentTime <= startTime1) {
&&&&&&&&&&&&&&&&&&&&// current sample is still before the new starttime
&&&&&&&&&&&&&&&&&&&&startSample1 = currentSample;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&if (currentTime > lastTime && currentTime <= endTime1) {
&&&&&&&&&&&&&&&&&&&&// current sample is after the new start time and still
&&&&&&&&&&&&&&&&&&&&// before the new endtime
&&&&&&&&&&&&&&&&&&&&endSample1 = currentSample;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&// if (currentTime > lastTime && currentTime <= startTime2) {
&&&&&&&&&&&&&&&&// // current sample is still before the new starttime
&&&&&&&&&&&&&&&&// startSample2 = currentS
&&&&&&&&&&&&&&&&// }
&&&&&&&&&&&&&&&&// if (currentTime > lastTime && currentTime <= endTime2) {
&&&&&&&&&&&&&&&&// // current sample is after the new start time and still
&&&&&&&&&&&&&&&&// before the new endtime
&&&&&&&&&&&&&&&&// endSample2 = currentS
&&&&&&&&&&&&&&&&// }
&&&&&&&&&&&&&&&&lastTime = currentTime;
&&&&&&&&&&&&&&&&currentTime += (double) delta
&&&&&&&&&&&&&&&&&&&&&&&&/ (double) track.getTrackMetaData().getTimescale();
&&&&&&&&&&&&&&&&currentSample++;
&&&&&&&&&&&&}
&&&&&&&&&&&&movie.addTrack(new CroppedTrack(track, startSample1, endSample1));// new
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// AppendTrack(new
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// CroppedTrack(track,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// startSample1,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// endSample1),
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// new
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// CroppedTrack(track,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// startSample2,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// endSample2)));
&&&&&&&&long start1 = System.currentTimeMillis();
&&&&&&&&Container out = new DefaultMp4Builder().build(movie);
&&&&&&&&long start2 = System.currentTimeMillis();
&&&&&&&&FileOutputStream fos = new FileOutputStream(f.getAbsolutePath()
&&&&&&&&&&&&&&&&+ File.separator
&&&&&&&&&&&&&&&&+ String.format("output-%f-%f.mp4", startTime1, endTime1));
&&&&&&&&FileChannel fc = fos.getChannel();
&&&&&&&&out.writeContainer(fc);
&&&&&&&&fc.close();
&&&&&&&&fos.close();
&&&&&&&&long start3 = System.currentTimeMillis();
&&&&&&&&Log.e(TAG, "Building IsoFile took : " + (start2 - start1) + "ms");
&&&&&&&&Log.e(TAG, "Writing IsoFile took
: " + (start3 - start2) + "ms");
&&&&&&&&Log.e(TAG,
&&&&&&&&&&&&&&&&"Writing IsoFile speed : "
&&&&&&&&&&&&&&&&&&&&&&&&+ (new File(String.format("output-%f-%f.mp4",
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&startTime1, endTime1)).length()
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/ (start3 - start2) / 1000) + "MB/s");
&&&&private static double correctTimeToSyncSample(Track track, double cutHere,
&&&&&&&&&&&&boolean next) {
&&&&&&&&double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
&&&&&&&&long currentSample = 0;
&&&&&&&&double currentTime = 0;
&&&&&&&&for (int i = 0; i < track.getSampleDurations().length; i++) {
&&&&&&&&&&&&long delta = track.getSampleDurations()[i];
&&&&&&&&&&&&if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
&&&&&&&&&&&&&&&&// samples always start with 1 but we start with zero therefore
&&&&&&&&&&&&&&&&// +1
&&&&&&&&&&&&&&&&timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(),
&&&&&&&&&&&&&&&&&&&&&&&&currentSample + 1)] = currentTime;
&&&&&&&&&&&&}
&&&&&&&&&&&&currentTime += (double) delta
&&&&&&&&&&&&&&&&&&&&/ (double) track.getTrackMetaData().getTimescale();
&&&&&&&&&&&&currentSample++;
&&&&&&&&double previous = 0;
&&&&&&&&for (double timeOfSyncSample : timeOfSyncSamples) {
&&&&&&&&&&&&if (timeOfSyncSample > cutHere) {
&&&&&&&&&&&&&&&&if (next) {
&&&&&&&&&&&&&&&&&&&&return timeOfSyncSample;
&&&&&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&&&&&return previous;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&previous = timeOfSyncSample;
&&&&&&&&return timeOfSyncSamples[timeOfSyncSamples.length - 1];
&&&&&&&& 有了工具类,下面就是增加一个操作界面了。我用一个列表列出所有的视频,点击视频后就会在后台截取出5s~15s总共10s的视频。当然也可以根据需要加上自己想要的开始结束时间,代码如下:
package com.example.mp4clip;
import java.io.IOException;
import java.lang.ref.SoftReference;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import edu.mit.mobile.android.imagecache.ImageCache;
import edu.mit.mobile.android.imagecache.ImageCache.OnImageLoadListener;
public class MainActivity extends Activity implements OnItemClickListener,
&&&&&&&&OnImageLoadListener {
&&&&private static final String TAG = "MainActivity";
&&&&ListView mList;
&&&&private Cursor mCursor;
&&&&private final SparseArray<SoftReference<ImageView>> mImageViewsToLoad = new SparseArray<SoftReference<ImageView>>();
&&&&private ImageCache mCache;
&&&&@Override
&&&&protected void onCreate(Bundle savedInstanceState) {
&&&&&&&&super.onCreate(savedInstanceState);
&&&&&&&&setContentView(R.layout.activity_main);
&&&&&&&&mCache = ImageCache.getInstance(this);
&&&&&&&&mCache.registerOnImageLoadListener(this);
&&&&&&&&mList = (ListView) findViewById(R.id.list);
&&&&&&&&mList.setOnItemClickListener(this);
&&&&&&&&mCursor = getContentResolver().query(
&&&&&&&&&&&&&&&&MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null,
&&&&&&&&&&&&&&&&MediaStore.Video.Media.DATE_MODIFIED + " desc");
&&&&&&&&SimpleCursorAdapter adapter = new videoListAdapter(this,
&&&&&&&&&&&&&&&&R.layout.video_listitem, mCursor,
&&&&&&&&&&&&&&&&new String[] { MediaStore.Video.Media.TITLE },
&&&&&&&&&&&&&&&&new int[] { R.id.video_title });
&&&&&&&&mList.setAdapter(adapter);
&&&&@Override
&&&&public boolean onCreateOptionsMenu(Menu menu) {
&&&&&&&&getMenuInflater().inflate(R.menu.main, menu);
&&&&&&&&return true;
&&&&public boolean onOptionsItemSelected(MenuItem item) {
&&&&&&&&// 扫描新多媒体文件,添加到数据库中
&&&&&&&&sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
&&&&&&&&&&&&&&&&Uri.parse("file://"
&&&&&&&&&&&&&&&&&&&&&&&&+ Environment.getExternalStorageDirectory()
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.getAbsolutePath())));
&&&&&&&&return false;
&&&&@Override
&&&&public void onItemClick(AdapterView<?> parent, View view, int position,
&&&&&&&&&&&&long id) {
&&&&&&&&if (mCursor.moveToPosition(position)) {
&&&&&&&&&&&&int index = -1;
&&&&&&&&&&&&index = mCursor.getColumnIndex(MediaStore.Video.Media.DATA);
&&&&&&&&&&&&String path = null;
&&&&&&&&&&&&if (index >= 0) {
&&&&&&&&&&&&&&&&path = mCursor.getString(index);
&&&&&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&&&&&ClipUtil.clipVideo(path, 5, 15);
&&&&&&&&&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&private static final class ViewHolder {
&&&&&&&&/** 视频名称 */
&&&&&&&&TextView titleView;
&&&&&&&&/** 视频时长 */
&&&&&&&&TextView durationView;
&&&&&&&&/** 文件大小 */
&&&&&&&&TextView sizeView;
&&&&private class videoListAdapter extends SimpleCursorAdapter {
&&&&&&&&/*
&&&&&&&& * constructor.
&&&&&&&& */
&&&&&&&&public videoListAdapter(Context context, int layout, Cursor c,
&&&&&&&&&&&&&&&&String[] from, int[] to) {
&&&&&&&&&&&&super(context, layout, c, from, to);
&&&&&&&&@Override
&&&&&&&&public int getCount() {
&&&&&&&&&&&&return super.getCount();
&&&&&&&&@Override
&&&&&&&&public Object getItem(int position) {
&&&&&&&&&&&&return super.getItem(position);
&&&&&&&&@Override
&&&&&&&&public long getItemId(int position) {
&&&&&&&&&&&&return super.getItemId(position);
&&&&&&&&@Override
&&&&&&&&public View getView(int position, View convertView, ViewGroup parent) {
&&&&&&&&&&&&View view = super.getView(position, convertView, parent);
&&&&&&&&&&&&Cursor cursor = getCursor();
&&&&&&&&&&&&cursor.moveToPosition(position);
&&&&&&&&&&&&ViewHolder holder = (ViewHolder) view.getTag();
&&&&&&&&&&&&if (holder == null) {
&&&&&&&&&&&&&&&&holder = new ViewHolder();
&&&&&&&&&&&&&&&&holder.titleView = (TextView) view
&&&&&&&&&&&&&&&&&&&&&&&&.findViewById(R.id.video_title);
&&&&&&&&&&&&&&&&holder.durationView = (TextView) view
&&&&&&&&&&&&&&&&&&&&&&&&.findViewById(R.id.video_duration);
&&&&&&&&&&&&&&&&holder.sizeView = (TextView) view.findViewById(R.id.video_size);
&&&&&&&&&&&&}
&&&&&&&&&&&&view.setTag(holder);
&&&&&&&&&&&&final ImageView iv = (ImageView) view.findViewById(R.id.thumbnail);
&&&&&&&&&&&&int index = -1;
&&&&&&&&&&&&index = mCursor.getColumnIndex(MediaStore.Video.Media.DATA);
&&&&&&&&&&&&String path = null;
&&&&&&&&&&&&if (index >= 0) {
&&&&&&&&&&&&&&&&path = mCursor.getString(index);
&&&&&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&&&&&Drawable draw = mCache.loadImage(position, Uri.parse(path),
&&&&&&&&&&&&&&&&&&&&&&&&&&&&120, 120);
&&&&&&&&&&&&&&&&&&&&if (draw != null) {
&&&&&&&&&&&&&&&&&&&&&&&&iv.setBackground(draw);
&&&&&&&&&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&&&&&&&&&mImageViewsToLoad.put(position,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&new SoftReference<ImageView>(iv));
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&index = -1;
&&&&&&&&&&&&index = cursor.getColumnIndex(MediaStore.Video.Media.TITLE);
&&&&&&&&&&&&String title = null;
&&&&&&&&&&&&if (index >= 0) {
&&&&&&&&&&&&&&&&title = cursor.getString(index);
&&&&&&&&&&&&&&&&holder.titleView.setText(title);
&&&&&&&&&&&&}
&&&&&&&&&&&&index = -1;
&&&&&&&&&&&&index = cursor.getColumnIndex(MediaStore.Video.Media.DURATION);
&&&&&&&&&&&&int duration;
&&&&&&&&&&&&if (index >= 0) {
&&&&&&&&&&&&&&&&duration = cursor.getInt(index);
&&&&&&&&&&&&&&&&holder.durationView.setText(Util.durationFormat(duration));
&&&&&&&&&&&&}
&&&&&&&&&&&&index = -1;
&&&&&&&&&&&&index = cursor.getColumnIndex(MediaStore.Video.Media.SIZE);
&&&&&&&&&&&&long size;
&&&&&&&&&&&&if (index >= 0) {
&&&&&&&&&&&&&&&&size = cursor.getLong(index);
&&&&&&&&&&&&&&&&holder.sizeView.setText(Util.sizeFormat(size));
&&&&&&&&&&&&}
&&&&&&&&&&&&return view;
&&&&@Override
&&&&public void onImageLoaded(int id, Uri imageUri, Drawable image) {
&&&&&&&&Log.d(TAG, "onImageLoaded:" + id);
&&&&&&&&final SoftReference<ImageView> ivRef = mImageViewsToLoad.get(id);
&&&&&&&&if (ivRef == null) {
&&&&&&&&&&&&Log.d(TAG, "ivRef=null");
&&&&&&&&&&&&return;
&&&&&&&&final ImageView iv = ivRef.get();
&&&&&&&&if (iv == null) {
&&&&&&&&&&&&Log.d(TAG, "ivRef=null");
&&&&&&&&&&&&mImageViewsToLoad.remove(id);
&&&&&&&&&&&&return;
&&&&&&&&iv.setBackground(image);
阅读(13028) | 评论(33) | 转发(2) |
相关热门文章
给主人留下些什么吧!~~
:博主,down最新的代码下来,android录下来的mp4视频切割后没有声音,我运行的是SimpleShortenExample.java这个类,你试过有声音的吗?另外,github上也没有编译好的jar包,源码down下来报错。
我的也没声音你怎么解决的呢 |
楼主您好,我下载的是&&【mp4parser-mp4parser-project-1.9.21】&还有【mp4parser-master】&&这两个里面全是密密麻麻的&.java文件呢,不是完整的工程,怎么用啊,哪个类是分包的呢&不太懂怎么使用呢&求讲解
:博主,down最新的代码下来,android录下来的mp4视频切割后没有声音,我运行的是SimpleShortenExample.java这个类,你试过有声音的吗?另外,github上也没有编译好的jar包,源码down下来报错。
有编译好的包,你看release |
博主,down最新的代码下来,android录下来的mp4视频切割后没有声音,我运行的是SimpleShortenExample.java这个类,你试过有声音的吗?另外,github上也没有编译好的jar包,源码down下来报错。
:您好,我用的就是他这里的最新的代码,所以我很费解,而且不知如何解遂向您请教解决方案,可否有您的联系方式?&我的QQ
你出错的那个地方是test类,怎么能用来分割视频呢?运行examples里面的 |
请登录后评论。

我要回帖

更多关于 android google map 的文章

 

随机推荐