Android多媒体运用 一

通知

使用Android通知功能步骤:
  1. 通过ContextgetSystemService(Context.NOTIFITICATION_SERVICE)方法,获取一个NotificationManager来对通知进行管理。
  2. 使用Builder建造者模式创建Notification对象(使用support-v4库中的NotificationCompat类)。
  3. 调用NofiticationManagernotify()(参数:id;Notification对象)方法让通知显示出来。
MainActivity代码:
//布局用一个button和一个ImageViewpublic class MainActivity extends AppCompatActivity {    @BindView(R.id.notification)    Button button;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);    }    @OnClick(R.id.notification)    public void onClick(View view){        switch (view.getId()){            case R.id.notification:                Intent intent = new Intent(this,NotificationActivity.class);                PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);                NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);                Notification notification = new NotificationCompat.Builder(this)                        .setContentTitle("Notification")       //指定通知的标题内容                        .setContentText("快来点我")             //指定通知的内容                        .setWhen(System.currentTimeMillis())   //指定通知被创建的时间                        .setSmallIcon(R.mipmap.ic_launcher)    //设置通知的小图标                        .setContentIntent(pendingIntent)       //设置延时Intent                        .setAutoCancel(true)                   //设置点击通知后会自动取消                        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))     //设置一段音频                        .setVibrate(new long[]{0,1000,1000,1000})   //设置震动(参数:1、表示静止的时长,2、表示震动时长,以此往复)【此处表示通知到来立刻震动一秒,然后静止一秒继续震动一秒】                        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))    //设置通知的大图标                        .setLights(Color.RED,1000,1000)        //设置前置LED灯//                        .setDefaults(NotificationCompat.DEFAULT_ALL) 设置直接使用默认的效果                        .build();                notificationManager.notify(1,notification);    //让通知显示.参数:1、id,2、Notification对象                break;            default:                break;        }    }

当然按上述步骤创建出来的通知是最简单的,点击通知也不会进行任何跳转,而要实现跳转可以参考上面的代码。先使用PendingIntent又称延时性Intent,然后在builder中用.setContentIntent(pendingIntent)设置。

更详细可以参考Android Developer

摄像头和相册

摄像头调用和图片显示步骤:

  1. 设置布局,绑定监听
  2. 创建一个File对象用于存储图片
  3. 判断系统版本,设置uri
  4. new Intent("android.media.action.IMAGE_CAPTURE")Intent带参uri,通过StartActivityForResult(Intent,1)启动
  5. 重写onActivityResult() ,更新UI

代码:

//MainActivitypublic class MainActivity extends AppCompatActivity {    public static final int TAKE_PHOTO = 1;    public static final int CHOOSE_PHOTO = 0;    @BindView(R.id.picture)    ImageView picture;    private Uri uri;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);    }    @OnClick({R.id.take_photo,R.id.choose_photo})    public void OnClick(View V){        switch (V.getId()){            case  R.id.take_photo://                创建File对象,用于缓存拍照后的图片,图片名为"output_image.jpg"                File outputImage = new File(getExternalCacheDir(),                        "output_image.jpg");                try {                    if (outputImage.exists()){                        outputImage.delete();                    }                    outputImage.createNewFile();                } catch (IOException e) {                    e.printStackTrace();                }                if(Build.VERSION.SDK_INT >= 24){//判断Android的版本是否大于7.0                    uri = FileProvider.getUriForFile(MainActivity.this,                            "com.amap.cameraalbumtest.fileprovider",                            outputImage);                }else{//                    此方法将File对象转化为一个Uri对象,标识图片的真实路径                    uri = Uri.fromFile(outputImage);                }                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");//                指定图片输出地址                intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);                startActivityForResult(intent , TAKE_PHOTO);                break;            case R.id.choose_photo://                动态权限申请                if (ContextCompat.checkSelfPermission(MainActivity.this,                        Manifest.permission.WRITE_EXTERNAL_STORAGE)                        != PackageManager.PERMISSION_GRANTED){                    ActivityCompat.requestPermissions(MainActivity.this,                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);                }else{                    openAlbum();                }                break;            default:                break;        }    }//  打开相册    private void openAlbum() {        Intent intent = new Intent("android.intent.action.GET_CONTENT");        intent.setType("image/*");        startActivityForResult(intent,CHOOSE_PHOTO);    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        switch (requestCode){            case TAKE_PHOTO:                if (resultCode == RESULT_OK){                    try {                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().                                openInputStream(uri));                        picture.setImageBitmap(bitmap);                    } catch (FileNotFoundException e) {                        e.printStackTrace();                    }                }                break;            case CHOOSE_PHOTO:                if (resultCode == RESULT_OK){                    if (Build.VERSION.SDK_INT>= 19){//                        4.4以上版本使用这个方法                        handleImageOnKitKat(data);                    }else{//                        4.4以下使用这个                        handleImageBeforeKitBat(data);                    }                }                break;            default:                break;        }    }    @TargetApi(19)    private void handleImageOnKitKat(Intent data) {        String imagePath = null;        Uri uri = data.getData();        if (DocumentsContract.isDocumentUri(this,uri)){//            如果是document类型的Uri,则通过document id 处理            String docId = DocumentsContract.getDocumentId(uri);            if ("com.android.providers.media.documents".equals(uri.getAuthority())){                String id = docId.split(":")[1];//解析出数字格式的id                String selection = MediaStore.Images.Media._ID + "=" + id;                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);        }else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())){            Uri contentUri = ContentUris.withAppendedId(Uri.parse("content:" +                    "//downloads/public_downloads"),Long.valueOf(docId));            imagePath = getImagePath(contentUri,null);        }        }else if ("content".equalsIgnoreCase(uri.getScheme())){//            如果是content类型的Uri,则使用普通方式处理            imagePath = getImagePath(uri,null);        }else if ("file".equalsIgnoreCase(uri.getScheme())){            //如果是file类型的Uri,直接获取图片路径即可            imagePath = uri.getPath();        }        displayImage(imagePath);    }    private void handleImageBeforeKitBat(Intent data) {        Uri uri = data.getData();        String imagePath = getImagePath(uri,null);        displayImage(imagePath);    }    private String getImagePath(Uri uri, String selection) {        String path = null;//        通过Uri和selection来获取真实的图片路径        Cursor cursor = getContentResolver().query(uri,null,selection,null,null);        if (cursor != null){            if (cursor.moveToFirst()){                path = cursor.getString(cursor.getColumnIndex(                        MediaStore.Images.Media.DATA));            }            cursor.close();        }        return path;    }    private void displayImage(String imagePath) {        if (imagePath != null){            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);            picture.setImageBitmap(bitmap);        }else{            Toast.makeText(this, "failed to get image !", Toast.LENGTH_SHORT).show();        }    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        switch (requestCode){            case 1:                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){                    openAlbum();                }else{                    Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();                }                break;            default:                break;        }    }}

