[Android] 사진 저장 후 갤러리에 보이지 않는 경우.

Posted by Find my true self Fimtrus
2014.07.25 10:34 Programming/Android

안드로이드에서 현재 화면을 저장하는 경우, 또는 이미지를 저장하였을 때


갤러리에서 보이지 않는 경우가 있다.


안드로이드에서는 사용자가 가지고 있는 리소스를 디비화 해서 저장하고 있는데,


해당 파일의 정보 및 썸네일까지 담고 있다.


그래서 갤러리 같은 경우, 이미지 파일을 보여주긴 하지만 상당히 빠른 속도로 화면을 볼수 있는 이유 중의 하나이다.


아무튼..갤러리에 보여주기 위해서는 디비에 업데이트 해주는 인텐트가 필요하다. 아니면 별도의 스캐너를 사용해도되고....


간단하게 인텐트를 통해 해당 파일을 업데이트하는 방법이다.




//
context.sendBroadcast(new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)) );
//

context : Activity 또는 해당 어플리케이션의 context

file : 업데이트할 파일 객체.


이 댓글을 비밀 댓글로

[Android, Hybrid] 앱에서 파일 다운로드 구현. URL File Download.

Posted by Find my true self Fimtrus
2014.07.10 15:09 Programming/Android

웹브라우저를 이용해서 파일을 다운로드 받을 경우, 다운로드매니저를 통해 받게 된다.(진저브레드 이상)


앱에서 다운로드 매니저를 사용하여 파일 다운로드 받는 방법을 쓰고자 한다.


앱이나 하이브리드나 다운로드 하는 방법은 동일하다.


다운로드 매소드, 그리고 다운로드매니저로부터 액션을 받을 수 있는 리시버를 만드면 끝.!


Download Method

private DownloadManager mDownloadManager; //다운로드 매니저. 
private int mDownloadQueueId; //다운로드 큐 아이디..
private String mFileName ; //파일다운로드 완료후...파일을 열기 위해 저장된 위치를 입력해둔다.
/**
 * @param url : 파일을 다운로드할 url.
 */
public void download(String url) {
	if (mDownloadManager == null) {
		mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
	}
	Request request = new DownloadManager.Request( Uri.parse(url) );
	request.setTitle("==타이틀==");
	request.setDescription("==설명==");
	List<string> pathSegmentList = uri.getPathSegments();
	Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/temp").mkdirs();  //경로는 입맛에 따라...바꾸시면됩니다.
	request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS + "/temp/", pathSegmentList.get(pathSegmentList.size()-1) );
	mFileName = pathSegmentList.get(pathSegmentList.size()-1);

	mDownloadQueueId = mDownloadManager.enqueue(request);
}



다운로드관련 인텐트를 받을 리시버를 만들고, 등록시켜주면 끝!

(onResume 에서 등록, onPause에서 해제를 추천한다.)


Complete Receiver

/**
 * 다운로드 완료 액션을 받을 리시버.
 */
private BroadcastReceiver mCompleteReceiver = new BroadcastReceiver() {
	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
			Toast.makeText(context, "Complete.", Toast.LENGTH_SHORT).show();
			Intent intent1 = new Intent();
			intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent1.setAction(android.content.Intent.ACTION_VIEW);
			intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

			String localUrl = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
					+ "/temp/" + mFileName; //저장했던 경로..
			String extension = MimeTypeMap.getFileExtensionFromUrl(localUrl);
			String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);

			File file = new File(localUrl);
			intent1.setDataAndType(Uri.fromFile(file), mimeType);
			try {
				startActivity(intent1);
			} catch (ActivityNotFoundException e) {
				Toast.makeText(NPF.this, "Not found. Cannot open file.", Toast.LENGTH_SHORT).show();
				e.printStackTrace();
			}
		}
	}
};


@Override
protected void onPause() {
	super.onPause();
	unregisterReceiver(mCompleteReceiver);
}

@Override
protected void onResume() {
	super.onResume();
	IntentFilter completeFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
	registerReceiver(mCompleteReceiver, completeFilter);
}


하이브리드 앱의 경우 JavaInterface에 해당 method를 넣어주면 되고, 일반적인 앱에서 사용할 경우에는


유틸 같은 곳에 추가하여 사용하면된다.(물론 해당 method를 조금 수정해서 context를 받도록 해야할 것이긴 하지만)



