অ্যান্ড্রয়েডে কোনও চিত্র কীভাবে ডাউনলোড এবং সংরক্ষণ করবেন


91

অ্যান্ড্রয়েডে প্রদত্ত ইউআরএল থেকে আপনি কীভাবে একটি চিত্র ডাউনলোড এবং সংরক্ষণ করবেন?

উত্তর:


224

30.12.2015 হিসাবে সম্পাদনা করুন - চিত্র ডাউনলোডের চূড়ান্ত গাইড


শেষ বড় আপডেট: মার্চ 31 2016


টিএল; ডিআর ওরফে কথা বলা বন্ধ করুন, আমাকে কোড দিন!

এই পোস্টের নীচে যাও, কপি BasicImageDownloader(javadoc সংস্করণ এখানে আপনার প্রকল্পে), বাস্তবায়ন OnImageLoaderListenerইন্টারফেস এবং আপনার কাজ সম্পন্ন হয়।

দ্রষ্টব্য : যদিও BasicImageDownloaderসম্ভাব্য ত্রুটিগুলি পরিচালনা করে এবং আপনার অ্যাপ্লিকেশনটিকে কোনও সমস্যা হতে পারে ক্রাশ হওয়া থেকে রোধ করবে, এটি ডাউনলোডের পরে কোনও পোস্ট-প্রসেসিং (উদাহরণস্বরূপ ডাউনসাইজিং) সম্পাদন করবে না Bitmaps


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

আমি "ইমেজ ডাউনলোডার" নামে একটি ডেমো প্রকল্প তৈরি করেছি যা দেখায় যে কীভাবে আমার নিজের ডাউনলোডার প্রয়োগকরণ, অ্যান্ড্রয়েডের অন্তর্নির্মিত DownloadManagerপাশাপাশি কয়েকটি জনপ্রিয় ওপেন-সোর্স লাইব্রেরি ব্যবহার করে কোনও চিত্র ডাউনলোড (এবং সংরক্ষণ) করা যায় । আপনি সম্পূর্ণ সোর্স কোড দেখতে বা গিটহাবে প্রকল্পটি ডাউনলোড করতে পারেন ।

দ্রষ্টব্য : আমি এখনও এসডিকে 23+ (মার্শমালো) এর জন্য অনুমতি ব্যবস্থা সামঞ্জস্য করি নি, সুতরাং প্রকল্পটি এসডিকে 22 (ললিপপ) লক্ষ্য করে যাচ্ছে।

এই পোস্টের শেষে আমার উপসংহারে আমি উল্লেখ করেছি প্রতিচ্ছবি ডাউনলোড করার প্রতিটি বিশেষ পদ্ধতিতে যথাযথ ব্যবহারের ক্ষেত্রে আমার নম্র মতামতটি ভাগ করব

আসুন একটি নিজস্ব বাস্তবায়ন দিয়ে শুরু করুন (আপনি পোস্টের শেষে কোডটি সন্ধান করতে পারেন)। প্রথমত, এটি একটি বেসিক ইমেজডাউনলোডার এবং এটিই। এটি যা করা তা হ'ল প্রদত্ত ইউআরএলটির সাথে সংযোগ স্থাপন, ডেটা পড়ার এবং এটিকে ডিকোড করার চেষ্টা করা Bitmap, OnImageLoaderListenerযখন উপযুক্ত হয় তখন ইন্টারফেস কলব্যাকগুলি ট্রিগার করে । এই পদ্ধতির সুবিধা - এটি সহজ এবং আপনার কী চলছে সে সম্পর্কে একটি পরিষ্কার ধারণা রয়েছে। আপনার প্রয়োজন মতো কিছু চিত্র ডাউনলোড করা / প্রদর্শন করা এবং সংরক্ষণ করা ভাল উপায়, যদিও আপনি কোনও স্মৃতি / ডিস্ক ক্যাশে বজায় রাখার বিষয়ে চিন্তা করেন না।

দ্রষ্টব্য: বড় চিত্রগুলির ক্ষেত্রে আপনার এগুলি কমিয়ে দেওয়ার প্রয়োজন হতে পারে ।

-

অ্যান্ড্রয়েড ডাউনলোডম্যানেজারটি আপনার জন্য সিস্টেমটিকে ডাউনলোড পরিচালনা করতে দেয় এমন একটি উপায়। এটি কেবল চিত্রগুলি নয়, যে কোনও ধরণের ফাইল ডাউনলোড করতে সক্ষম capable আপনি আপনার ডাউনলোডটি নিঃশব্দে এবং ব্যবহারকারীর কাছে অদৃশ্য হয়ে যেতে দিতে পারেন বা আপনি বিজ্ঞপ্তি ক্ষেত্রে ডাউনলোডটি ব্যবহারকারীকে সক্ষম করতে পারবেন। আপনি একটি নিবন্ধন করতে পারেনBroadcastReceiverডাউনলোড শেষ হওয়ার পরে আপনি বিজ্ঞপ্তি পেতে একটিতে । সেটআপটি বেশ সোজা, নমুনা কোডের জন্য সংযুক্ত প্রকল্পটি দেখুন।

DownloadManagerআপনি যদি চিত্রটিও প্রদর্শন করতে চান তবে সাধারণত এটি ব্যবহার করা ভাল ধারণা নয়, যেহেতু আপনার কেবল ডাউনলোড Bitmapকরা একটিতে সেট করার পরিবর্তে সেভ করা ফাইলটি পড়তে এবং ডিকোড করা দরকার ImageViewDownloadManagerআপনি ডাউনলোড অগ্রগতি ট্র্যাক করতে অ্যাপের জন্য যে কোনো এপিআই প্রদান করে না।

-

এখন দুর্দান্ত জিনিস - গ্রন্থাগারগুলির ভূমিকা। মেমরি / ডিস্ক ক্যাশে তৈরি করা ও পরিচালনা করা, মেমরি / ডিস্ক ক্যাশে তৈরি করা এবং পরিচালনা করা, চিত্রগুলি পুনরায় আকার দেওয়া, সেগুলিকে রূপান্তর করা এবং আরও অনেক কিছু সহ এগুলি কেবল চিত্রগুলি ডাউনলোড এবং প্রদর্শন করা ছাড়াও আরও অনেক কিছু করতে পারে।

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

ভলির অনুরোধগুলি পরিচালনা করার জন্য আপনাকে একটি সিঙ্গলটন ক্লাস প্রয়োগ করতে হবে এবং আপনি যেতে ভাল।

