অ্যান্ড্রয়েড - গ্যালারীটিতে চিত্র সংরক্ষণ করুন


94

আমার কাছে চিত্রগুলির একটি গ্যালারী সহ একটি অ্যাপ্লিকেশন রয়েছে এবং আমি চাই যে ব্যবহারকারী এটির নিজের গ্যালারিতে সংরক্ষণ করতে পারেন। আমি এটির জন্য একক ভয়েস "সেভ" দিয়ে একটি বিকল্প মেনু তৈরি করেছি তবে সমস্যাটি ... আমি কীভাবে চিত্রটি গ্যালারিতে সংরক্ষণ করতে পারি?

এটি আমার কোড:

@Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle item selection
            switch (item.getItemId()) {
            case R.id.menuFinale:

                imgView.setDrawingCacheEnabled(true);
                Bitmap bitmap = imgView.getDrawingCache();
                File root = Environment.getExternalStorageDirectory();
                File file = new File(root.getAbsolutePath()+"/DCIM/Camera/img.jpg");
                try 
                {
                    file.createNewFile();
                    FileOutputStream ostream = new FileOutputStream(file);
                    bitmap.compress(CompressFormat.JPEG, 100, ostream);
                    ostream.close();
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }



                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }

আমি কোডের এই অংশ সম্পর্কে নিশ্চিত নই:

File root = Environment.getExternalStorageDirectory();
                File file = new File(root.getAbsolutePath()+"/DCIM/Camera/img.jpg");

গ্যালারিতে সংরক্ষণ করা কি সঠিক? দুর্ভাগ্যক্রমে কোডটি কাজ করে না :(


আপনি কি এই সমস্যাটি সমাধান করেছেন? আপনি দয়া করে আমার সাথে ভাগ করতে পারেন
user3233280

আমিও একই সমস্যা হচ্ছে না stackoverflow.com/questions/21951558/...
user3233280

আপনারা যারা ফাইলটি সংরক্ষণে এখনও সমস্যা নিয়ে আছেন তাদের পক্ষে এটি সম্ভবত কারণ আপনার ইউআরএলে "?", ":", "" "এবং" - "এগুলি সরান এবং এটির কাজ করা উচিত। এটি বিদেশী ডিভাইস এবং অ্যান্ড্রয়েড এমুলেটরগুলিতে একটি সাধারণ ত্রুটি। এটি সম্পর্কে এখানে আরও দেখুন: stackoverflow.com/questions/11394616/…
চ্যালেঞ্জএকসেপ্টেড

গৃহীত উত্তরটি 2019 সালে কিছুটা পুরানো। আমি একটি আপডেট উত্তর এখানে লিখেছি: stackoverflow.com/questions/36624756/…
বাও লেই

উত্তর:


171
MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);

পূর্বের কোডটি গ্যালারীটির শেষে চিত্রটি যুক্ত করবে। আপনি যদি তারিখটি পরিবর্তন করতে চান তাই এটি শুরুতে বা অন্য কোনও মেটাডেটাতে প্রদর্শিত হয়, নীচের কোডটি দেখুন (এসকে এর কর্টেসি , সমকির্টন ):

https://gist.github.com/samkirton/0242ba81d7ca00b475b9

/**
 * Android internals have been modified to store images in the media folder with 
 * the correct date meta data
 * @author samuelkirton
 */
public class CapturePhotoUtils {

    /**
     * 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(ContentResolver, Bitmap, String, String)
     */
    public static final String insertImage(ContentResolver cr, 
            Bitmap source, 
            String title, 
            String description) {

        ContentValues values = new ContentValues();
        values.put(Images.Media.TITLE, title);
        values.put(Images.Media.DISPLAY_NAME, title);
        values.put(Images.Media.DESCRIPTION, description);
        values.put(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(Images.Media.DATE_ADDED, System.currentTimeMillis());
        values.put(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 = Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null);
                // This is for backward compatibility.
                storeThumbnail(cr, miniThumb, id, 50F, 50F,Images.Thumbnails.MICRO_KIND);
            } else {
                cr.delete(url, null, null);
                url = null;
            }
        } catch (Exception e) {
            if (url != null) {
                cr.delete(url, null, null);
                url = null;
            }
        }

        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 static final 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(Images.Thumbnails.KIND,kind);
        values.put(Images.Thumbnails.IMAGE_ID,(int)id);
        values.put(Images.Thumbnails.HEIGHT,thumb.getHeight());
        values.put(Images.Thumbnails.WIDTH,thumb.getWidth());

        Uri url = cr.insert(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) {
            return null;
        } catch (IOException ex) {
            return null;
        }
    }
}

24
এটি চিত্রটি সংরক্ষণ করে, তবে গ্যালারীটির শেষ পর্যন্ত আপনি যখন ক্যামেরা সহ কোনও ছবি তোলেন তখন এটি শীর্ষে সংরক্ষণ করে। আমি কীভাবে চিত্রটিকে গ্যালারির শীর্ষে সংরক্ষণ করতে পারি?
এরিক.হিজক

