有时为同一位图保存为黑色图像的位图

时间:2016-03-27 03:20:52

标签: android bitmap qr-code universal-image-loader android-bitmap

我知道这是一个常见的问题,但我尝试了不同的建议,但仍然没有解决方案。

我的问题是位图正确显示,但有时会将其保存为黑色位图,而有时会正确保存。

任何人都可以看到我做了什么并告诉我哪里出错了?

我查看了其他大多数StackOverflow问题。

以下是我的代码,它将剪贴板文本编码为QR代码并尝试保存生成的qr代码。

谢谢!

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.text.ClipboardManager;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;

import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

//import android.content.ClipboardManager;

public class BarcodeWriter extends AppCompatActivity {
    ImageLoader imgLoader;
    ImageView qrImg;
    String copiedStr;
    TextView qrTxt;
    ClipboardManager clipboard;

    String BASE_QR_URL = "http://chart.apis.google.com/chart?cht=qr&chs=400x400&chld=M&choe=UTF-8&chl=";
    String fullUrl = BASE_QR_URL;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.barcode_writer);

        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultOptions)
                .build();
        imgLoader = ImageLoader.getInstance(); // Do it on Application start
        imgLoader.init(config);

        qrImg = (ImageView)findViewById(R.id.qrImg);
        qrTxt = (TextView)findViewById(R.id.qrTxt);

        clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);

        /*
         * clipboard.getText() is now deprecated. But I am going to use it here
         * because the new way of doing the same thing only works on API lvl 11+
         * Since I want this application to support API lvl 4+ we have to use
         * the old method.
         */
        CharSequence clipTxt = clipboard.getText();

        //This is the new, non-deprecated way of getting text from the Clipboard.
        //CharSequence clipTxt = clipboard.getPrimaryClip().getItemAt(0).getText();


        //If the clipboard has text, and it is more than 0 characters.
        if((null != clipTxt) && (clipTxt.length() > 0)){
            try {
                qrTxt.setText(clipTxt);
                copiedStr = clipTxt.toString();
                fullUrl += URLEncoder.encode(copiedStr, "UTF-8");
                //imgLoader.displayImage(fullUrl, qrImg);


                ImageLoader.getInstance().displayImage(fullUrl, qrImg, defaultOptions); // Incoming options will be used

                qrImg.setDrawingCacheEnabled(true);

                qrImg.measure(View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY));
                qrImg.layout(0, 0, qrImg.getMeasuredWidth(), qrImg.getMeasuredHeight());

                qrImg.buildDrawingCache();
                Bitmap bm = Bitmap.createBitmap(qrImg.getDrawingCache());
                qrImg.setDrawingCacheEnabled(false); // clear drawing cache


                try {

                    String root = Environment.getExternalStorageDirectory().toString();
                    File myDir = new File(root + "/DCIM/QR codes");
                    myDir.mkdirs();


                    String fname = clipTxt+".png";
                    File file = new File (myDir, fname);

                    if (file.exists ()) file.delete ();
                    try {
                        FileOutputStream out = new FileOutputStream(file);
                        bm.compress(Bitmap.CompressFormat.PNG, 100, out);
                        Toast.makeText(BarcodeWriter.this, "Image Saved", Toast.LENGTH_SHORT).show();
                        out.flush();
                        out.close();

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    Uri contentUri = Uri.fromFile(file);
                    mediaScanIntent.setData(contentUri);
                    getApplicationContext().sendBroadcast(mediaScanIntent);

                    Toast.makeText(this,"QR Code showing "+clipTxt,Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    Toast.makeText(this, "Error occurred. Please try again later.",
                            Toast.LENGTH_SHORT).show();
                }



            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }else{ //If no text display a dialog.

            Toast.makeText(this,"No text in clipboard",Toast.LENGTH_SHORT).show();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您的代码似乎很好,我看到的唯一一件事就是您在调用displayImage后立即从Universal Image Loader获取Bitmap和外部URL。因此,对于网络中的某些延迟,有时您的ImageView仍然没有整个图像,并且可能会使您的位图保存为黑色。

请尝试将ImageLoader.getInstance().displayImage内的所有代码移到onLoadingComplete内,如下所示:

    ImageLoader.getInstance().displayImage(fullUrl, qrImg, defaultOptions,  new SimpleImageLoadingListener()
    {        

        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
             ImageLoader.getInstance().displayImage(fullUrl, qrImg, defaultOptions,null);
             qrImg.setDrawingCacheEnabled(true);
             ...
             catch (Exception e) {
                Toast.makeText(this, "Error occurred. Please try again  later.",
                        Toast.LENGTH_SHORT).show();
            }

        }
    });

希望这有帮助!!