আপনি নিজের ImageViewভলির সাথে প্রতিস্থাপন করতে চাইতে পারেন NetworkImageView, তাই ডাউনলোডটি মূলতঃ ওয়ান-লাইনারে পরিণত হয়:

((NetworkImageView) findViewById(R.id.myNIV)).setImageUrl(url, MySingleton.getInstance(this).getImageLoader());

আপনার যদি আরও নিয়ন্ত্রণের প্রয়োজন ImageRequestহয় তবে ভলির সাহায্যে এটি তৈরির মত দেখাচ্ছে :

     ImageRequest imgRequest = new ImageRequest(url, new Response.Listener<Bitmap>() {
             @Override
             public void onResponse(Bitmap response) {
                    //do stuff
                }
            }, 0, 0, ImageView.ScaleType.CENTER_CROP, Bitmap.Config.ARGB_8888, 
             new Response.ErrorListener() {
             @Override
             public void onErrorResponse(VolleyError error) {
                   //do stuff
                }
            });

এটি উল্লেখ করার মতো যে ভলিতে VolleyErrorক্লাস সরবরাহ করে একটি দুর্দান্ত ত্রুটি পরিচালনা করার ব্যবস্থা রয়েছে যা আপনাকে ত্রুটির সঠিক কারণ নির্ধারণ করতে সহায়তা করে। যদি আপনার অ্যাপ্লিকেশন প্রচুর নেটওয়ার্কিং করে এবং চিত্রগুলি পরিচালনা করা এর মূল উদ্দেশ্য না হয় তবে ভ্যালি এটি আপনার জন্য উপযুক্ত।

-

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

 Picasso.with(myContext)
       .load(url)
       .into(myImageView); 

ডিফল্টরূপে, পিকাসো ডিস্ক / মেমরি ক্যাশে পরিচালনা করে যাতে আপনার এটি নিয়ে চিন্তা করার দরকার নেই। আরও নিয়ন্ত্রণের জন্য আপনি Targetইন্টারফেসটি প্রয়োগ করতে পারেন এবং এতে আপনার চিত্র লোড করতে ব্যবহার করতে পারেন - এটি ভলির উদাহরণের মতো কলব্যাক সরবরাহ করবে। উদাহরণস্বরূপ ডেমো প্রকল্পটি দেখুন।

পিকাসো আপনাকে ডাউনলোড করা চিত্রটিতে রূপান্তরগুলি প্রয়োগ করতে দেয় এবং আরও কিছু লাইব্রেরি রয়েছে যা এপিআই-এর প্রসারিত করে। এছাড়াও RecyclerView/ ListView/ এ খুব ভাল কাজ করে GridView

-

ইউনিভার্সাল ইমেজ লোডার ইমেজ পরিচালনার উদ্দেশ্যে পরিবেশন করা অন্য একটি খুব জনপ্রিয় গ্রন্থাগার। এটি নিজস্ব ব্যবহার করে ImageLoaderযে (একবার সূচনা হওয়ার পরে) একটি বিশ্বব্যাপী উদাহরণ রয়েছে যা কোডের একক লাইনে চিত্রগুলি ডাউনলোড করতে ব্যবহার করা যেতে পারে:

  ImageLoader.getInstance().displayImage(url, myImageView);

আপনি যদি ডাউনলোডের অগ্রগতি ট্র্যাক করতে চান বা ডাউনলোড করা অ্যাক্সেস করতে পারেন Bitmap:

 ImageLoader.getInstance().displayImage(url, myImageView, opts, 
 new ImageLoadingListener() {
     @Override
     public void onLoadingStarted(String imageUri, View view) {
                     //do stuff
                }

      @Override
      public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                   //do stuff
                }

      @Override
      public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                   //do stuff
                }

      @Override
      public void onLoadingCancelled(String imageUri, View view) {
                   //do stuff
                }
            }, new ImageLoadingProgressListener() {
      @Override
      public void onProgressUpdate(String imageUri, View view, int current, int total) {
                   //do stuff
                }
            });

optsএই উদাহরণে যুক্তি হল DisplayImageOptionsঅবজেক্ট। আরও জানতে ডেমো প্রকল্পটি দেখুন।

ভলির অনুরূপ, ইউআইএল FailReasonক্লাস সরবরাহ করে যা আপনাকে ডাউনলোড ব্যর্থতায় কী ভুল হয়েছে তা যাচাই করতে সক্ষম করে। ডিফল্টরূপে, ইউআইএল স্পষ্টভাবে এটি না করতে বললে মেমরি / ডিস্ক ক্যাশে বজায় রাখে।

দ্রষ্টব্য : লেখক উল্লেখ করেছেন যে তিনি 27 শে নভেম্বর, ২০১৫ সালের মতো প্রকল্পটি আর পরিচালনা করছেন না many তবে যেহেতু অনেক অবদানকারী রয়েছে তাই আমরা আশা করতে পারি যে ইউনিভার্সাল ইমেজ লোডার বেঁচে থাকবে।

-

ফেসবুকের ফ্রেস্কো হ'ল নতুন এবং (আইএমও) সর্বাধিক উন্নত গ্রন্থাগার যা চিত্র পরিচালনাকে একটি নতুন স্তরে নিয়ে যায়: Bitmapsজাভা হিপ (ললিপপের পূর্বে) অ্যানিমেটেড ফর্ম্যাট এবং প্রগতিশীল জেপিইজি স্ট্রিমিং সমর্থন করে

ফ্রেস্কোর পিছনে ধারণা এবং কৌশল সম্পর্কে আরও জানতে, এই পোস্টটি দেখুন

প্রাথমিক ব্যবহারটি বেশ সহজ। নোট করুন যে আপনি Fresco.initialize(Context);কেবল একবার কল করতে হবে , Applicationক্লাসে অগ্রাধিকারযোগ্য । ফ্রেসকো একাধিকবার আরম্ভ করার ফলে অনাকাঙ্ক্ষিত আচরণ এবং OOM ত্রুটি হতে পারে।