19
নোট করুন যে আপনার অবশ্যই আপনার ম্যানিফেক্সট.এক্সএমএলে <ব্যবহারের অনুমতি অ্যান্ড্রয়েড: নাম = "android.permission.WRITE_EXTERNAL_STORAGE" /> যুক্ত করতে হবে।
কাইল Clegg

4
চিত্রগুলি গ্যালারির শীর্ষে সংরক্ষণ করা হয়নি কারণ অভ্যন্তরীণভাবে insertI छवि কোনও তারিখের মেটা ডেটা যোগ করে না। দয়া করে এই জিআইএসটি দেখুন: gist.github.com/0242ba81d7ca00b475b9.git এটি theোকান আইমেজ পদ্ধতির সঠিক কপি তবে এটি চিত্রটির গ্যালারির সামনের অংশে যুক্ত করা হয়েছে তা নিশ্চিত করার জন্য তারিখের মেটা তারিখ যুক্ত করে।
এস-কে '


4
ফাইল ফোল্ডারের নাম কীভাবে পরিবর্তন করবেন?
কোপি ব্রায়ান্ট

48

আসলে, আপনি যে কোনও জায়গায় আপনার ছবি সংরক্ষণ করতে পারেন। আপনি যদি কোনও সর্বজনীন জায়গায় সংরক্ষণ করতে চান, যাতে অন্য কোনও অ্যাপ্লিকেশন অ্যাক্সেস করতে পারে, এই কোডটি ব্যবহার করুন:

storageDir = new File(
    Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    ), 
    getAlbumName()
);

ছবিটি অ্যালবামে যায় না। এটি করতে, আপনাকে একটি স্ক্যান কল করতে হবে:

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

আপনি https://developer.android.com/training/camera/photobasics.html# টাস্ক গ্যালারী এ আরও তথ্য পেতে পারেন


4
এটি পুরোপুরি বাস্তবায়ন পরিবর্তন করার দরকার নেই এবং আমরা অ্যাপ্লিকেশনগুলির জন্য একটি কাস্টম ফোল্ডার তৈরি করতে পারি বলে এটি একটি দুর্দান্ত সহজ সমাধান।
হুগো গ্রেস

4
আপনি যখন কেবল একটি ফাইল স্ক্যান করতে পারেন তখন কোনও সম্প্রচার প্রেরণ করা অর্থের অপচয় হতে পারে: stackoverflow.com/a/5814533/43051
জারমি রেইনাউড

4
আপনি আসলে বিটম্যাপটি কোথায় পাস করবেন?
ড্যানিয়েল রেহানিয়ান

Environment.getExternalStoragePublicDirectoryএবং Intent.ACTION_MEDIA_SCANNER_SCAN_FILEএখনই
হতাশ

22

আমি মার্শমেলো এবং ললিপপে এই কাজটি করার জন্য অনেক কিছু চেষ্টা করেছি। অবশেষে আমি সংরক্ষিত ছবিটি ডিসিআইএম ফোল্ডারে সরিয়ে নিয়েছি (নতুন গুগল ফটো অ্যাপ্লিকেশনগুলি স্ক্যান চিত্রগুলি কেবলমাত্র এই ফোল্ডারের ভিতরে থাকলেই)

public static File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
         .format(System.currentTimeInMillis());
    File storageDir = new File(Environment
         .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/");
    if (!storageDir.exists())
        storageDir.mkdirs();
    File image = File.createTempFile(
            timeStamp,                   /* prefix */
            ".jpeg",                     /* suffix */
            storageDir                   /* directory */
    );
    return image;
}

এবং তারপরে ফাইলগুলি স্ক্যান করার জন্য মানক কোড যা আপনি গুগল বিকাশকারীদের সাইটেও খুঁজে পেতে পারেন ।

public static void addPicToGallery(Context context, String photoPath) {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(photoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    context.sendBroadcast(mediaScanIntent);
}

দয়া করে মনে রাখবেন যে এই ফোল্ডারটি বিশ্বের প্রতিটি ডিভাইসে উপস্থিত থাকতে পারে না এবং মার্শমেলো (এপিআই 23) থেকে শুরু করে, আপনাকে ব্যবহারকারীর কাছে ডাব্লুআরআইটি.ই.এস.আর।


4
গুগল ফটো সম্পর্কিত তথ্যের জন্য ধন্যবাদ।
জারমি রেয়নাড

4
এটি একটি এবং একমাত্র সমাধান যা ভালভাবে ব্যাখ্যা করছে। অন্য কেউ উল্লেখ করেনি যে ফাইলটি অবশ্যই ডিসিআইএম ফোল্ডারে থাকতে হবে। ধন্যবাদ!!!
প্রেরাগ মনোজলভিক

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)আমার জন্য কৌশলটি। ধন্যবাদ!
সালটান্পেপ্পর

4
getExternalStoragePublicDirectory()এখন এপিআই 29-এ অবজ্ঞা করা হয়েছে
Media

@ গ্রিগড়ু হ্যাঁ আপনি ঠিক রেবেকা, আমি উত্তরটি ASAP
ম্যাটপ্যাগে

