2016-07-19 23 views
0

Ich bin immer noch ein Anfänger in Bezug auf Java und Android-Programmierung, ich glaube, ich bin weit in den letzten Wochen gekommen, aber jetzt bin ich ein wenig fest und ich würde wirklich schätzen Ihre Hilfe.Make updated image bleiben nach Layout/Activity change

Ich versuche eine App zu entwickeln, die ein Benutzerprofil Layout erstellen kann. Bis jetzt habe ich es fertig und zeichne die Daten des Benutzers von einem Webservice. Aber jetzt muss ich einen Weg für den Benutzer hinzufügen, um sein Foto von der Galerie oder Kamera hochzuladen. Bisher habe ich dies mit dem nächsten Code erreicht:

public void loadimage (View view) 
{ 
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    startActivityForResult(intent, 0); 
} 

public void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    super.onActivityResult(requestCode, resultCode, data); 

    if (resultCode == RESULT_OK) 
    { 
     Uri targetUri = data.getData(); 
     picture_location = targetUri.toString(); 
     textTargetUri.setText(picture_location); 
     Bitmap bitmap; 
     try 
     { 
      bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri)); 
      targetImage.setImageBitmap(bitmap); 
     } 
     catch (FileNotFoundException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

Das funktioniert wirklich in das Bild von der Galeere Zeichnen und Anzeigen der Pfaddatei auf dem Bildschirm jedoch (na ja, das ist nicht gonna machen es auf meine endgültige Fassung) Wenn ich ein anderes Layout/eine andere Aktivität eingebe, wird das geladene Bild ausgeblendet und ich muss es erneut hochladen. Ich versuche, mit der nächsten Speichermethode:

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{ 
    image = savedInstanceState.getParcelable("BitmapImage"); 
    targetImage.setImageBitmap(image); 
    textTargetUri.setText(savedInstanceState.getString("path_to_picture")); 
} 

@Override 
public void onSaveInstanceState (Bundle savedInstanceState) 
{ 
    super.onSaveInstanceState(savedInstanceState); 
    savedInstanceState.putParcelable("BitmapImage", bitmap); 
    savedInstanceState.putString("path_to_picture", picture_location); 
} 

Allerdings funktioniert dies nur auf sreen orientarion Änderungen, nicht für das Layout/Aktivitätsänderungen. Gibt es eine Möglichkeit, das hochgeladene Bild beizubehalten, obwohl sich die Aktivität ändert? Mein Server ist ziemlich klein in Bezug auf Speicher, daher ist das Hochladen keine gute Option, ich muss es lokal halten. Bitte helfen :(

+0

Warum speichern Sie nicht einfach das Image-URI irgendwo und laden dann das Image von diesem URI zu ImageView? – Eenvincible

Antwort

1

diese beiden Methoden versuchen:

Zuerst ihnen ein Dialog Option auszuwählen:

private void selectImage() { 
    final CharSequence[] items = { getString(R.string.take_photo), getString(R.string.choose_from_gallery), 
      getString(R.string.cancel) }; 

    AlertDialog.Builder builder = new AlertDialog.Builder(MyAccountActivity.this); 
    builder.setTitle(getString(R.string.upload_photo)); 
    builder.setItems(items, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int item) { 
      if (items[item].equals(getString(R.string.take_photo))) { 
       Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
       startActivityForResult(intent, REQUEST_CAMERA); 
      } else if (items[item].equals(getString(R.string.choose_from_gallery))) { 
       Intent intent = new Intent(
         Intent.ACTION_PICK, 
         android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
       intent.setType("image/*"); 
       startActivityForResult(
         Intent.createChooser(intent, getString(R.string.select_file)), 
         SELECT_FILE); 
      } else if (items[item].equals(getString(R.string.choose_from_gallery))) { 
       dialog.dismiss(); 
      } 
     } 
    }); 
    builder.show(); 
} 

Empfang des aktuellen Bildes, wenn ein Benutzer Bild oder ausgewählt aus der Galerie übernommen hat:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (resultCode == Activity.RESULT_OK) { 
     if (requestCode == SELECT_FILE) 
      onSelectFromGalleryResult(data); 
     else if (requestCode == REQUEST_CAMERA) 
      onCaptureImageResult(data); 
     else if (requestCode == Crop.REQUEST_CROP) { 
      handleCrop(resultCode, data); 
     } 
    } 
} 

Weiter ist Zuschneiden zu behandeln, wenn Sie brauchen - dies nicht erforderlich ist, diesen Code zu arbeiten, aber Sie können es verwenden,

private void onCaptureImageResult(Intent data) { 

    beginCrop(data.getData()); 
} 

@SuppressWarnings("deprecation") 
private void onSelectFromGalleryResult(Intent data) { 
    Uri selectedImageUri = data.getData(); 

    beginCrop(selectedImageUri); 
} 

private void beginCrop(Uri source) { 
    Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped")); 
    Crop.of(source, destination).asSquare().start(this); 
} 