ফ্রেস্কো Draweeচিত্রগুলি প্রদর্শন করতে এস ব্যবহার করে, আপনি সেগুলি সেগুলি হিসাবে ভাবতে পারেন ImageView:

    <com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/drawee"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    fresco:fadeDuration="500"
    fresco:actualImageScaleType="centerCrop"
    fresco:placeholderImage="@drawable/placeholder_grey"
    fresco:failureImage="@drawable/error_orange"
    fresco:placeholderImageScaleType="fitCenter"
    fresco:failureImageScaleType="centerInside"
    fresco:retryImageScaleType="centerCrop"
    fresco:progressBarImageScaleType="centerInside"
    fresco:progressBarAutoRotateInterval="1000"
    fresco:roundAsCircle="false" />

আপনি দেখতে পাচ্ছেন, প্রচুর স্টাফ (ট্রান্সফর্মেশন অপশন সহ) এক্সএমএলে ইতিমধ্যে সংজ্ঞায়িত হয়ে গেছে, সুতরাং কোনও চিত্র প্রদর্শিত করতে আপনাকে যা করতে হবে তা হ'ল এক-লাইনার:

 mDrawee.setImageURI(Uri.parse(url));

ফ্রেস্কো একটি বর্ধিত কাস্টমাইজেশন এপিআই সরবরাহ করে, যা পরিস্থিতিতে, বেশ জটিল হতে পারে এবং ব্যবহারকারীর ডকস সাবধানে পড়তে হবে (হ্যাঁ, কখনও কখনও আপনাকে আরটিএফএম করা দরকার )।

আমি নমুনা প্রকল্পের মধ্যে প্রগতিশীল জেপিজি এবং অ্যানিমেটেড চিত্রগুলির উদাহরণ অন্তর্ভুক্ত করেছি।


উপসংহার - "আমি দুর্দান্ত জিনিসগুলি সম্পর্কে শিখেছি, এখন আমার কী ব্যবহার করা উচিত?"

নোট করুন যে নিম্নলিখিত পাঠ্যটি আমার ব্যক্তিগত মতামতকে প্রতিবিম্বিত করে এবং একটি পোষ্টুলেট হিসাবে গ্রহণ করা উচিত নয়।

  • আপনার যদি কেবল কয়েকটি চিত্র ডাউনলোড / সংরক্ষণ / প্রদর্শনের Recycler-/Grid-/ListViewপ্রয়োজন হয় তবে এগুলিকে একটিতে ব্যবহার করার পরিকল্পনা করবেন না এবং প্রদর্শন-প্রস্তুত হওয়ার জন্য পুরো গোছা চিত্রের প্রয়োজন নেই, বেসিক আইমেজডাউনলোডারটি আপনার প্রয়োজনের সাথে খাপ খায়
  • যদি আপনার অ্যাপ্লিকেশন কোনও ব্যবহারকারী বা একটি স্বয়ংক্রিয় ক্রিয়াকলাপের ফলে চিত্রগুলি (বা অন্যান্য ফাইলগুলি) সংরক্ষণ করে এবং আপনার চিত্রগুলি প্রায়শই প্রদর্শিত হওয়ার প্রয়োজন না হয় তবে অ্যান্ড্রয়েড ডাউনলোডম্যানেজারটি ব্যবহার করুন
  • যদি আপনার অ্যাপ্লিকেশন প্রচুর নেটওয়ার্কিং করে, JSONতথ্য প্রেরণ / গ্রহণ করে, চিত্রগুলির সাথে কাজ করে তবে সেগুলি অ্যাপ্লিকেশনটির মূল উদ্দেশ্য নয়, ভলির সাথে যান ।
  • আপনার অ্যাপ্লিকেশনটি চিত্র / মিডিয়া-কেন্দ্রিক, আপনি চিত্রগুলিতে কিছু রূপান্তর প্রয়োগ করতে চান এবং জটিল এপিআই নিয়ে বিরক্ত করতে চান না: পিকাসো ব্যবহার করুন (দ্রষ্টব্য: মধ্যবর্তী ডাউনলোডের স্থিতি ট্র্যাক করার জন্য কোনও API সরবরাহ করে না) বা ইউনিভার্সাল চিত্র লোডার
  • যদি আপনার অ্যাপ্লিকেশনটি চিত্র সম্পর্কিত হয় তবে আপনার অ্যানিমেটেড ফর্ম্যাটগুলি প্রদর্শন করার মতো উন্নত বৈশিষ্ট্যগুলির প্রয়োজন এবং আপনি ডক্সটি পড়তে প্রস্তুত, ফ্রেস্কোর সাথে যান

আপনি যদি এটি মিস করেন তবে গিথুব লিঙ্কটি করেন তবে ডেমো প্রকল্পের জন্য ।


এবং এখানে BasicImageDownloader.java

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashSet;
import java.util.Set;

public class BasicImageDownloader {

    private OnImageLoaderListener mImageLoaderListener;
    private Set<String> mUrlsInProgress = new HashSet<>();
    private final String TAG = this.getClass().getSimpleName();

    public BasicImageDownloader(@NonNull OnImageLoaderListener listener) {
        this.mImageLoaderListener = listener;
    }

    public interface OnImageLoaderListener {
        void onError(ImageError error);      
        void onProgressChange(int percent);
        void onComplete(Bitmap result);
    }