13

এই কোর্স অনুসারে এটি করার সঠিক উপায়টি হ'ল:

Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    )

এটি আপনাকে গ্যালারী ডিরেক্টরিতে মূল পথ দেবে।


আমি এই নতুন কোড চেষ্টা করেছিলেন কিন্তু এটি ক্র্যাশ java.lang.NoSuchFieldError: android.os.Environment.DIRECTORY_PICTURES
খ্রিস্টান Giupponi

ঠিক আছে ধন্যবাদ, সুতরাং অ্যান্ড্রয়েড <2.2 দিয়ে গ্যালারীটিতে কোনও চিত্র দেওয়ার কোনও উপায় নেই?
খ্রিস্টান জিপ্পোনি

পারফেক্ট - সরাসরি অ্যান্ড্রয়েড বিকাশকারী ওয়েবসাইটের একটি লিঙ্ক। এটি কাজ করেছিল এবং এটি ছিল একটি সহজ সমাধান।
ফিল

4
ভাল উত্তর, তবে এখানে অন্যান্য উত্তরগুলি থেকে "গ্যালারীএডডপিক" পদ্ধতিটি যুক্ত করা আরও ভাল হবে, কারণ আপনি সাধারণত গ্যালারী অ্যাপ্লিকেশনটিকে নতুন ছবি লক্ষ্য করতে চান।
অ্যান্ড্রু কোস্টার

Environment.getExternalStoragePublicDirectoryইতিমধ্যে
অবচয় করা

11
private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

6

আপনি ক্যামেরা ফোল্ডারের ভিতরে একটি ডিরেক্টরি তৈরি করতে পারেন এবং চিত্রটি সংরক্ষণ করতে পারেন। এর পরে, আপনি কেবল আপনার স্ক্যান সম্পাদন করতে পারেন। এটি তাত্ক্ষণিকভাবে আপনার চিত্রটি গ্যালারীটিতে প্রদর্শন করবে।

String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()+ "/Camera/Your_Directory_Name";
File myDir = new File(root);
myDir.mkdirs();
String fname = "Image-" + image_name + ".png";
File file = new File(myDir, fname);
System.out.println(file.getAbsolutePath());
if (file.exists()) file.delete();
    Log.i("LOAD", root + fname);
    try {
        FileOutputStream out = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
        out.flush();
        out.close();
    } catch (Exception e) {
       e.printStackTrace();
    }

MediaScannerConnection.scanFile(context, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);

এই মানদণ্ডে এটি সেরা উত্তর
নূর হোসেন

1

আমি এখানে একই সন্দেহ নিয়ে এসেছি তবে অ্যান্ড্রয়েডের জন্য জামারিনের জন্য, আমি আমার ফাইলটি সংরক্ষণের পরে এই পদ্ধতিটি করার জন্য সিগ্রিস্ট উত্তরটি ব্যবহার করেছি:

private void UpdateGallery()
{
    Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
    Java.IO.File file = new Java.IO.File(_path);
    Android.Net.Uri contentUri = Android.Net.Uri.FromFile(file);
    mediaScanIntent.SetData(contentUri);
    Application.Context.SendBroadcast(mediaScanIntent);
} 

এবং এটি আমার সমস্যার সমাধান করে, থেক্স সিগ্রিস্ট। আমি এটি এখানে রেখেছি কারণ জামারিনের জন্য আমি এ সম্পর্কে কোনও উত্তরওয়ালা খুঁজে পাইনি এবং আমি আশা করি এটি অন্যান্য লোককে সহায়তা করতে পারে।


1

আমার ক্ষেত্রে উপরের সমাধানগুলি কাজ করে না আমাকে নিম্নলিখিতগুলি করতে হয়েছিল:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));

তার এর সত্যিই ভাল এই অপশনটি সম্পর্কে জানতে, কিন্তু দুর্ভাগ্যবশত অ্যান্ড্রয়েড 6 কিছু ডিভাইসে না কাজ করে, তাই ContentProviderবাঞ্ছনীয় solytion
Siarhei

0
 String filePath="/storage/emulated/0/DCIM"+app_name;
    File dir=new File(filePath);
    if(!dir.exists()){
        dir.mkdir();
    }

এই কোডটি অনক্রিট পদ্ধতিতে রয়েছে his এই কোডটি অ্যাপ_নামের একটি ডিরেক্টরি তৈরি করার জন্য। এখন, অ্যান্ড্রয়েডে ডিফল্ট ফাইল ম্যানেজার অ্যাপ ব্যবহার করে এই ডিরেক্টরিটি অ্যাক্সেস করা যায়। আপনার গন্তব্য ফোল্ডার সেট করতে যেখানেই প্রয়োজন এই স্ট্রিং ফাইলপথটি ব্যবহার করুন। আমি নিশ্চিত যে এই পদ্ধতিটি অ্যান্ড্রয়েড on এও কাজ করে কারণ আমি এটিতে পরীক্ষা করেছি H যদিও এটি অ্যান্ড্রয়েডের অন্যান্য সংস্করণেও কাজ করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.