Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/203.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将图像添加到媒体库-Android_Java_Android_Image_Android Mediascanner - Fatal编程技术网

Java 将图像添加到媒体库-Android

Java 将图像添加到媒体库-Android,java,android,image,android-mediascanner,Java,Android,Image,Android Mediascanner,我正在尝试向图库中添加新图像。我通过一个意图选择一个已经存在的图像,然后调整大小并压缩它 然后存储生成的位图: public static File compressAndSaveImage(Context ctx, Uri imageUri) throws FileNotFoundException { File file = null; if (imageUri != null) { ContextWrapper cw = new ContextWrappe

我正在尝试向图库中添加新图像。我通过一个意图选择一个已经存在的图像,然后调整大小并压缩它

然后存储生成的位图:

public static File compressAndSaveImage(Context ctx, Uri imageUri) throws FileNotFoundException {
    File file = null;

    if (imageUri != null) {
        ContextWrapper cw = new ContextWrapper(ctx);
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        file = new File(directory, imageUri.getLastPathSegment());
        System.out.println("storing to " + file);

        InputStream input = ctx.getContentResolver().openInputStream(imageUri);
        Bitmap b = ImageManager.resize(BitmapFactory.decodeStream(input),
                ctx.getResources().getDimension(R.dimen.player_thumb_w),
                ctx.getResources().getDimension(R.dimen.player_thumb_h));

        FileOutputStream fos = new FileOutputStream(file);
        if (b.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
            System.out.println("Compression success");// bmp is your Bitmap instance
        }
        addPictureToGallery(ctx, file);
    }
    return file;
}
但是,当我尝试将图像添加到库中时,我没有收到任何错误,图像也没有添加。我尝试了以下两种方法:

private static void addPictureToGallery(Context ctx, File filepath) {
//        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
//        System.out.println("Publish: " + filepath.exists());
//        System.out.println("Publish: " + filepath.getAbsolutePath());
//        Uri contentUri = Uri.fromFile(filepath);
//        mediaScanIntent.setData(contentUri);
//        ctx.sendBroadcast(mediaScanIntent);
    MediaScannerConnection.scanFile(
            ctx,
            new String[]{filepath.getAbsolutePath()},
            null,
            new MediaScannerConnection.OnScanCompletedListener() {
                @Override
                public void onScanCompleted(String path, Uri uri) {
                    Log.w("mydebug", "file " + path + " was scanned successfully: " + uri);
                }
            });
    }
}
回调将打印以下行:

file /data/data/test.myapps.appname/app_imageDir/6045564126748266738 was scanned successfully: content://media/external/file/7838

我遗漏了什么?

我想把这作为一个评论,因为我没有时间真正深入了解事情的细节,但它显然太长了。尝试类似的方法(我使用它将位图存储到库中)。请注意,除了扫描图像之外,您似乎什么都没做。现在,您似乎正在将文件存储到内部存储器中,而不是手机内容(多媒体资料)

假设我们是从扩展活动的ActivityA.class运行此操作

 /**
 * Will save our card (currently set as a bitmap) as a jpeg and save it into our devices
 * native photo gallery. Unfortunately, the default method for this will add the image to the bottom
 * of the gallery by default, that is no good. This more complex method that utilizes Android's
 * native methods will allow us to store the bitmap at the top of the gallery by setting it's
 * meta data to today's date.
 */
public class SaveBitmapToDevice extends AsyncTask<Bitmap, Void, String>{

    private final ShareType type;

    public SaveBitmapToDevice(ShareType type){
        this.type = type;
    }

    @Override
    protected String doInBackground(Bitmap... cards) {
        return insertImageIntoGallery(getContentResolver(), cards[0], getString(R.string.card_gallery_title),
                getString(R.string.card_gallery_label));
    }

    /**
     * A copy of the Android internals insertImage method, this method populates the
     * meta data with DATE_ADDED and DATE_TAKEN. This fixes a common problem where media
     * that is inserted manually gets saved at the end of the gallery (because date is not populated).
     * @see android.provider.MediaStore.Images.Media#insertImage(android.content.ContentResolver, Bitmap, String, String).
     * If the MediaStore not available, we will redirect the file to our alternative source, the SD card.
     */
    public String insertImageIntoGallery(ContentResolver cr, Bitmap source, String title, String description) {

        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, title);
        values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
        values.put(MediaStore.Images.Media.DESCRIPTION, description);
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        // Add the date meta data to ensure the image is added at the front of the gallery
        values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());

        Uri url = null;
        String stringUrl = null;    /* value to be returned */

        try {
            url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

            if (source != null) {
                OutputStream imageOut = cr.openOutputStream(url);
                try {
                    source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
                } finally {
                    imageOut.close();
                }

                long id = ContentUris.parseId(url);
                // Wait until MINI_KIND thumbnail is generated.
                Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(cr, id, MediaStore.Images.Thumbnails.MINI_KIND, null);
                // This is for backward compatibility.
                storeThumbnail(cr, miniThumb, id, 50F, 50F, MediaStore.Images.Thumbnails.MICRO_KIND);
            } else {
                cr.delete(url, null, null);
                return storeToAlternateSd(source, title);
                // url = null;
            }
        } catch (Exception e) {
            if (url != null) {
                cr.delete(url, null, null);
                return storeToAlternateSd(source, title);
                // url = null;
            }
        }

        savedOnSD = false;
        if (url != null) {
            stringUrl = url.toString();
        }

        return stringUrl;
    }

    /**
     * A copy of the Android internals StoreThumbnail method, it used with the insertImage to
     * populate the android.provider.MediaStore.Images.Media#insertImage with all the correct
     * meta data. The StoreThumbnail method is private so it must be duplicated here.
     * @see android.provider.MediaStore.Images.Media (StoreThumbnail private method).
     */
    private Bitmap storeThumbnail(
            ContentResolver cr,
            Bitmap source,
            long id,
            float width,
            float height,
            int kind) {

        // create the matrix to scale it
        Matrix matrix = new Matrix();

        float scaleX = width / source.getWidth();
        float scaleY = height / source.getHeight();

        matrix.setScale(scaleX, scaleY);

        Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
                source.getWidth(),
                source.getHeight(), matrix,
                true
        );

        ContentValues values = new ContentValues(4);
        values.put(MediaStore.Images.Thumbnails.KIND,kind);
        values.put(MediaStore.Images.Thumbnails.IMAGE_ID,(int)id);
        values.put(MediaStore.Images.Thumbnails.HEIGHT,thumb.getHeight());
        values.put(MediaStore.Images.Thumbnails.WIDTH,thumb.getWidth());

        Uri url = cr.insert(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, values);

        try {
            OutputStream thumbOut = cr.openOutputStream(url);
            thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
            thumbOut.close();
            return thumb;
        } catch (FileNotFoundException ex) {
            Log.e("IMAGE_COMPRESSION_ERROR", "File not found");
            ex.printStackTrace();
            return null;
        } catch (IOException ex) {
            Log.e("IMAGE_COMPRESSION_ERROR", "IO Exception");
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * If we have issues saving into our MediaStore, save it directly to our SD card. We can then interact with this file
     * directly, opposed to pulling from the MediaStore. Again, this is a backup method if things don't work out as we
     * would expect (seeing as most devices will have a MediaStore).
     *
     * @param src
     * @param title
     * @return - the file's path
     */
    private String storeToAlternateSd(Bitmap src, String title){
        if(src == null)
            return null;

        File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "My Cards");
        if(!sdCardDirectory.exists())
            sdCardDirectory.mkdir();

        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy - (hh.mm.a)", Locale.US);
        File image = new File(sdCardDirectory, title + " -- [" + sdf.format(new Date()) + "].jpg");
        try {
            FileOutputStream imageOut = new FileOutputStream(image);
            src.compress(Bitmap.CompressFormat.JPEG, 100, imageOut);
            imageOut.close();
            savedOnSD = true;
            return image.getAbsolutePath();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
            return null;
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    @Override
    public void onPostExecute(String url){
        if(url != null){
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            if(savedOnSD){
                File file = new File(url);
                if(file.exists())
                    intent.setDataAndType(Uri.fromFile(file), "image/jpeg");
                else
                    return;
            }
            else
                intent.setDataAndType(Uri.parse(url), "image/jpeg");

            ActivityA.this.startActivity(intent);
        }
        else
            Toast.makeText(ActivityA.this, getString(R.string.error_compressing), Toast.LENGTH_SHORT).show();
    }

}
public Uri addImageToGallery(ContentResolver cr, String imgType, File filepath) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, "player");
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "player");
    values.put(MediaStore.Images.Media.DESCRIPTION, "");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/" + imgType);
    values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
    values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
    values.put(MediaStore.Images.Media.DATA, filepath.toString());

    return cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