    public void download(@NonNull final String imageUrl, final boolean displayProgress) {
        if (mUrlsInProgress.contains(imageUrl)) {
            Log.w(TAG, "a download for this url is already running, " +
                    "no further download will be started");
            return;
        }

        new AsyncTask<Void, Integer, Bitmap>() {

            private ImageError error;

            @Override
            protected void onPreExecute() {
                mUrlsInProgress.add(imageUrl);
                Log.d(TAG, "starting download");
            }

            @Override
            protected void onCancelled() {
                mUrlsInProgress.remove(imageUrl);
                mImageLoaderListener.onError(error);
            }

            @Override
            protected void onProgressUpdate(Integer... values) {
                mImageLoaderListener.onProgressChange(values[0]);
            }

        @Override
        protected Bitmap doInBackground(Void... params) {
            Bitmap bitmap = null;
            HttpURLConnection connection = null;
            InputStream is = null;
            ByteArrayOutputStream out = null;
            try {
                connection = (HttpURLConnection) new URL(imageUrl).openConnection();
                if (displayProgress) {
                    connection.connect();
                    final int length = connection.getContentLength();
                    if (length <= 0) {
                        error = new ImageError("Invalid content length. The URL is probably not pointing to a file")
                                .setErrorCode(ImageError.ERROR_INVALID_FILE);
                        this.cancel(true);
                    }
                    is = new BufferedInputStream(connection.getInputStream(), 8192);
                    out = new ByteArrayOutputStream();
                    byte bytes[] = new byte[8192];
                    int count;
                    long read = 0;
                    while ((count = is.read(bytes)) != -1) {
                        read += count;
                        out.write(bytes, 0, count);
                        publishProgress((int) ((read * 100) / length));
                    }
                    bitmap = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
                } else {
                    is = connection.getInputStream();
                    bitmap = BitmapFactory.decodeStream(is);
                }
            } catch (Throwable e) {
                if (!this.isCancelled()) {
                    error = new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION);
                    this.cancel(true);
                }
            } finally {
                try {
                    if (connection != null)
                        connection.disconnect();
                    if (out != null) {
                        out.flush();
                        out.close();
                    }
                    if (is != null)
                        is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return bitmap;
        }

            @Override
            protected void onPostExecute(Bitmap result) {
                if (result == null) {
                    Log.e(TAG, "factory returned a null result");
                    mImageLoaderListener.onError(new ImageError("downloaded file could not be decoded as bitmap")
                            .setErrorCode(ImageError.ERROR_DECODE_FAILED));
                } else {
                    Log.d(TAG, "download complete, " + result.getByteCount() +
                            " bytes transferred");
                    mImageLoaderListener.onComplete(result);
                }
                mUrlsInProgress.remove(imageUrl);
                System.gc();
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public interface OnBitmapSaveListener {
        void onBitmapSaved();
        void onBitmapSaveError(ImageError error);
    }


    public static void writeToDisk(@NonNull final File imageFile, @NonNull final Bitmap image,
                               @NonNull final OnBitmapSaveListener listener,
                               @NonNull final Bitmap.CompressFormat format, boolean shouldOverwrite) {

    if (imageFile.isDirectory()) {
        listener.onBitmapSaveError(new ImageError("the specified path points to a directory, " +
                "should be a file").setErrorCode(ImageError.ERROR_IS_DIRECTORY));
        return;
    }

    if (imageFile.exists()) {
        if (!shouldOverwrite) {
            listener.onBitmapSaveError(new ImageError("file already exists, " +
                    "write operation cancelled").setErrorCode(ImageError.ERROR_FILE_EXISTS));
            return;
        } else if (!imageFile.delete()) {
            listener.onBitmapSaveError(new ImageError("could not delete existing file, " +
                    "most likely the write permission was denied")
                    .setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
            return;
        }
    }

    File parent = imageFile.getParentFile();
    if (!parent.exists() && !parent.mkdirs()) {
        listener.onBitmapSaveError(new ImageError("could not create parent directory")
                .setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
        return;
    }

    try {
        if (!imageFile.createNewFile()) {
            listener.onBitmapSaveError(new ImageError("could not create file")
                    .setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
            return;
        }
    } catch (IOException e) {
        listener.onBitmapSaveError(new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION));
        return;
    }

    new AsyncTask<Void, Void, Void>() {

        private ImageError error;

        @Override
        protected Void doInBackground(Void... params) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(imageFile);
                image.compress(format, 100, fos);
            } catch (IOException e) {
                error = new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION);
                this.cancel(true);
            } finally {
                if (fos != null) {
                    try {
                        fos.flush();
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

        @Override
        protected void onCancelled() {
            listener.onBitmapSaveError(error);
        }

        @Override
        protected void onPostExecute(Void result) {
            listener.onBitmapSaved();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
  }

public static Bitmap readFromDisk(@NonNull File imageFile) {
    if (!imageFile.exists() || imageFile.isDirectory()) return null;
    return BitmapFactory.decodeFile(imageFile.getAbsolutePath());
}

public interface OnImageReadListener {
    void onImageRead(Bitmap bitmap);
    void onReadFailed();
}

public static void readFromDiskAsync(@NonNull File imageFile, @NonNull final OnImageReadListener listener) {
    new AsyncTask<String, Void, Bitmap>() {
        @Override
        protected Bitmap doInBackground(String... params) {
            return BitmapFactory.decodeFile(params[0]);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap != null)
                listener.onImageRead(bitmap);
            else
                listener.onReadFailed();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageFile.getAbsolutePath());
}

    public static final class ImageError extends Throwable {

        private int errorCode;
        public static final int ERROR_GENERAL_EXCEPTION = -1;
        public static final int ERROR_INVALID_FILE = 0;
        public static final int ERROR_DECODE_FAILED = 1;
        public static final int ERROR_FILE_EXISTS = 2;
        public static final int ERROR_PERMISSION_DENIED = 3;
        public static final int ERROR_IS_DIRECTORY = 4;


        public ImageError(@NonNull String message) {
            super(message);
        }

        public ImageError(@NonNull Throwable error) {
            super(error.getMessage(), error.getCause());
            this.setStackTrace(error.getStackTrace());
        }

        public ImageError setErrorCode(int code) {
            this.errorCode = code;
            return this;
        }

        public int getErrorCode() {
            return errorCode;
        }
      }
   }

অনপিকচারটেকেন () কলব্যাক সম্পর্কে কী যা ছবিটিকে বাইট হিসাবে দেয় [], ক্যামেরা থেকে সরাসরি কোনও ছবিতে কোনও ইউআরএল পাওয়া যায়? অথবা অ্যান্ড্রয়েডে কোনও ছবি সংরক্ষণ করার জন্য অ্যান্ড্রয়েডের বেসিক পুরানো আউটপুট স্ট্রিম () কেবল অন্তর্নিহিত অন্তর্নিহিত ব্যবহার না করেই কোনও ক্যামেরা তোলা কোনও ছবি? এটি অদ্ভুত বলে মনে হচ্ছে, কারণ অনুলিপিটিউটের পরে প্রাকৃতিক জিনিসটি এটি সংরক্ষণ করা অবশ্যই। এটি করার জন্য কোনও বিশেষ সমর্থন নেই?
টমবোলা

4
@ টমবোলা হাই! এই পোস্টটি ওয়েব থেকে একটি ছবি ডাউনলোড করার বিষয়ে। তবে আপনার প্রশ্নের উত্তর দেওয়ার জন্য (যতদূর আমি এটি বুঝতে পেরেছি): ক্যামেরা ছবি সংরক্ষণের সাধারণ উপায়টি Cursor( onActivityResult()পদ্ধতিতে) এর পথ পাচ্ছে , তারপরে Bitmapসেই পথটি ব্যবহার করে তৈরি করা হবে । এবং হ্যাঁ, আপনি এই চিত্রটিকে এসডিতে সংরক্ষণ করতে চাইলে আপনি একটি FileOutputStreamএবং একটি ব্যবহার করা থেকে দূরে থাকবেন না ByteArrayOutputStream
Droidman

@ বার্টবার্গ এই প্রশ্নটি একটি চিত্র ডাউনলোড এবং সংরক্ষণের বিষয়ে। তবে আপনি ঠিকঠাক পর্যায়ে এসেছেন, যেহেতু লেখার পদ্ধতি রয়েছে, তাই সম্পূর্ণতার স্বার্থে একটি পঠন পদ্ধতিও থাকা উচিত। আমি শীঘ্রই এই পোস্টে এটি পরবর্তী আপডেটে যুক্ত করব।
Droidman

আপনি কি এই বেসিক ইমেজডাউনলোডার ব্যবহার করে একটি উদাহরণ সরবরাহ করতে পারেন?
জয়দেব

4
@ জয়দেব কালিভারপু দয়া করে গিটহাবের ডেমো অ্যাপ্লিকেশনটি দেখুন ( উদাহরণ সহ উত্স শ্রেণি )
ড্রোডম্যান

35

আমি কেবল এই সমস্যার সমাধান থেকে এসেছি এবং আমি সম্পূর্ণ কোডটি শেয়ার করতে চাই যা ডাউনলোড করতে পারে, এসডকার্ডে সংরক্ষণ করতে পারে (এবং ফাইলের নামটি আড়াল করতে পারে) এবং চিত্রগুলি পুনরুদ্ধার করতে পারে এবং অবশেষে এটি পরীক্ষা করে যে চিত্রটি ইতিমধ্যে আছে কিনা। ইউআরএল ডাটাবেস থেকে আসে যাতে ফাইলের নামটি আইডি ব্যবহার করে অনন্যভাবে করা যায়।

প্রথম ডাউনলোড চিত্র

   private class GetImages extends AsyncTask<Object, Object, Object> {
    private String requestUrl, imagename_;
    private ImageView view;
    private Bitmap bitmap ; 
      private FileOutputStream fos;
    private GetImages(String requestUrl, ImageView view, String _imagename_) {
        this.requestUrl = requestUrl;
        this.view = view;
        this.imagename_ = _imagename_ ;
    }

    @Override
    protected Object doInBackground(Object... objects) {
        try {
            URL url = new URL(requestUrl);
            URLConnection conn = url.openConnection();
            bitmap = BitmapFactory.decodeStream(conn.getInputStream());
        } catch (Exception ex) {
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object o) { 
        if(!ImageStorage.checkifImageExists(imagename_))
        { 
                view.setImageBitmap(bitmap);
                ImageStorage.saveToSdCard(bitmap, imagename_); 
            }  
        }  
   }

তারপরে ফাইলগুলি সংরক্ষণ এবং পুনরুদ্ধারের জন্য একটি শ্রেণি তৈরি করুন

  public class ImageStorage {


public static String saveToSdCard(Bitmap bitmap, String filename) {

    String stored = null;

    File sdcard = Environment.getExternalStorageDirectory() ; 

    File folder = new File(sdcard.getAbsoluteFile(), ".your_specific_directory");//the dot makes this directory hidden to the user
    folder.mkdir(); 
    File file = new File(folder.getAbsoluteFile(), filename + ".jpg") ;
    if (file.exists())
        return stored ;

    try {
        FileOutputStream out = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
        stored = "success";
    } catch (Exception e) {
        e.printStackTrace();
    }
     return stored;
   }

public static File getImage(String imagename) {

        File mediaImage = null;
        try {
            String root = Environment.getExternalStorageDirectory().toString();
            File myDir = new File(root);
            if (!myDir.exists())
                return null;

            mediaImage = new File(myDir.getPath() + "/.your_specific_directory/"+imagename);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return mediaImage;
    }
public static boolean checkifImageExists(String imagename)
{
    Bitmap b = null ;
    File file = ImageStorage.getImage("/"+imagename+".jpg");
    String path = file.getAbsolutePath();

    if (path != null)
        b = BitmapFactory.decodeFile(path); 

    if(b == null ||  b.equals(""))
    {
        return false ;
    }
    return true ;
}
  }

তারপরে চিত্রগুলি অ্যাক্সেস করতে প্রথমে এটি ডাউনলোড আছে কিনা তা আগে থেকেই আছে কিনা তা পরীক্ষা করে দেখুন

          if(ImageStorage.checkifImageExists(imagename))
            {
                File file = ImageStorage.getImage("/"+imagename+".jpg"); 
                String path = file.getAbsolutePath(); 
                if (path != null){
                    b = BitmapFactory.decodeFile(path);
                    imageView.setImageBitmap(b);
                }  
            } else { 
                new GetImages(imgurl, imageView, imagename).execute() ; 
            }

দ্রষ্টব্য : এই উদাহরণটি সাধারণত কার্যকরভাবে কাজ করতে পারে, তবে এটি কোনও ত্রুটি পরিচালনার ব্যবস্থা করে না এবং AsyncTaskএর সুবিধাগুলির (প্যারামিট্রাইজেশনের যথাযথ ব্যবহার, সমান্তরাল সম্পাদন ..) এর কিছু প্রাথমিক বোঝার অভাব রয়েছে । বিস্তারিত জানার জন্য নীচে আমার উদাহরণ দেখুন। দ্রষ্টব্য । যারা মনে করতে পারে আমি যাই হোক না কেন কারণেই নিজের কোডটি প্রচার করার জন্য এটি লিখেছিলাম: না, আমি কেবলমাত্র প্রদত্ত উদাহরণটিতে দেখতে পাচ্ছি এমন সমস্যাগুলি দেখিয়ে দিচ্ছি।
Droidman

হ্যাঁ ড্রডম্যান, আমি আপনার সাথে একমত এই কোডের টুকরোটি ট্যাম্পলেট হিসাবে নেওয়া উচিত এবং এটিকে ত্রুটি পরিচালনা করা সহ নিজেরাই এটি সম্পন্ন করতে হবে। যাইহোক, আপনার কোডটিতেও ত্রুটি পরিচালনার অভাব রয়েছে। আইওএক্সেপশনের ক্ষেত্রে আপনার সংযোগ এবং স্ট্রিমগুলির কী হবে?
অ্যান্ড্রয়েডারে

@ অ্যান্ড্রয়েডার দয়া করে আমার downloadপদ্ধতিটি, বিশেষত doInBackgroundআমি যে টাস্কটি ব্যবহার করি তার পদ্ধতিটি খুব কাছ থেকে দেখুন । একটি ব্লকে IOExceptionঅবতরণ করবে catch (Throwable e), যার ফলে একটি ImageErrorফিরে আসবে এবং onError()কলব্যাক ট্রিগার হবে। ImageErrorবস্তুর মূল স্ট্যাক ট্রেস এবং ঘটেছে কারণ থাকতে হবেException
Droidman

4
হ্যাঁ, তবে আপনার সংযোগটি সংযোগ বিচ্ছিন্ন হবে না এবং আপনার স্ট্রিমগুলি বন্ধ হবে না
Androider

@ এন্ড্রয়েডার আহ, আমি আপনার বক্তব্যটি দেখতে পাচ্ছি। যদিও আমি আমার পরীক্ষার ডিভাইসে কোনও সন্দেহজনক ফাঁস লক্ষ্য করিনি, অন্য ডিভাইসেও এই আচরণটি আলাদা হতে পারে। ইঙ্গিতটির জন্য ধন্যবাদ - আমি কোডটি আপডেট করেছি
Droidman

33

এটি ডাউনলোড করার জন্য আপনার নিজের কোডটি কেন সত্যই প্রয়োজন? কীভাবে ডাউনলোড ম্যানেজারকে আপনার ইউআরআই পাস করবেন?

public void downloadFile(String uRl) {
    File direct = new File(Environment.getExternalStorageDirectory()
            + "/AnhsirkDasarp");

    if (!direct.exists()) {
        direct.mkdirs();
    }

    DownloadManager mgr = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);

    Uri downloadUri = Uri.parse(uRl);
    DownloadManager.Request request = new DownloadManager.Request(
            downloadUri);

    request.setAllowedNetworkTypes(
            DownloadManager.Request.NETWORK_WIFI
                    | DownloadManager.Request.NETWORK_MOBILE)
            .setAllowedOverRoaming(false).setTitle("Demo")
            .setDescription("Something useful. No, really.")
            .setDestinationInExternalPublicDir("/AnhsirkDasarp", "fileName.jpg");

    mgr.enqueue(request);

}

4
এপিআই> 8 এর জন্য নিখুঁত উদাহরণ।
জিতেন পারমার

আপনার কোড এক চিত্রের জন্য নিখুঁত! আমি আমার সার্ভারে আমার ইমেজ ফাইল থেকে আরও (100 টি পিক) ডাউনলোড করতে চাইলে আমি কী করতে পারি ???
কোস্টান্টিনোস ইব্রাহ

আমি মেসেজ পেয়েছি বলে ফাইল ক্ষতিগ্রস্থ হয়েছে!
অনুপ

4
হতে পারে, .setDestinationInExternPublicDir ("/ AnhsirkDasarp", "fileName.jpg");
বিশেষজ্ঞ চাই

4
এটি সফলভাবে ডাউনলোড হয়েছে বা ব্যর্থ হয়েছে কিনা তা আমরা কীভাবে জানি
প্রবস

12

এটা আপনাকে সাহায্য করতে পারে ..

Button download_image = (Button)bigimagedialog.findViewById(R.id.btn_downloadimage);
                    download_image.setOnClickListener(new View.OnClickListener()
                    {
                        public void onClick(View v)
                        {
                            boolean success = (new File("/sdcard/dirname")).mkdir(); 
                            if (!success)
                            {
                                Log.w("directory not created", "directory not created");
                            }

                            try
                            {
                                URL url = new URL("YOUR_URL");
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                                connection.setDoInput(true);
                                connection.connect();
                                InputStream input = connection.getInputStream();
                                Bitmap myBitmap = BitmapFactory.decodeStream(input);

                                String data1 = String.valueOf(String.format("/sdcard/dirname/%d.jpg",System.currentTimeMillis()));

                                FileOutputStream stream = new FileOutputStream(data1);

                                ByteArrayOutputStream outstream = new ByteArrayOutputStream();
                                myBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outstream);
                                byte[] byteArray = outstream.toByteArray();

                                stream.write(byteArray);
                                stream.close();

                                Toast.makeText(getApplicationContext(), "Downloading Completed", Toast.LENGTH_SHORT).show();
                            }
                            catch (Exception e)
                            {
                                e.printStackTrace();
                            }
                        }
                    });

6

আমার একটি সহজ সমাধান রয়েছে যা নিখুঁতভাবে কাজ করছে। কোডটি আমার নয়, আমি এই লিঙ্কটিতে এটি পেয়েছি । এখানে অনুসরণের পদক্ষেপগুলি:

১. চিত্রটি ডাউনলোড করার আগে, Android এর অভ্যন্তরীণ স্টোরেজে কোনও চিত্র ফাইলে বিটম্যাপ সংরক্ষণের জন্য একটি পদ্ধতি লিখি। GetapplicationContext () এর মাধ্যমে অ্যাপ্লিকেশন প্রসঙ্গে পাসটি ব্যবহার করার জন্য এটির একটি প্রসঙ্গ প্রয়োজন। এই পদ্ধতিটি আপনার ক্রিয়াকলাপ শ্রেণি বা অন্যান্য ব্যবহারের ক্লাসে ফেলে দেওয়া যেতে পারে।

public void saveImage(Context context, Bitmap b, String imageName) 
{
    FileOutputStream foStream;
    try 
    {
        foStream = context.openFileOutput(imageName, Context.MODE_PRIVATE);
        b.compress(Bitmap.CompressFormat.PNG, 100, foStream);
        foStream.close();
    } 
    catch (Exception e) 
    {
        Log.d("saveImage", "Exception 2, Something went wrong!");
        e.printStackTrace();
    }
}

২. এখন অ্যান্ডরিডে একটি চিত্র ফাইলে বিটম্যাপ সংরক্ষণ করার জন্য আমাদের একটি পদ্ধতি রয়েছে, আসুন ইউআরএল দ্বারা চিত্রগুলি ডাউনলোড করার জন্য অ্যাসিঙ্কটাস্ক লিখি। এই ব্যক্তিগত শ্রেণিকে সাবক্লাস হিসাবে আপনার ক্রিয়াকলাপ শ্রেণিতে স্থাপন করা দরকার। চিত্রটি ডাউনলোড হওয়ার পরে, onPostExecute পদ্ধতিতে, এটি চিত্রটি সংরক্ষণ করতে উপরের সংজ্ঞায়িত SaveI छवि পদ্ধতিটিকে কল করে। দ্রষ্টব্য, চিত্রটির নামটি "my_image.png" হিসাবে হার্ডকোড করা আছে।

private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
    private String TAG = "DownloadImage";
    private Bitmap downloadImageBitmap(String sUrl) {
        Bitmap bitmap = null;
        try {
            InputStream inputStream = new URL(sUrl).openStream();   // Download Image from URL
            bitmap = BitmapFactory.decodeStream(inputStream);       // Decode Bitmap
            inputStream.close();
        } catch (Exception e) {
            Log.d(TAG, "Exception 1, Something went wrong!");
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        return downloadImageBitmap(params[0]);
    }

    protected void onPostExecute(Bitmap result) {
        saveImage(getApplicationContext(), result, "my_image.png");
    }
}

৩. ছবিটি ডাউনলোডের জন্য অ্যাসিঙ্কটাস্ক সংজ্ঞায়িত করা হয়েছে, তবে সেই অ্যাসিঙ্কটাস্ক চালানোর জন্য আমাদের এটি সম্পাদন করতে হবে। এটি করার জন্য, আপনার ক্রিয়াকলাপ শ্রেণিতে আপনার অনক্রিয়া পদ্ধতিতে এই লাইনটি লিখুন বা একটি বোতামের অনক্লিক পদ্ধতিতে বা আপনি দেখতে উপযুক্ত অন্যান্য জায়গাগুলিতে লিখুন।

new DownloadImage().execute("http://developer.android.com/images/activity_lifecycle.png");

চিত্রটি /data/data/your.app.packagename/files/my_image.jpeg এ সংরক্ষণ করা উচিত, আপনার ডিভাইস থেকে এই ডিরেক্টরিটি অ্যাক্সেস করার জন্য এই পোস্টটি চেক করুন।

আইএমও এটি সমস্যার সমাধান! আপনি যদি চিত্রটি লোড করার মতো আরও পদক্ষেপগুলি চান তবে আপনি এই অতিরিক্ত পদক্ষেপগুলি অনুসরণ করতে পারেন:

৪. ছবিটি ডাউনলোড হওয়ার পরে, আমাদের অভ্যন্তরীণ স্টোরেজ থেকে চিত্র বিটম্যাপটি লোড করার একটি উপায় প্রয়োজন, যাতে আমরা এটি ব্যবহার করতে পারি। চিত্র বিটম্যাপ লোড করার পদ্ধতিটি লিখি। এই পদ্ধতিতে দুটি প্যারামেথার লাগে, একটি প্রসঙ্গ এবং একটি চিত্র ফাইলের নাম, পুরো পথ ব্যতীত, প্রসঙ্গটি.ওপেনফাইএইলপুট (চিত্রনাম) উপরের সেভিআইমেজ পদ্ধতিতে এই ফাইলটির নাম সংরক্ষণ করা হলে সেভ ডিরেক্টরিতে ফাইলটি সন্ধান করবে।

public Bitmap loadImageBitmap(Context context, String imageName) {
    Bitmap bitmap = null;
    FileInputStream fiStream;
    try {
        fiStream    = context.openFileInput(imageName);
        bitmap      = BitmapFactory.decodeStream(fiStream);
        fiStream.close();
    } catch (Exception e) {
        Log.d("saveImage", "Exception 3, Something went wrong!");
        e.printStackTrace();
    }
    return bitmap;
}

৫. এখন আমাদের কাছে ইমেজভিউ বা অন্য যে কোনও ভিউ যা আপনি ছবিটি ব্যবহার করতে চান তা চিত্র নির্ধারণের জন্য আমাদের প্রয়োজনীয় সমস্ত কিছু রয়েছে। আমরা যখন চিত্রটি সংরক্ষণ করি, তখন আমরা চিত্রটির নামটিকে "my_image.jpeg" হিসাবে হার্ডকোড করেছি, এখন আমরা বিটম্যাপটি পেতে এই চিত্রের নামটি উপরের লোড ইমেজবিটম্যাপ পদ্ধতিতে পাস করতে এবং এটি একটি চিত্রভিউতে সেট করতে পারি।

someImageView.setImageBitmap(loadImageBitmap(getApplicationContext(), "my_image.jpeg"));

Image. চিত্রের নাম অনুসারে চিত্রটির পুরো পথ পাবে।

File file            = getApplicationContext().getFileStreamPath("my_image.jpeg");
String imageFullPath = file.getAbsolutePath();

7. চিত্র ফাইল উপস্থিত আছে কিনা তা পরীক্ষা করে দেখুন।

ফাইল ফাইল =

getApplicationContext().getFileStreamPath("my_image.jpeg");
if (file.exists()) Log.d("file", "my_image.jpeg exists!");
  1. চিত্র ফাইল মুছতে।

    ফাইল ফাইল = getApplicationContext ()। GetFileStreamPath ("my_image.jpeg"); যদি (file.delete ()) লগ.ডি ("ফাইল", "my_image.jpeg মোছা!");


0

এই কোডটি আমার প্রকল্পে পুরোপুরি চালিত

downloadImagesToSdCard(imagepath,imagepath);

private void downloadImagesToSdCard(String downloadUrl,String imageName)
        {
            try
            {
                URL url = new URL("www.xxx.com"+downloadUrl); 
                /* making a directory in sdcard */
            //  String sdCard=Environment.getExternalStorageDirectory().toString();
                ContextWrapper cw = new ContextWrapper(getActivity());
                 // path to /data/data/yourapp/app_data/imageDir
                File directory = cw.getDir("files", Context.MODE_PRIVATE);

                File myDir = new File(directory,"folder");

                /*  if specified not exist create new */
                if(!myDir.exists())
                {
                    myDir.mkdir();
                    Log.v("", "inside mkdir");
                }

                /* checks the file and if it already exist delete */
                String fname = imageName;
                File file = new File (myDir, fname);
                Log.d("file===========path", ""+file);
                if (file.exists ()) 
                    file.delete (); 

                /* Open a connection */
                URLConnection ucon = url.openConnection();
                InputStream inputStream = null;
                HttpURLConnection httpConn = (HttpURLConnection)ucon;
                httpConn.setRequestMethod("GET");
                httpConn.connect();
                inputStream = httpConn.getInputStream();
                /*if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) 
                {
                    inputStream = httpConn.getInputStream();
                }*/

                FileOutputStream fos = new FileOutputStream(file);  
                int totalSize = httpConn.getContentLength();
                int downloadedSize = 0;   
                byte[] buffer = new byte[1024];
                int bufferLength = 0;
                while ( (bufferLength = inputStream.read(buffer)) >0 ) 
                {                 
                    fos.write(buffer, 0, bufferLength);                  
                    downloadedSize += bufferLength;                 
                    Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;
                }   

                fos.close();
                Log.d("test", "Image Saved in sdcard..");  
                viewimage();
            }
            catch(IOException io)
            {                  
                io.printStackTrace();
            }
            catch(Exception e)
            {                     
                e.printStackTrace();
            }


        } 

        public void viewimage()
        {
              String path = serialnumber+".png";
               ContextWrapper cw = new ContextWrapper(getActivity());

                //path to /data/data/yourapp/app_data/dirName
                File directory = cw.getDir("files", Context.MODE_PRIVATE);

                File mypath=new File(directory,"folder/"+path);

                Bitmap b;
                try {
                    b = BitmapFactory.decodeStream(new FileInputStream(mypath));
                //  b.compress(format, quality, stream)
                    profile_image.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }

4
হাই, অবদানের জন্য ধন্যবাদ নোট করুন যে অ্যাপ্লিকেশনটির ব্যক্তিগত স্টোরেজে চিত্রটি সংরক্ষণ করার উপরের পদ্ধতির ২ টি ডাউনসাইড রয়েছে: ১) চিত্রটি কেবলমাত্র আপনার অ্যাপের জন্য উপলব্ধ থাকবে এবং ২) অ্যাপ্লিকেশনটির ব্যক্তিগত স্টোরেজে চিত্র সংরক্ষণ করা এড়াতে হবে কারণ এটি বৃহত সামগ্রীর জন্য নয়।
ড্রয়েডম্যান

0

এটা চেষ্টা কর

 try
                {
                    Bitmap bmp = null;
                    URL url = new URL("Your_URL");
                    URLConnection conn = url.openConnection();
                    bmp = BitmapFactory.decodeStream(conn.getInputStream());
                    File f = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis() + ".jpg");
                    if(f.exists())
                        f.delete();
                    f.createNewFile();
                    Bitmap bitmap = bmp;
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
                    byte[] bitmapdata = bos.toByteArray();
                    FileOutputStream fos = new FileOutputStream(f);
                    fos.write(bitmapdata);
                    fos.flush();
                    fos.close();
                    Log.e(TAG, "imagepath: "+f );
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }

0
public class testCrop extends AppCompatActivity {
    ImageView iv;
    String imagePath = "https://style.pk/wp-content/uploads/2015/07/omer-Shahzad-performed-umrah-600x548.jpg";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testcrpop);
        iv = (ImageView) findViewById(R.id.testCrop);
        imageDownload image = new imageDownload(testCrop.this, iv);
        image.execute(imagePath);
    }
    class imageDownload extends AsyncTask<String, Integer, Bitmap> {
        Context context;
        ImageView imageView;
        Bitmap bitmap;
        InputStream in = null;
        int responseCode = -1;
//constructor.
        public imageDownload(Context context, ImageView imageView) {
            this.context = context;
            this.imageView = imageView;
        }
        @Override
        protected void onPreExecute() {
        }
        @Override
        protected Bitmap doInBackground(String... params) {
            try {
                URL url = new URL(params[0]);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setDoOutput(true);
                httpURLConnection.connect();
                responseCode = httpURLConnection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    in = httpURLConnection.getInputStream();
                    bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        }
        @Override
        protected void onPostExecute(Bitmap data) {
            imageView.setImageBitmap(data);
            saveImage(data);
        }

        private void saveImage(Bitmap data) {
            File createFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"test");
            createFolder.mkdir();
            File saveImage = new File(createFolder,"downloadimage.jpg");
            try {
                OutputStream outputStream = new FileOutputStream(saveImage);
                data.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
                outputStream.flush();
                outputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

আউটপুটএখানে চিত্র বর্ণনা লিখুন

আপনি মেমরিতে ডেটা লেখার অনুমতি যুক্ত করেছেন তা নিশ্চিত করুন

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

0

@ড্রোডম্যান পোস্টটি বেশ বিস্তৃত। ভলি কয়েকটি কেবাইটের ছোট ডেটা দিয়ে ভাল কাজ করে। আমি যখন 'বেসিকআইমেজডাউনলোডার.জভা' ব্যবহার করার চেষ্টা করেছি তখন অ্যান্ড্রয়েড স্টুডিও আমাকে সতর্ক করে দিয়েছিল যে অ্যাসিঙ্কটাস্ক ক্লাসটি স্থিতিশীল হওয়া উচিত বা ফাঁস হতে পারে। আমি ভলিকে অন্য একটি পরীক্ষামূলক অ্যাপ্লিকেশনটিতে ব্যবহার করেছি এবং এটি ফাঁসের কারণে ক্র্যাশ করে চলেছে তাই আমি ইমেজ ডাউনলোডারের জন্য ভোলি ব্যবহার সম্পর্কে উদ্বিগ্ন (চিত্রগুলি কয়েকশ কেবি হতে পারে)।

আমি পিকাসো ব্যবহার করেছি এবং এটি ভালভাবে কাজ করেছে, উপরের পোস্ট থেকে যা কিছু পরিবর্তন হয়েছে (সম্ভবত পিকাসোর উপর একটি আপডেট)। নীচের কোডটি আমার জন্য কাজ করেছে:

    public static void imageDownload(Context ctx, String url){
    Picasso.get().load(yourURL)
            .into(getTarget(url));
}
private static Target getTarget(final String url){

    Target target2 = new Target() {
        @Override
        public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
            new Thread(new Runnable() {

                @Override
                public void run() {

                    File file = new File(localPath + "/"+"YourImageFile.jpg");
                    try {
                        file.createNewFile();
                        FileOutputStream ostream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 80, ostream);
                        ostream.flush();
                        ostream.close();
                    } catch (IOException e) {
                        Log.e("IOException", e.getLocalizedMessage());
                    }
                }
            }).start();
        }

        @Override
        public void onBitmapFailed(Exception e, Drawable errorDrawable) {
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
        }
    };
    return target;
}

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