이미지를 sdcard에 저장했는데 sdcard를 꺼내서 다시 돌려 줄 때까지 갤러리 애플리케이션에 표시되지 않습니다.
왜 그런지 아십니까?
갤러리 애플리케이션에 파일 저장시 업데이트되지 않는 캐시가있는 것 같습니다.
사실, 나는 또한 갤러리 응용 프로그램에서 방금 저장 한 이미지를 열 것을 아무 성공이 없다 할
이 이 문제에 대한 내 질문입니다.
답변:
시스템은 새 이미지 (및 기타) 파일을 찾기 위해 마운트 될 때 SD 카드를 스캔합니다. 프로그래밍 방식으로 파일을 추가하는 경우 다음 클래스를 사용할 수 있습니다.
http://developer.android.com/reference/android/media/MediaScannerConnection.html
더 간단한 해결책은 정적 편의 메서드 scanFile () 을 사용하는 것입니다 .
File imageFile = ...
MediaScannerConnection.scanFile(this, new String[] { imageFile.getPath() }, new String[] { "image/jpeg" }, null);
this
당신의 활동은 어디에 있든 (또는 어떤 컨텍스트 든), mime-type은 비표준 파일 확장자를 사용하고있는 경우에만 필요하고 null
는 선택적 콜백을위한 것입니다 (이런 간단한 경우에는 필요하지 않습니다).
원래 질문 및이 문제가있을 수있는 다른 사람에 대한 나의 대답 :
나는 사람들이 SD 카드에 저장 한 내 앱의 이미지가 갤러리에 즉시 표시되지 않는 동일한 문제가 발생했습니다. 몇 가지 검색 후 문제를 해결 한 'sdcard에 저장'코드 뒤에 삽입 된 코드 한 줄을 발견했습니다.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
의도에 따라 이미지를 미디어 갤러리에 추가 할 수도 있습니다. 예제 코드를 살펴보고 어떻게 수행되는지 확인하세요.
ContentValues image = new ContentValues();
image.put(Images.Media.TITLE, imageTitle);
image.put(Images.Media.DISPLAY_NAME, imageDisplayName);
image.put(Images.Media.DESCRIPTION, imageDescription);
image.put(Images.Media.DATE_ADDED, dateTaken);
image.put(Images.Media.DATE_TAKEN, dateTaken);
image.put(Images.Media.DATE_MODIFIED, dateTaken);
image.put(Images.Media.MIME_TYPE, "image/png");
image.put(Images.Media.ORIENTATION, 0);
File parent = imageFile.getParentFile();
String path = parent.toString().toLowerCase();
String name = parent.getName().toLowerCase();
image.put(Images.ImageColumns.BUCKET_ID, path.hashCode());
image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name);
image.put(Images.Media.SIZE, imageFile.length());
image.put(Images.Media.DATA, imageFile.getAbsolutePath());
Uri result = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
Uri
된 이미지 를 확인하여 확인 했지만 삽입 된 이미지가 갤러리에 표시되지 않는 것이 문제입니다. 나는 갤러리의 시작과 끝에서 모두 확인했습니다. 삽입 된 이미지가 갤러리에 즉시 표시되도록 방법을 제안 해 주시겠습니까?
Android KITKAT을 포함한 갤러리 새로 고침
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
else
{
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
MediaScannerConnection에 대한 코드는 다음과 같습니다.
MyMediaConnectorClient client = new MyMediaConnectorClient(newfile);
MediaScannerConnection scanner = new MediaScannerConnection(context, client);
client.setScanner(scanner);
scanner.connect();
newfile은 새 / 저장된 파일의 파일 개체입니다.
MyMediaConnectorClient
...
활동에서 'MediaScannerConnectionClient'를 구현하고이를 활동에 추가합니다.
private void startScan()
{
if(conn!=null) conn.disconnect();
conn = new MediaScannerConnection(YourActivity.this,YourActivity.this);
conn.connect();
}
@Override
public void onMediaScannerConnected() {
try{
conn.scanFile(yourImagePath, "image/*");
} catch (java.lang.IllegalStateException e){
}
}
@Override
public void onScanCompleted(String path, Uri uri) {
conn.disconnect();
}
Uri
, 예를 들어, 이미지를 :content://media/external/images/media/1231778
이 작품은 나와 함께
File file = ..... // Save file
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
File folderGIF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/newgif2"); //path where gif will be stored
success = folderGIF.mkdir(); //make directory
String finalPath = folderGIF + "/test1.gif"; //path of file
.....
/* changes in gallery app if any changes in done*/
MediaScannerConnection.scanFile(this,
new String[]{finalPath}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
여기에서는 비트 맵 형식으로 이미지를로드하고 해당 이미지를 앱 이름 폴더의 sdcard 갤러리에 저장할 수있는 코드를 공유하고 있습니다. 다음 단계를 따라야합니다.
private Bitmap loadBitmap(String url) {
try {
InputStream in = new java.net.URL(url).openStream();
return BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
uses-permission android:name="android.permission.INTERNET"
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
void saveMyImage(String appName, String imageUrl, String imageName) {
Bitmap bmImg = loadBitmap(imageUrl);
File filename;
try {
String path1 = android.os.Environment.getExternalStorageDirectory()
.toString();
File file = new File(path1 + "/" + appName);
if (!file.exists())
file.mkdirs();
filename = new File(file.getAbsolutePath() + "/" + imageName
+ ".jpg");
FileOutputStream out = new FileOutputStream(filename);
bmImg.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
ContentValues image = new ContentValues();
image.put(Images.Media.TITLE, appName);
image.put(Images.Media.DISPLAY_NAME, imageName);
image.put(Images.Media.DESCRIPTION, "App Image");
image.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
image.put(Images.Media.MIME_TYPE, "image/jpg");
image.put(Images.Media.ORIENTATION, 0);
File parent = filename.getParentFile();
image.put(Images.ImageColumns.BUCKET_ID, parent.toString()
.toLowerCase().hashCode());
image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, parent.getName()
.toLowerCase());
image.put(Images.Media.SIZE, filename.length());
image.put(Images.Media.DATA, filename.getAbsolutePath());
Uri result = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
Toast.makeText(getApplicationContext(),
"File is Saved in " + filename, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
KITKAT에서 작동하지 않는 것 같습니다. 권한 거부 예외 가 발생하고 앱이 충돌합니다. 그래서 이것을 위해 다음을 수행했습니다.
String path = mediaStorageDir.getPath() + File.separator
+ "IMG_Some_name.jpg";
CameraActivity.this.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
.parse("file://" + path)));
도움이되기를 바랍니다.
이미지 저장 후 사용
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
MyMediaConnectorClient에 대한 내 코드 :
public class MyMediaConnectorClient implements MediaScannerConnectionClient {
String _fisier;
MediaScannerConnection MEDIA_SCANNER_CONNECTION;
public MyMediaConnectorClient(String nume) {
_fisier = nume;
}
public void setScanner(MediaScannerConnection msc){
MEDIA_SCANNER_CONNECTION = msc;
}
@Override
public void onMediaScannerConnected() {
MEDIA_SCANNER_CONNECTION.scanFile(_fisier, null);
}
@Override
public void onScanCompleted(String path, Uri uri) {
if(path.equals(_fisier))
MEDIA_SCANNER_CONNECTION.disconnect();
}
}
갤러리의 이미지가 대신 표시되지 않으면 중간에 404 유형 비트 맵이 표시 될 수있는 경우에도 문제가 해결됩니다. 갤러리에 이미지를 표시하려면 메타 데이터가 있어야하므로 내 코드에있는 태그를 이미지와 함께 추가하세요.
String resultPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES)+
getString(R.string.directory) + System.currentTimeMillis() + ".jpg";
new File(resultPath).getParentFile().mkdir();
try {
OutputStream fileOutputStream = new FileOutputStream(resultPath);
savedBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e2) {
e2.printStackTrace();
}
savedBitmap.recycle();
File file = new File(resultPath);
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Photo");
values.put(MediaStore.Images.Media.DESCRIPTION, "Edited");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis ());
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
values.put("_data", resultPath);
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
return resultPath;
이것을 시도하면 생성 된 새 이미지에 대해 방송되므로 이미지가 표시됩니다. 갤러리 내부. photoFile 새로 생성 된 이미지의 실제 파일 경로로 대체
private void galleryAddPicBroadCast() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(photoFile);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}