2015年8月12日星期三

获取 本地图片 路径

android 4.4之前可以用这种方法获取图片的绝对路径
[java] view plaincopy
  1. String[] proj = { MediaStore.Images.Media.DATA };  
  2.     cursor = activity.managedQuery(uri, proj, nullnullnull);  
  3.     column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);  
  4.     cursor.moveToFirst();  
  5. catch (Exception e) {  
  6.     return null;  
  7. }  
  8. if (column_index == -1) {  
  9.     return null;  
  10. }  
  11. String path = cursor.getString(column_index);  
但是android4.4之后,用这种方法获取到到path为null。
这时候就需要根据系统版本来使用不同方法处理了。

Android系统中可以通过如下方法判断版本:
[java] view plaincopy
  1. Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT  

所以,我们正确的获取选择选择图片的绝对路径的方法应该这样写:
[java] view plaincopy
  1. import android.content.Context;  
  2. import android.database.Cursor;  
  3. import android.net.Uri;  
  4. import android.os.Build;  
  5. import android.provider.DocumentsContract;  
  6. import android.provider.MediaStore;  
  7. import android.util.Log;  
  8.   
  9. /** 
  10.  * Created by nicholas on 1/18/15. 
  11.  */  
  12. public class FileUtil {  
  13.   
  14.     Uri contentUri;  
  15.   
  16.     boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;  
  17.   
  18.     public FileUtil() {  
  19.   
  20.     }  
  21.   
  22.     public void setContentUri(Uri uri) {  
  23.         this.contentUri = uri;  
  24.     }  
  25.   
  26.     public Uri getContentUri() {  
  27.         return contentUri;  
  28.     }  
  29.   
  30.     public String getPath(Context context, Uri uri) {  
  31.         Log.v(" File -",  
  32.                 "Authority: " + uri.getAuthority() +  
  33.                         ", Fragment: " + uri.getFragment() +  
  34.                         ", Port: " + uri.getPort() +  
  35.                         ", Query: " + uri.getQuery() +  
  36.                         ", Scheme: " + uri.getScheme() +  
  37.                         ", Host: " + uri.getHost() +  
  38.                         ", Segments: " + uri.getPathSegments().toString()  
  39.         );  
  40.   
  41.         if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {  
  42.             return getRealPathFromUriKitKatPlus(context, uri);  
  43.         } else {  
  44.             return getRealPathFromUriMinusKitKat(context, uri);  
  45.         }  
  46.     }  
  47.   
  48.   
  49.   
  50.     private String getRealPathFromUriKitKatPlus(Context context, Uri uri) {  
  51.         Cursor cursor = null;  
  52.         String wholeId = DocumentsContract.getDocumentId(uri);  
  53.         String id = wholeId.split(":")[1];  
  54.   
  55.         try {  
  56.             String proj[] = {MediaStore.Images.Media.DATA};  
  57.             String sel = MediaStore.Images.Media._ID + "=?";  
  58.             cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,  
  59.                     proj, sel, new String[]{id}, null);  
  60.             int column_index = cursor.getColumnIndexOrThrow(proj[0]);  
  61.             String filePath = "";  
  62.             if (cursor.moveToFirst()){  
  63.                 filePath = cursor.getString(column_index);  
  64.             }  
  65.             cursor.close();  
  66.             return filePath;  
  67.         } catch (Exception e) {  
  68.             e.printStackTrace();  
  69.             return "";  
  70.         }  
  71.   
  72.     }  
  73.   
  74.     private String getRealPathFromUriMinusKitKat(Context context, Uri uri) {  
  75.         String[] filePathColumn = {MediaStore.Images.Media.DATA};  
  76.         Cursor cursor = context.getContentResolver().query(uri, filePathColumn, nullnullnull);  
  77.         cursor.moveToFirst();  
  78.         int columnIndex = cursor.getColumnIndex(filePathColumn[0]);  
  79.         String picturePath = cursor.getString(columnIndex);  
  80.         cursor.close();  
  81.         System.out.println(picturePath);  
  82.         return picturePath;  
  83.     }  
  84. }  

2015年8月11日星期二

浏览器中 打开应用