/**
*将我们的卡(当前设置为位图)保存为jpeg格式,并将其保存到我们的设备中
*本地照片库。不幸的是,默认方法会将图像添加到底部
*默认情况下,这是不好的。这个更复杂的方法利用了Android的
*本机方法将允许我们通过设置位图的
*到今天为止的元数据。
*/
公共类SaveBitmapToDevice扩展了异步任务{
私有最终共享类型;
公共SaveBitmapToDevice(共享类型){
this.type=type;
}
@凌驾
受保护的字符串背景(位图…卡){
返回insertImageIntoGallery(getContentResolver(),cards[0],getString(R.string.card\u gallery\u title),
getString(R.string.card_gallery_label));
}
/**
*作为Android内部构件插入图像方法的副本,此方法填充
*添加了DATE_和DATE_的元数据。这解决了媒体
*手动插入的数据将保存在库的末尾(因为日期未填充)。
*@请参阅android.provider.MediaStore.Images.Media#insertImage(android.content.ContentResolver,位图,字符串,字符串)。
*如果MediaStore不可用,我们将把文件重定向到我们的替代源SD卡。
*/
公共字符串插入图像库(ContentResolver cr、位图源、字符串标题、字符串描述){
ContentValues=新的ContentValues();
value.put(MediaStore.Images.Media.TITLE,TITLE);
value.put(MediaStore.Images.Media.DISPLAY\u名称、标题);
value.put(MediaStore.Images.Media.DESCRIPTION,DESCRIPTION);
value.put(MediaStore.Images.Media.MIME_类型,“image/jpeg”);
//添加日期元数据以确保图像添加到库的前面
value.put(添加了MediaStore.Images.Media.DATE_,System.currentTimeMillis());
value.put(MediaStore.Images.Media.DATE_take,System.currentTimeMillis());
uriurl=null;
字符串stringUrl=null;/*要返回的值*/
试一试{
url=cr.insert(MediaStore.Images.Media.EXTERNAL\u CONTENT\u URI,值);
如果(源!=null){
OutputStream imageOut=cr.openOutputStream(url);
试一试{
压缩(Bitmap.CompressFormat.JPEG,50,imageOut);
}最后{
imageOut.close();
}
long id=ContentUris.parseId(url);
//等待生成迷你缩略图。
位图miniThumb=MediaStore.Images.Thumbnails.getThumbnail(cr,id,MediaStore.Images.Thumbnails.MINI_-KIND,null);
//这是为了向后兼容。
storeThumbnail(cr、miniThumb、id、50F、50F、MediaStore.Images.thumbnail.MICRO_-KIND);
}否则{
cr.delete(url,null,null);
将存储返回到AlternateSD(来源、标题);
//url=null;
}
}捕获(例外e){
如果(url!=null){
cr.delete(url,null,null);
将存储返回到AlternateSD(来源、标题);
//url=null;
}
}
savedOnSD=false;
如果(url!=null){
stringUrl=url.toString();
}
返回字符串URL;
}
/**
*Android内部构件StoreThumbnail方法的一个副本,它与insertImage一起用于
*使用所有正确的
*元数据。StoreThumbnail方法是私有的,因此必须在此处复制。
*@请参阅android.provider.MediaStore.Images.Media(store缩略图私有方法)。
*/
私有位图存储缩略图(
内容解析程序cr,
位图源,
长id,
浮动宽度,
浮动高度,
国际货币基金组织(实物){
//创建矩阵以进行缩放
矩阵=新矩阵();
float scaleX=width/source.getWidth();
float scaleY=height/source.getHeight();
矩阵.setScale(scaleX,scaleY);
Bitmap thumb=Bitmap.createBitmap(源代码,0,0,
source.getWidth(),
source.getHeight(),矩阵,
真的
);
ContentValues=新的ContentValues(4);
value.put(MediaStore.Images.缩略图.KIND,KIND);
value.put(MediaStore.Images.Thumbnails.IMAGE\u ID,(int)ID);
value.put(MediaStore.Images.Thumbnails.HEIGHT,thumb.getHeight());
value.put(MediaStore.Images.Thumbnails.WIDTH,thumb.getWidth());
Uri url=cr.insert(MediaStore.Images.Thumbnails.EXTERNAL\u CONTENT\u Uri,值);
试一试{
OutputStream thumbOut=cr.openOutputStream(url);
thumb.compress(Bitmap.CompressFormat.JPEG,100,thumbOut);
thumbOut.close();
回拇指;
}捕获(FileNotFoundException ex){
Log.e(“图像压缩错误”,“文件”
private static File getImagesDirectory() {
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + IMAGE_DIR);//Environment.getExternalStorageDirectory()
    if (!file.mkdirs() && !file.isDirectory()) {
        Log.e("mkdir", "Directory not created");
    }
    return file;
}

public static File generateImagePath(String title, String imgType) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
    return new File(getImagesDirectory(), title + "_" + sdf.format(new Date()) + "." + imgType);
}
public boolean compressAndSaveImage(File file, Bitmap bitmap) {
    boolean result = false;
    try {
        FileOutputStream fos = new FileOutputStream(file);
        if (result = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
            Log.w("image manager", "Compression success");
        }
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
public Uri addImageToGallery(ContentResolver cr, String imgType, File filepath) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, "player");
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "player");
    values.put(MediaStore.Images.Media.DESCRIPTION, "");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/" + imgType);
    values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
    values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
    values.put(MediaStore.Images.Media.DATA, filepath.toString());

    return cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
public String addImageToGallery(ContentResolver cr, File filepath) {
    try {
       return MediaStore.Images.Media.insertImage(cr, filepath.toString(), 
                                                  filepath.getName(), "Image Description");
    } catch (FileNotFoundException e) {
       e.printStackTrace();
       return e.getMessage();
    }
}
fun addImageToGallery(b: Bitmap): Uri {
    val resolver = context.applicationContext.contentResolver

    val pictureCollection = MediaStore.Images.Media
        .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)

    val pictureDetails = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, "CurrentAlbumArt.png")
        put(MediaStore.Audio.Media.IS_PENDING, 1)
    }

    val pictureContentUri = resolver.insert(pictureCollection, pictureDetails)!!

    resolver.openFileDescriptor(pictureContentUri, "w", null).use { pfd ->
        try {
            pfd?.let {
                val fos = FileOutputStream(it.fileDescriptor)
                b.compress(Bitmap.CompressFormat.PNG, 100, fos)
                fos.close()
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    pictureDetails.clear()
    pictureDetails.put(MediaStore.Images.Media.IS_PENDING, 0)
    resolver.update(pictureContentUri, pictureDetails, null, null)
    return pictureContentUri
}