private void handleCrop(int resultCode, Intent result) { 
    if (resultCode == RESULT_OK) { 

     try { 
      Bitmap bitmap = handleSamplingAndRotationBitmap(this, Crop.getOutput(result)); 

      saveToInternalStorage(bitmap); 

      mUserProfilePhoto.setImageBitmap(readFromInternalStorage("profile.png")); 
     }catch (IOException e){ /* do nothing here */} 
    } else if (resultCode == Crop.RESULT_ERROR) { 
     Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show(); 
    } 
} 

Manchmal möchten Sie vielleicht das Bild drehen, wenn es nicht aufrecht ist:

private static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage) throws IOException { 
    int MAX_HEIGHT = 1024; 
    int MAX_WIDTH = 1024; 

    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    InputStream imageStream = context.getContentResolver().openInputStream(selectedImage); 
    BitmapFactory.decodeStream(imageStream, null, options); 
    imageStream.close(); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    imageStream = context.getContentResolver().openInputStream(selectedImage); 
    Bitmap img = BitmapFactory.decodeStream(imageStream, null, options); 

    img = rotateImageIfRequired(img, selectedImage); 
    return img; 
} 

private static int calculateInSampleSize(BitmapFactory.Options options, 
             int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     // Calculate ratios of height and width to requested height and width 
     final int heightRatio = Math.round((float) height/(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will guarantee a final image 
     // with both dimensions larger than or equal to the requested height and width. 
     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 

     // This offers some additional logic in case the image has a strange 
     // aspect ratio. For example, a panorama may have a much larger 
     // width than height. In these cases the total pixels might still 
     // end up being too large to fit comfortably in memory, so we should 
     // be more aggressive with sample down the image (=larger inSampleSize). 

     final float totalPixels = width * height; 

     // Anything more than 2x the requested pixels we'll sample down further 
     final float totalReqPixelsCap = reqWidth * reqHeight * 2; 

     while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
      inSampleSize++; 
     } 
    } 
    return inSampleSize; 
} 

private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException { 

    ExifInterface ei = new ExifInterface(selectedImage.getPath()); 
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

    switch (orientation) { 
     case ExifInterface.ORIENTATION_ROTATE_90: 
      return rotateImage(img, 90); 
     case ExifInterface.ORIENTATION_ROTATE_180: 
      return rotateImage(img, 180); 
     case ExifInterface.ORIENTATION_ROTATE_270: 
      return rotateImage(img, 270); 
     default: 
      return img; 
    } 
} 

private static Bitmap rotateImage(Bitmap img, int degree) { 
    Matrix matrix = new Matrix(); 
    matrix.postRotate(degree); 
    Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true); 
    img.recycle(); 
    return rotatedImg; 
} 

Denn sobald die Speicherung, wenn der Benutzer die Galerie nimmt oder nimmt von Kamera:

private boolean saveToInternalStorage(Bitmap image) { 

    try { 
     FileOutputStream fos = this.openFileOutput("profile.png", Context.MODE_PRIVATE); 

     image.compress(Bitmap.CompressFormat.PNG, 100, fos); 
     fos.close(); 

     return true; 
    } catch (Exception e) { 
     return false; 
    } 
} 

Jetzt zum Lesen aus dem Speicher:

private Bitmap readFromInternalStorage(String filename){ 
    try { 
     File filePath = this.getFileStreamPath(filename); 
     FileInputStream fi = new FileInputStream(filePath); 
     return BitmapFactory.decodeStream(fi); 
    } catch (Exception ex) { /* do nothing here */} 

    return null; 
} 

Inside onResume, ich ha habe diesen Code, um das Bild zu Imageview zu setzen:

@Override 
public void onResume(){ 
    super.onResume(); 

    Bitmap savedProfilePhoto = readFromInternalStorage("profile.png"); 

    if (savedProfilePhoto != null){ 
     mUserProfilePhoto.setImageBitmap(savedProfilePhoto); 
    } 
} 

Fast hier getan:

Fügen Sie diese auf Ihre Abhängigkeiten (build.gradle)

dependencies{ 
    compile 'com.soundcloud.android:android-crop:[email protected]' 
} 

schließlich in Ihrem Android-Manifest-Datei, dies für das Zuschneiden Bibliothek zu arbeiten, fügt:

<activity android:name="com.soundcloud.android.crop.CropImageActivity"/> 

das ist alles, was Sie von ga Auswählen von Bild aktivieren müssen oder fotografieren Sie mit Ihrer Kamera in Ihrer App!

Ich hoffe, das hilft Ihnen und allen anderen in Not und viel Glück!

+0

Wow Kumpel, das ist so komplett, Entschuldigung, so spät zu antworten, ich war gestern mit anderen Dingen beschäftigt. Ich werde deine Methode jetzt ausprobieren. So vielen Dank Eenvincible !! – mrRSA

+0

Wenn es hilft, bitte denken Sie daran zu stimmen und akzeptieren Sie es; Ich benutze diesen Code in meinem Projekt tatsächlich und funktioniert gut – Eenvincible

+0

Noch eine Sache, verwenden Sie externe Bibliotheken? – mrRSA