今天老大给我提了一个需求叫我调研一下,他已经测试了IOS平台上是可以的,需求很简单就是在系统浏览器中通过输入一个uri就可以打开相应的app。
比如你在IOS中的系统浏览器中输入:tel://123,就会跳到拨打电话页面而且拨打号码是123,像这样的命令,老大他用了小米手机测试了一下,发现可以的,所以他就以为Android的也是可以的,但是当我用三星和htc手机测试发现不行,这时候老大就纠结了,但是我个人认为,我们都知道小米手机是模仿IOS的,没想到模仿的这么想。所以老大就叫我去调研,我查阅了资料之后,找到了解决办法如下
先上一份代码,经楼主验证是绝对可以用的而且也比较清晰的代码!(ps:还是先剧透下吧,第三方大部分浏览器无法成功。)
点击浏览器中的URL链接,启动特定的App。
首先做成HTML的页面,页面内容格式如下:
<a href="[scheme]://[host]/[path]?[query]">启动应用程序</a> 
这一句就可以了。

各个项目含义如下所示:
scheme:判别启动的App。 ※详细后述
host:适当记述
path:传值时必须的key     ※没有也可以
query:获取值的Key和Value  ※没有也可以

作为测试好好写了一下,如下:
<a href="myapp://jp.app/openwith?name=zhangsan&age=26">启动应用程序</a>  

接下来是Android端。
首先在AndroidManifest.xml的MAIN Activity下追加以下内容。(启动Activity时给予)
※必须添加项
<intent-filter>  
    <action android:name="android.intent.action.VIEW"/>  
    <category android:name="android.intent.category.DEFAULT" />  
    <category android:name="android.intent.category.BROWSABLE" />  
    <data android:scheme="myapp" android:host="jp.app" android:pathPrefix="/openwith"/>  
</intent-filter>
HTML记述的内容加入<data …/>。
其中必须的内容仅scheme,没有其他内容app也能启动。

※注意事项:intent-filter的内容【android.intent.action.MAIN】和 【android.intent.category.LAUNCHER】这2个,不能与这次追加的内容混合。
                 所以,如果加入了同一个Activity,请按以下这样做,否则会导致应用图标在桌面消失等问题。
复制代码
<intent-filter>  
    <action android:name="android.intent.action.MAIN"/>  
    <category android:name="android.intent.category.LAUNCHER" />  
</intent-filter>  
<intent-filter>  
    <action android:name="android.intent.action.VIEW"/>  
    <category android:name="android.intent.category.DEFAULT" />  
    <category android:name="android.intent.category.BROWSABLE" />  
    <data android:scheme="myapp" android:host="jp.app" android:pathPrefix="/openwith"/>  
</intent-filter> 
复制代码
这样的话,没有问题。

接下来在Activity中需要取值的地方添加以下代码,我是直接写在OnCreate函数里的:

Intent i_getvalue = getIntent();
String action = i_getvalue.getAction();
 
if(Intent.ACTION_VIEW.equals(action)){
    Uri uri = i_getvalue.getData();
    if(uri != null){
        String name = uri.getQueryParameter("name");
        String age= uri.getQueryParameter("age");
    }
}

这样就能获取到URL传递过来的值了。
——————————————————————————————————我是分割线————————————————————————————————————

代码copy完了,是不是很惊奇的发现用浏览器输入
myapp://jp.app/openwith?name=zhangsan&age=26
是不是404,打不开?
楼主你这不是骗人么!楼主你个混蛋啊。
客官,稍安勿躁啊,你看看你用的浏览器是什么?UC,猎豹,欧朋?放弃吧,试试系统自带浏览器或者谷歌浏览器吧。肯定能成功的,不能成功的话再来坑我。哈哈。

——————————————————————————————————我是分割线————————————————————————————————————
突然觉得好悲哀,好不容易get了这个技能,却不能被第三方浏览器使用。在这个android浏览器大部分被第三方占据着的时代不得不说是个悲剧啊。

接下来还是说说为什么第三方浏览器不能成功吧。首先,我发现的是UC浏览器,如果你使用了自己的scheme,而不是http的话,uc会默认在你的scheme前面添加http://。这太坑爹了。其他浏览器没看是不是同样的情况。发现这个问题后我就试着把自己的scheme换成http。然后满怀期待的又跑了一遍,结果还是坑爹了。所以我想会不会是第三方浏览器对url做了处理。到这里,我也无可奈何了。我测试了UC,猎豹,欧朋,这3个都不支持。系统自带的和谷歌浏览器是支持的。