我的这段代码中还有调用相册的部分,这些下面再记录。

摄像头代码中的注意点:
  • getExternalCacheDir() 表示存放在手机SD卡的应用关联缓存目录下。因为Android6.0后,读写SD卡操作被列为危险操作,需要运行时权限处理,而使用应用相关联目录则可以跳过此步。
  • if(Build.VERSION.SDK_INT >= 24)判断系统版本。
    如果低于7.0就使用uri = Uri.fromFile(outputImage)
    否则就调用FileProvider.getUriForFile(MainActivity.this, "com.amap.cameraalbumtest.fileprovider",outputImage)
    因为7.0开始,直接使用本地真实路径是不安全的,会抛FileUriExposedException异常。而FileProvider则是一种特殊的内容提供器,它使用了和内容提供器类似的机制来对数据进行保护,可以选择性地将Uri共享给外部,从而提高安全性。

AndroidManifest和file_paths.xml代码:

...                                                                            //注册内容提供器                                ...

注意:android:authorities="com.amap.cameraalbumtest.fileprovider"必须与之前FileProvider.getUriForFile()第二个参数一致。

//res下建一个新的xml文件夹,再建file_paths.xml<?xml version="1.0" encoding="utf-8"?>    

注意:用来指定Uri共享的,name可以随便填,path表示共享的具体路径,为空表示整个SD卡进行共享

调用相册步骤:

  1. 绑定监听
  2. 运行时权限——读取SD卡
  3. 设置intent,启动相册
  4. onActivityResult()方法,更新UI

具体代码在上面的代码中。

注意:

  • Android系统于4.4开始,选中图片就不会再返回真实的Uri了,而是一个封装后了的Uri
  • handleImageOnKitKat()方法中的逻辑就是基于封装后了的Uri的。
    判断uri是否是document类型,是的话就取出document id进行处理,如果不是,就是用普通方法getImagePath(uri,null)。另外,如果Uri的authority是media格式的话,document id 还需要再进行一次解析,通过字符串分割split()方法取出后半部分才能得到真正的数字id。取出id用于构建新的Uri和条件语句,然后把这些值作为参数传入getImagePath(),就可以获得图片真实的地址了。

此处demo出自《Android 第一行代码》

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)代码分析 私有析构函数
  3. Android通话和数据传输过程分析
  4. Android第六个功能:XmlPullParser解析XML文件
  5. Android(安卓)Layout Binder(在线将XML中View find出来,生成java代
  6. Android(安卓)Toast 总结
  7. android JNI调用 - char*与jstring相互转换
  8. Android应用自动更新功能的实现!!!软件更新,自动下载,安装
  9. android文件上传示例分享(android图片上传)

随机推荐

  1. 解决flutter Android(安卓)license statu
  2. Android包管理机制(一)PackageInstaller的
  3. 《当程序员的那些快乐日子》(十七)Iphone
  4. Arcgis Runtime sdk for android 授权
  5. android viewPager滑动速度设置
  6. Android(安卓)wifi密码的位置
  7. 腾讯微博Android客户端开发——自动获取
  8. 开源一款android 偷拍 app【静拍】豌豆荚
  9. Android实现甘特图(GanttChart)效果
  10. android手机定位