PromptShadow PromptShadow - 4 months ago 23
Android Question

Android Studio: save image in SD Card

I keep a school project dealing with a ListView filled with images hosted on a server.

When someone selects an image from the list, this is shown by "original" size in another layout and even here everything went well.

But also ask when the image display have the option to save it to the SD Card and that's the part I can not do.

This is the code I did:

public class MainActivity extends AppCompatActivity {

private ListView listView;
private ProgressDialog progressDialog;
ArrayList asuntos=new ArrayList();
ArrayList imagen=new ArrayList();

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolBar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolBar);
listView=(ListView) findViewById(R.id.list);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
lista o=new lista();
o.obtenerAvisos();
}

public class lista {

public void obtenerAvisos() {

asuntos.clear();
imagen.clear();

String tag_string_req = "req_data";

progressDialog.setMessage("Conectando...");
showDialog();

StringRequest strReq = new StringRequest(Request.Method.POST, AppURLs.URL, new Response.Listener<String>() {

public void onResponse(String response) {

hideDialog();

try {

JSONArray jsonArray = new JSONArray(response);

for (int i = 0; i < jsonArray.length(); i++) {
asuntos.add(jsonArray.getJSONObject(i).getString("asunto"));
imagen.add(jsonArray.getJSONObject(i).getString("publicacion"));
}

listView.setAdapter(new ImagenAdaptador(getApplicationContext()));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {

public void onErrorResponse(VolleyError error) {

Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {

protected Map<String, String> getParams() {

Map<String, String> params = new HashMap<String, String>();
params.put("tag", "data");
return params;
}

};
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
}

private void showDialog() {

if (!progressDialog.isShowing())
progressDialog.show();
}

private void hideDialog() {

if (progressDialog.isShowing())
progressDialog.dismiss();
}

public class ImagenAdaptador extends BaseAdapter {

Context ctx;
LayoutInflater layoutInflater;
SmartImageView smartImageView;
TextView tvasunto;

public ImagenAdaptador(Context applicationContext) {

this.ctx=applicationContext;
layoutInflater=(LayoutInflater)ctx.getSystemService(LAYOUT_INFLATER_SERVICE);
}

public int getCount() {
return imagen.size();
}

public Object getItem(int position) {
return position;
}


public long getItemId(int position) {
return position;
}


public View getView(int position, View convertView, ViewGroup parent) {

ViewGroup viewGroup=(ViewGroup) layoutInflater.inflate(R.layout.activity_main_items,null);
smartImageView=(SmartImageView)viewGroup.findViewById(R.id.imagen1);
tvasunto=(TextView) viewGroup.findViewById(R.id.tvAsunto);
final String urlfinal="http://192.168.43.45/InfoTec/publicaciones/"+imagen.get(position).toString();
Rect rect=new Rect(smartImageView.getLeft(), smartImageView.getTop(), smartImageView.getRight(), smartImageView.getBottom());
smartImageView.setImageUrl(urlfinal, rect);
tvasunto.setText(asuntos.get(position).toString());

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this, Visor.class);
intent.putExtra("arg", asuntos.get(position).toString());
intent.putExtra("arg2",imagen.get(position).toString());
startActivity(intent);
}
});
return viewGroup;
}
}
}


This part works, but this class is the problem:

public class Visor extends AppCompatActivity {

TextView tvasunto2;
SmartImageView smartImageView2;
Button descarga;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_visor);
String original=getIntent().getStringExtra("arg");
String imgOriginal=getIntent().getStringExtra("arg2");
tvasunto2=(TextView) findViewById(R.id.tvAsunto2);
smartImageView2=(SmartImageView) findViewById(R.id.imagen2);
descarga=(Button) this.findViewById(R.id.button);

tvasunto2.setText(original);
String url="http://192.168.43.45/InfoTec/publicaciones/"+imgOriginal;
Rect rect=new Rect(smartImageView2.getLeft(), smartImageView2.getTop(), smartImageView2.getRight(), smartImageView2.getBottom());
smartImageView2.setImageUrl(url,rect);

descarga.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

}
});
}
}


If the selected image is displayed, but not now how to handle the data in the event the download button.

What would be the solution?

Answer

First, you need to get your Bitmap. You can already have it as an object Bitmap, or you can try to get it from the ImageView such as:

BitmapDrawable drawable = (BitmapDrawable) mImageView1.getDrawable();
Bitmap bitmap = drawable.getBitmap();

Then you must get to directory (a File object) from SD Card such as:

File sdCardDirectory = Environment.getExternalStorageDirectory();

Next, create your specific file for image storage:

File image = new File(sdCardDirectory, "test.png");

After that, you just have to write the Bitmap thanks to its method compress such as:

boolean success = false;

// Encode the file as a PNG image.
FileOutputStream outStream;
try {

    outStream = new FileOutputStream(image);
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream); 
    /* 100 to keep full quality of the image */

    outStream.flush();
    outStream.close();
    success = true;
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

Finally, just deal with the boolean result if needed. Such as:

if (success) {
    Toast.makeText(getApplicationContext(), "Image saved with success",
            Toast.LENGTH_LONG).show();
} else {
    Toast.makeText(getApplicationContext(),
            "Error during image saving", Toast.LENGTH_LONG).show();
}

Don't forget to add the following permission in your Manifest:

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