[转载]Android拍照后文件的单个扫描上传

[转载]歇一歇(1)文件的单个扫描 – One Kid Sky – 博客园.

终于能有闲暇来写些东西,就当是对前段时间工作的总结。

 

公司年前制定一个基于GPS定位的进销存数据上报的软件,大体上就是这么个东西,本人主要负责终端开发(Android手机)。开发周期3个月,包括过年。

 

首先看一个问题:

 

项目需求1:现场拍照上传,或者选择已有文件上传。就是类似于微博中发表带图片的微博是一个道理。

 

首先,从现有文件选择上传这个比较容易解决:

 

只需要发起一个Intent:

 

action:Intent.ACTION_GET_CONTENT

 

type:image/*

 

startActivityForResult(intent,code);//一定要使用此方法哦,接收返回值。

 

比较头痛的是调用系统相机并且拍照上传,原因是这个样子的,首先,调用系统相机,拍照确认并返回到主界面,图片正常显示到你规划的 ImageView中,这个时候,你突发奇想,通过选择已有文件的方式,也就是通过调用系统相册,或者什么文件浏览器来再次加载刚才新鲜出炉的图片到你的 ImageView时,这是你会发现,不管是相册还是文件管理器中都没有这张图片,图片失踪了?

 

   按照以往的逻辑,当我们打开相机,按下开门,在没有任何“外因”的阻止下,照片理当应该存储在SDCard中或内部存储中,可是为什么通过调用系统相机 后拍的相片却怎么也通过相册看不到呢?但是当连接上电脑浏览手机中的文件时,你会发现刚才拍的相片就在那里,然后你重启手机,浏览相册,发现刚才拍照的相 片神奇的出现了,如果有同学遇到了相同的问题,那么恭喜你,看这篇文章就看对头了。

 

   是这个样子的,Android原生的系统相机,在拍照的结束后还做了一件事情,就是“扫描”,他会发出一个广播,来通知硬件区扫描自己,说白了就是刷 新,用过电脑的同学都明白刷新是个什么概念,当你浏览电脑文件夹时,刷新后会显示刚才操作的结果,比如图标的变化等,从“面”上讲,这是一个相同的概念。 当然,“扫描”这件事,在android系统初始化的时候也会执行,比如开机、重启,这就是为什么,当我重启手机后,相册就能显示这张照片的原因了,难道 说,每次为了能在相册中显示新拍的相片,都要重启手机吗???那老板还不K.O 我?

 

  手动扫描:

 

  但是调用系统相机就不一样了,刷新设备是要开发人员自己手动完成的(到目前为,我没有找到自动刷新的方式。。。)。

 

  看以下代码:

 

  

 

 1 private void doCamrea() {
 2         Intent capturePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 3         String picPartName = makePicName();
 4         String fullFileName = CurrentParameter.PATH + picPartName;
 5         // 因为有的手机在接收相机Intent返回的值data时,收不到,所以在这里发送一个uri,让其相机在内部进行一个本地存储的操作
 6         if (CurrentUtils.isHasSdcard()) {
 7             capturePic.putExtra(MediaStore.EXTRA_OUTPUT,
 8                     Uri.fromFile(new File(CurrentParameter.PATH, picPartName)));
 9             // 将这一张相片的名字保存在共享文件中,让scan在扫描的时候,再从这个共享文件中获取此相片名
10             SharedPreferences sd = this.getSharedPreferences(
11                     CurrentParameter.SHARED_FILE_NAME, 3);
12             Editor ed = sd.edit();
13             ed.putString("fullName", fullFileName);
14             ed.commit();
15         }
16 
17         startActivityForResult(capturePic, CurrentParameter.CAPTURE_PIC);
18     }

 


 

上面只是一个调用启动系统相机意图的方法,并没有看到过关于“扫描”的,因为并不是在这里处理,这是一个 startActivityForResult,有经验的同学都知道是什么意思了吧,结果当然是要放到Activity的回调方法 onActivityResult(……)中去做啦,但以上代码有个关键之处,请看第10行,没错,我开了一个SharedPreferences(共享 文件),并且将刚才拍照的相片的:绝对路径+文件名 保存在了这个共享文件中。暂且记住这一点,我们往下看:

 

onActivityResult方法:

 

 1 /**
 2  * 接受返回结果,并做业务处理
 3 */
 4     @Override
 5     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 6         // TODO Auto-generated method stub
 7         super.onActivityResult(requestCode, resultCode, data);
 8 
 9         switch (requestCode) {
10         // 相册
11         case CurrentParameter.LOCAL_PIC:
12             if (resultCode != RESULT_OK || data == null)
13                 return;
14             Uri thisUri = data.getData();
15             Log.i("----SysLog", thisUri.toString());
16             picPath = getPicPath(thisUri);
17             if (picPath != null) {
18                 // 设置缩略图,大小为30px
19                 previewBitmap = PictureUtils.getPreview(this, picPath,
20                         CurrentParameter.PREVIEW_PX);
21                 picPathMap.put(marker, picPath);
22             }
23             break;
24         // 相机
25         case CurrentParameter.CAPTURE_PIC:
26             if (resultCode == RESULT_OK || (Build.MODEL.toString().equals("D539") && resultCode == 0)/*酷派D539*/) {
27                 // 刷新后,相册就能显示这张图片了。
28                 SharedPreferences sd = PhotoMessageEditActivity.this
29                         .getSharedPreferences(
30                                 CurrentParameter.SHARED_FILE_NAME, 3);
31                 picPath = sd.getString("fullName", "is-fuck-null");
32                 CurrentUtils.scanOneFile(this,picPath);
33 
34                 previewBitmap = PictureUtils.getPreview(this, picPath,
35                         CurrentParameter.PREVIEW_PX);
36                 picPathMap.put(marker, picPath);
37             }
38             break;
39 .
40 .
41 .
42 .

 

没错,这段代码我只是为大家展示一部分,因为其他的都无关紧要。从24行开始,调用系统相机后并返回结果

 

26行,进行resultCode的判断,如果这个值是-1,说明你拍完照点击的是完成按钮,也就是说你“确定”要把这张图片保存并显示,|| 后面是对酷派D539的适配,比较变态人家用的是0~~~~,废话不多说接着看。

 

28行,开始从上面第一段代码创建的共享文件中取出当先相片的绝对名称,32行,调用scanOneFile方法,进行文件扫描。到此为止整个处理过程结束,那么最后一段代码,scanOneFile方法的是如何实现扫描的。

 

 1 /**
 2  * 扫描
 3  * 
 4  * @param filePath
 5 */
 6     public static void scanOneFile(Context context, String filePath) {
 7         // TODO Auto-generated method stub
 8         if (filePath != null && "is-fuck-null".equals(filePath))
 9             return;
10         Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
11         Uri uri = Uri.parse("file://" + filePath);
12         intent.setData(uri);
13         context.sendBroadcast(intent);
14 
15     }

 

接收的参数,第一个是context对象,对二个是这张图片的全路径名称,没错是发送一个广播,data为一个uri对象,通过这个uri对象,系统会精确扫描这一文件,让它无处可藏,原形毕露。

 

有的同学可能会问,为什么要用共享文件来存储文件名呢?第一段代码和第二段代码不是在一个类中吗?用一个全局变量不就可以了吗?这个问题留给你们自己去实验吧。

 

 

转载请标明出处,如果有更好的解决方式,希望大家共同探讨。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