이 댓글을 비밀 댓글로
    • 2014.07.14 09:31
    비밀댓글입니다
    • 조금의(?) 수정
    • 2015.10.21 22:14
    직접 내용을 수정하여 제목, 내용 커스텀 + 경로 지정 가능하게 해보고
    일반 앱에 바로 복붙하고 Import만 하면 가능하게 대충 수정을...

    public void download(String url, String title, String des, String path) {
    DownloadManager mDownloadManager = null; //다운로드 매니저.
    int mDownloadQueueId; //다운로드 큐 아이디..
    String mFileName ; //파일다운로드 완료후...파일을 열기 위해 저장된 위치를 입력해둔다.
    if (mDownloadManager == null) {
    mDownloadManager = (DownloadManager) getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
    }
    DownloadManager.Request request = new DownloadManager.Request( Uri.parse(url) );
    request.setTitle(title);
    request.setDescription(des);
    List<String> pathSegmentList = Uri.parse(url).getPathSegments();
    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/" + path).mkdirs(); //경로는 입맛에 따라...바꾸시면됩니다.
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS + "/" + path + "/", pathSegmentList.get(pathSegmentList.size()-1) );
    mFileName = pathSegmentList.get(pathSegmentList.size()-1);

    mDownloadQueueId = (int) mDownloadManager.enqueue(request);
    }

[Android] Notification 에서 onNewIntent가 타지 않는 문제. How to call onNewIntent from Notification.

Posted by Find my true self Fimtrus
2014.06.26 11:40 Programming/Android

launchMode 가 singleTask 혹은 singleTop 인 Activity에 intent를 보내게 되면,


존재 할 경우 onNewIntent, 존재하지 않을 경우 Activity가 새로 시작하게 된다.


일반적인 방법으로 액티비티를 호출할 때에는 startActivity로 호출하지만,


Notification을 통해 호출할 경우 PendingIntent를 사용하는데,


액티비티의 모드가 singTask, singleTop 이며 존재하는데도 


강제로 액티비티를 재시작시키는 경우가 있다.

(아마도..안드로이드 레퍼런스에 코드만 보고 만들어서 그런건 아닐까 생각이 든다.)


정상적인 Activity lifecycle을 태우기 위해선, PendingIntent 생성시 requestCode를 반드시 넣어야한다.

(대부분 default값으로 0을 넣는다)




대부분 REQUEST_CODE 부분에 0 을 넣는데, private 한 값을 추가시켜주면, 정상적으로 onNewIntent가 불린다.

PendingIntent resultPendingIntent = PendingIntent.getActivity(
        context, REQUEST_CODE, 
        resultIntent, 
        PendingIntent.FLAG_UPDATE_CURRENT);



이 댓글을 비밀 댓글로
    • 날개
    • 2014.11.07 15:14
    private 한 값이 무엇인가요 ?
    • 2015.10.06 09:54
    비밀댓글입니다

[Android] 여러개 Intent를 묶어서 보내기.

Posted by Find my true self Fimtrus
2014.05.29 13:35 Programming/Android

앱을 만들 때, 제조사 또는 버전의 차이로 인해 인텐트 호출후 원하는 리스트가 표시되지 않을 때가 있다.

특히 카메라와 갤러리의 경우가 그렇다.

대부분의 개발자들은 호출 한번으로 카메라와 갤러리를 모두 보여주고 싶은데,

검색능력부족(?)으로 인해, 결국 따로 만드는 경우가 태반이다.

카메라와 갤러리를 동시에 호출할 수 있는 소스를 첨부한다.




먼저 인텐트들을 담을 리스트와와 카메라호출을 위한 인텐트, 그리고 패키지 검색을 위한 패키지 매니저, 마지막으로 카메라 패키지 정보를 담을 변수를 선언한다.


final List<intent> cameraIntents = new ArrayList<intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<resolveinfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);


그리고 검색된 카메라 패키지 정보를 통해 인텐트 리스트를 만든다.


for(ResolveInfo res : listCam) {
    final String packageName = res.activityInfo.packageName;
    final Intent i = new Intent(captureIntent);
    i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
    i.setPackage(packageName);
    i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));
    cameraIntents.add(i);

}


마지막으로 갤러리리를 불러오는 인텐트에 카메라 인텐트정보가 담겨 있는 리스트를 담아주면 끝!


Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
i.addCategory(Intent.CATEGORY_OPENABLE);  
i.setType("image/*"); 
Intent chooserIntent = Intent.createChooser(i,"File Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE); 


이렇게 하면 리스트다이얼로그를 통해 카메라와 갤러리가 함께있는 것을 볼 수 있다.


출처 : 기억안남...

이 댓글을 비밀 댓글로
  1. 테스트해 보기도 전에, 눈이 번쩍 띕니다.
    잘 쓰겠습니다.
    감사합니다.