最后再补充个线索吧,在浏览器里搜索百度应用。进了他们的页面后,他们是可以实现在各种浏览器启动已经安装好的本地app的。看到这个后我就看了下他们页面的源码。
在这里他们页面添加了个data-sentintent的标签,看到这里,应该能确定第三方浏览器应该是默认都不支持发intent的,只能自己起一个。根据前端说,这个标签应该是自定义的。我们前端看源码的时候发现是这样的
所以最后的结果应该是百度这边是起了个端口,然后在应用里启用了一个服务,来监听这个端口,来获取这个intent。大概就这个思路了。不过楼主没有实际去操作。项目时间紧,太麻烦了。对了,百度这个是有集成他们inapp这个sdk的。
版权声明:本文为博主原创文章,未经博主允许不得转载。

2015年8月7日星期五

获取视频的图片

Bitmap bitmap = null;bitmap = ThumbnailUtils.createVideoThumbnail(data.get(position).sdcardPath, MediaStore.Images.Thumbnails.MICRO_KIND);

2015年8月6日星期四

获取 视频的图片

public class MoviImageThumbActivity extends AppCompatActivity {
    private ImageView imageThumbnail;    private ImageView videoThumbnail;
    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.mpchoise_activity);
        findViewById(R.id.picturemedia_button).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent camera = new Intent();                camera.setType("vedio/*");                startActivityForResult(camera, 0x11);            }        });        imageThumbnail = (ImageView) findViewById(R.id.image_thumbnail);        videoThumbnail = (ImageView) findViewById(R.id.video_thumbnail);
        String imagePath = Environment.getExternalStorageDirectory()                .getAbsolutePath()                + File.separator                + "DCIM/Camera"                + File.separator                + "20140816_082345.jpg";
        String videoPath = Environment.getExternalStorageDirectory()                .getAbsolutePath()                + File.separator                + "DCIM/Camera"                + File.separator                + "20141015_150234.mp4";
        imageThumbnail.setImageBitmap(getImageThumbnail(imagePath, 200, 200));        videoThumbnail.setImageBitmap(getVideoThumbnail(videoPath, 200, 200,
                MediaStore.Images.Thumbnails.MICRO_KIND));    }
    /**     * 根据指定的图像路径和大小来获取缩略图     * 此方法有两点好处:     *     1. 使用较小的内存空间,第一次获取的bitmap实际上为null,只是为了读取宽度和高度,     *        第二次读取的bitmap是根据比例压缩过的图像,第三次读取的bitmap是所要的缩略图。     *     2. 缩略图对于原图像来讲没有拉伸,这里使用了2.2版本的新工具ThumbnailUtils,使     *        用这个工具生成的图像不会被拉伸。     * @param imagePath 图像的路径     * @param width 指定输出图像的宽度     * @param height 指定输出图像的高度     * @return 生成的缩略图     */    private Bitmap getImageThumbnail(String imagePath, int width, int height) {        Bitmap bitmap = null;        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        // 获取这个图片的宽和高,注意此处的bitmapnull        bitmap = BitmapFactory.decodeFile(imagePath, options);        options.inJustDecodeBounds = false; // 设为 false        // 计算缩放比        int h = options.outHeight;        int w = options.outWidth;        int beWidth = w / width;        int beHeight = h / height;        int be = 1;        if (beWidth < beHeight) {            be = beWidth;        } else {            be = beHeight;        }        if (be <= 0) {            be = 1;        }        options.inSampleSize = be;        // 重新读入图片,读取缩放后的bitmap,注意这次要把options.inJustDecodeBounds 设为 false        bitmap = BitmapFactory.decodeFile(imagePath, options);        // 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);        return bitmap;    }
    /**     * 获取视频的缩略图     * 先通过ThumbnailUtils来创建一个视频的缩略图,然后再利用ThumbnailUtils来生成指定大小的缩略图。     * 如果想要的缩略图的宽和高都小于MICRO_KIND,则类型要使用MICRO_KIND作为kind的值,这样会节省内存。     * @param videoPath 视频的路径     * @param width 指定输出视频缩略图的宽度     * @param height 指定输出视频缩略图的高度度     * @param kind 参照MediaStore.Images.Thumbnails类中的常量MINI_KINDMICRO_KIND     *            其中,MINI_KIND: 512 x 384MICRO_KIND: 96 x 96     * @return 指定大小的视频缩略图     */    private Bitmap getVideoThumbnail(String videoPath, int width, int height,
                                     int kind) {        Bitmap bitmap = null;        // 获取视频的缩略图        bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);        return bitmap;    }}








<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent">
    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="图片缩略图" />
    <ImageView        android:id="@+id/image_thumbnail"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />
    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="视频缩略图" />
    <ImageView        android:id="@+id/video_thumbnail"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />
    <Button        android:id="@+id/picturemedia_button"        android:text="systemPictureAndMedia"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />
</LinearLayout>