\ '분류 전체보기' 카테고리의 글 목록 (5 Page) :: Something New
728x90
반응형

1. aws 가입하기

2. 루트사용자로 로그인하기

3. ec2에 들어가서 인스턴스 시작하기

4. 이름 및 태그를 지정하기

5.ubuntu서버로 지정하기

6.프리티어 사용가능한 걸로 지정해주고

7.키페어를 생성해서 로컬에 저장

8.스토리지는 최대인 30으로 지정하면 인스턴스시작

 

mobaxterm 다운로드하기

https://mobaxterm.mobatek.net/download.html

 

MobaXterm free Xserver and tabbed SSH client for Windows

The ultimate toolbox for remote computing - includes X server, enhanced SSH client and much more!

mobaxterm.mobatek.net

installer edition으로 설치해주고

프로그램을 열어서 Sesstions에서

세팅을 해줍니다.

aws에서 만든 인스턴스의 퍼블릭 IPv4주소를 복사해서

Remote host 에 넣어주고

Specify username에는 ubuntu라고 써줍니다.

앞에 생성한 키페어를 Use private key에서 파일 지정해주고 ok를 누룹니다.

 AWS 회원가입과 서버 임대, 접속방식 설정 완료!

728x90
728x90
반응형

안녕하세요 

오랜만에 지브리에서 미야자키 하야오의 작품 그대들은 어떻게 살 것인가 영화 개봉해서

사실 일본에선 7월에 개봉했다고 하네요 그렇지만 일본은 상영기간이 길어서 아직 상영 중이었습니다

 

우리가 다소 이해하기 어려운 관계들과 도대체 어떤 감정의 흐름인지 알기 어려운 장면들이 많았는데요

그것도 다 각자 해석해 보는 재미라고 하길래

저도 제가 본 그대들은 어떻게 살 것인가 영화리뷰를 해보도록 하겠습니다.

 

시대적 배경은 일본 전쟁 중이었고 도쿄생활을 하던 주인공이 

시골로 내려가서 발생하는 이상한 일들이 발단이 됩니다.

 

전체적인 줄거리보다는 몇몇 기억에 남은 의문점들만 얘기를 할게요

 

1. 마히토의 자해?

시골의 학교에 아버지는 일부러 아들을 차로 데려다 줌으로써 우월감을 과시하는 모습과

 

아버지는 아마 돈 많은 아들을 시골학교의 아이들이 부러워하며 따를 것이라고 예상한 것일까요

그렇지만 학교에선 과하게 눈에 들어오는 것 보통 친구들과의 다름은 어울림보단 따돌림에 가까운 접근이죠

이건 돈을 중요시하는 어른의 생각일 수도 있겠네요

갑자기 밭에서 친구와 주먹다짐을 한 마히토는 돌아오는 길에 돌을 주워 자신의 머리를 강하게 칩니다

저는 이 장면을 보고 두 가지를 생각했는데요

첫 번째는 자해를 친구한테 받은 피해라고 말하기 위해?

두 번째는 아파서 학교를 가지 않기 위함?

 

사실 첫 번째가 컸는데 두 번째였던 것 같습니다.

다치고 온 아들을 보호하기 위해 누구한테 맞은 건지 이름을 대라고 화내며 아들 편을 들어주는 아빠

엄마의 여동생과 재혼하고 밤늦게까지 기다리지만 아들은 뒷전인 아빠

전쟁으로 인해 피해보다는 돈을 많이 벌어 기뻐하는 아빠

아들과 아내가 사라진 걸 알고 직접 찾으려 하는 아빠

 

아버지의 캐릭터에 다양한 모습을 볼 수 있었습니다.

단순히 좋은 사람인가 나쁜 사람인가 뭐라고 하기 어려운 면이었습니다

 

2. 새엄마 나츠코와 마히토의 관계 발전

아들이 상처를 입고 학교에서 돌아온 모습을 본 아버지는 나츠코를 탓했지 않았을까 싶다

집에서 자식이 잘못되면 부모탓을 하는 그 시절엔 으레 더 심했을 것도 같은 

입덧이 함께 찾아오고 외로움과 서러움을 느낀 나츠코는 이 세계로 들어가게 되고

현실을 마주하고 싶지 않다는 이유로 나가는 것을 거부한다

나츠코가 있는 방에 히미는 들어가지 못하고 

마히토는 나츠코를 설득한다

그러다 여태 천사 같던 새엄마 나츠코가 히스테릭하고 상처 주는 말들을 하지만

마히토는 끝내 나츠코를 엄마라고 부르게 된다.

사실 둘이 마지막으로 만난 건 입덧으로 힘들어하던 나츠코의 방에 잠시 들렀던 것뿐 같은데...

어느새 엄마가 된겨? 싶었지만

그 사이의 서사를 상상해 보자면

나름 초면부터 잘해주셨고 괜히 아버지에게 서러움을 사게 한 장본인으로서의 미안함을 갖고

또 엄마의 여동생임을 감안..

나츠코의 히스테리는 임신해서 신경이 예민해졌던 걸로,,,

 

3. 블록이 이 세계를 좌우한다

큰 할아버지는 마히토를 이 세계는 바깥세계와 달리 선과 악이 없고 좋으니 네가 차기 왕이 되거라

하는데 그냥 핏줄이 당겼던 것뿐 아닐까

마지막에 깽판이 너무 허술하게 뒤를 밟히고 배신자라고 욕하며 

블록을 대신 쌓으려다 망치는 앵무새는,,,

뭔가 다급하게 치닫는 결말이 허무하기도 했다.

쓰러져가는 탑을 보며 드는 생각은

큰할아버지는 작가 같았고 작가인 미야자키 하야오의 세계관이 무너져내리는 걸까

 

마히토는 큰할아버지의 후계자리 제안을 거절하는데

그 이유는 여기에 있는 것처럼 바깥에서도 좋은 친구들을 사귀고 싶다는 것이었다.

갑자기 왜가리와 히미 같은 친구?

히미는 엄마가 아니라 친구구나

사실은 엄마가 죽은 슬픔에 휩싸인 10대 청소년이 아닌

인생을 함께 나눌 친구들을 원한 거였구나

시골학교에서 뜻대로 되지 않아서 좌절감을 느꼈던 걸까 라는 생각이 들었다.

 

 

지브리 작품을 좋아하는 분들이라면 

지브리의 전작품에서 나왔던 요소들과 겹치는 부분들도 찾을 수 있을 것 같다.

새로운 세계로 통하는 문

하얗고 동그란 인간들

탑 안에서 끊임없이 노동하며 옥상의 정원을 동경하는 삶을 사는 앵무새들

히미의 능력이 불이라는 것

등등 

 

마지막으로 그대들은 어떻게 살 것인가에 답을 해보자면

나는 물 흐르듯이 시간에 맡기고 사소한 감정과 관계 사이에서 행복을 주워가는 삶을 살고 싶다.

 

그 어떤 불안감도 그 어떤 분노도 영원하진 않을 거라 믿는 수밖에

지금이 행복하지 않아 괴롭고 힘들어도 과거의 행복을 태워가며 또 미래의 행복을 기대하며 사는 것

다들 어떤 생각을 하며 영화를 보았나요?

 

그대들은 어떻게 살 것인가요?

 

지브리를 좋아하신다면 추천!

조금 난해함도 좋다면 추천~

 

 

 

728x90
728x90
반응형

 //Web인코딩된 파일명을 디코드해줌
 mFileName = URLDecoder.decode(mFileName, String.valueOf(UTF_8));

서블릿에서 base64디코딩을 해줬어도 서블릿에서 안드로이드로 넘어올때 url인코딩이 되므로

파일명을 한번 더 디코딩해주어야한다.

 

728x90
728x90
반응형

안녕하세요

저는 웹뷰를 이용한 하이브리드 어플을 개발중이구요

오늘 하려는 어플 종료시 어플에서 다운로드한 파일 삭제하기는

제가 어플을 만드는 이유이기도 합니다.

웹은 이미 사용되는 중이었으나 고객이 원한건 웹에서는 cache를 지울수 없기 때문이었습니다.

저는 파일 업로드 및 다운로드 처리를 구현한 상태였구요

제가 다운로드한 path는 내장저장소의 개별어플 안 다운로드폴더 였습니다.

안드로이드의 업데이트로 내장저장소의 개별어플 내부의 디렉토리를 볼 수 없게 된 상태라는 것을 알고

살짝 멘붕에 빠지려던 찰나

캐시파일은 삭제가 가능하다는 document를 보고 다운로드path를 변경했습니다.

 

어플 종료시 작동하는 메소드로 onDestroy()부터 작성합니다.

    public void onDestroy() {
        super.onDestroy();
        deleteCache(getApplicationContext());
    }

이후에 deleteCache를 만들어 줍니다

여기서 File dir = context.getCacheDir(); 이 부분을 getFilesDir().getAbsolutePath();이렇게 바꿔보았으나

아예 디렉토리를 못찾더라구요

        public static void deleteCache(Context context) {
            try {
                File dir = context.getCacheDir();
                deleteDir(dir);
            } catch (Exception e) { 
            	e.printStackTrace();
            }
        }
        
        public static boolean deleteDir(File dir) {
            if (dir != null && dir.isDirectory()) {
                String[] children = dir.list();
                for (int i = 0; i < children.length; i++) {
                    boolean success = deleteDir(new File(dir, children[i]));
                    if (!success) {
                        return false;
                    }
                }
                return dir.delete();
            } else if(dir!= null && dir.isFile()) {
                return dir.delete();
            } else {
                return false;
            }
        }

 

저 같은 상황에 직면하신 분들이 또 계실지는 모르겠으니

다운로드 파일의 path를 캐시폴더로 바꿔줍니다

<웹뷰에서 파일 다운로드는 이 게시물을 참고해주세요>

https://ssomethingnew.tistory.com/37

 request.setDestinationInExternalFilesDir(getApplicationContext(),"/cache/", mFileName );

제가 찾은 답은 이렇게 작성해 주는 것이 었고요

원래는 "/cache/" 이 부분에 getCacheDir()을 넣었는데 getCacheDir()이거 자체에 컨텍스트 path까지 포함되어있어서

앞의 getApplicationContext()  부분의 path가 중복이 되더라고요 

디렉토리 내부에 어떤파일이든 다 삭제하는 것이 목표였기 때문에 저는 전체 삭제 해줬습니다만

혹시 특정 파일명만 삭제하시고 싶으시다면 for문안에 파일명만 지정해주는 것도 좋을 것 같습니다.

치치부에 축제(마쯔리)에 놀러가서 먹은 당고

 

728x90
728x90
반응형

저는 하이브리드 어플을 개발하고 있구요 webview에서 파일 다운로드하고 파일 열기까지 

제가 하는 환경에서 web에서 다운로드매니저로 다운받을때 url에 서버파일의 path가 담겨있지 않아서

웹.서블렛 수정까지 같이 하느라 시간이 많이 걸렸습니다만

여러분의 url에는 파일명과 파일path가 담겨있을거라 생각하고 

파일 다운로드와 intent로 파일열기 검색한대로 했는데 왜 자꾸 커미션 넣으라고만 하냐구요ㅠㅠ

전 커미션 당연히 설정한 상태였습니다.

중요한건 파일명이 url이나 base64로 인코딩된 상태이면 디코딩이 필요할 수 있구요

저는 내부저장소에 개별어플파일안 \내장 저장공간\Android\data\어플이름\files\download에 저장했습니다.

\내장 저장공간\Download에 저장하고 싶으시다면 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mFileName); 

로 바꿔 써주시면 됩니다.

onCreate()안에 여러 웹뷰 세팅하시고 밑의 코드를 넣어주시면 됩니다.

    newWebView.setDownloadListener(new DownloadListener() {

                @Override
                public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
                    try {
                        DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                        DownloadManager.Query query = new DownloadManager.Query();

                        request.setMimeType(mimeType);
                        String cookies = CookieManager.getInstance().getCookie(url);
                        request.addRequestHeader("cookie", cookies);
                        request.addRequestHeader("User-Agent", userAgent);
                        request.addRequestHeader("Referer", getReferrer().getAuthority());
                        request.addRequestHeader("Content-Disposition", contentDisposition);
                        request.setDescription("Downloading file...");
                        String content = contentDisposition;
                        String[] contentSplit = content.split(content);

                        mFileName = content.replace("attachment; filename=", "").trim();
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                            mFileName = URLDecoder.decode( mFileName, UTF_8);
                        }

                        request.setTitle(mFileName);
                        request.allowScanningByMediaScanner();
                        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                        //다운받아서 넣을 파일의 디렉토리 지정해 주세요
                        //request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mFileName); 
                        request.setDestinationInExternalFilesDir(getApplicationContext(),DIRECTORY_DOWNLOADS, mFileName);
                
                        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);

                         dm.enqueue(request);
                       Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show();

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

 

여기까지하시면 다운로드가 됩니다.

다운로드 후에 바로 다운로드한 파일을 열고 싶을 때 밑에 소스를 추가해 주세요

 private final BroadcastReceiver mCompleteReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (ActivityCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                        PackageManager.PERMISSION_GRANTED) {

                    //권한 허가
                    ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1000);
                }
                //파일 다운로드가 완료되었을 때
                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                    Toast.makeText(context, "Complete.", Toast.LENGTH_SHORT).show();
                    long downloadId = intent.getLongExtra(
                            DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                    openDownloadedAttachment(context, downloadId);
                }
            }
        };

여기까지는 흔하게 파일 완료 액션을 잡아서 어찌저찌 했습니다만 중요한건 여기부터 입니다

  private void openDownloadedAttachment(final Context context, final long downloadId) {
            DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downloadId);
            Cursor cursor = downloadManager.query(query);
            //다운로드한 정보를 꺼내서
            if (cursor.moveToFirst()) {
                @SuppressLint("Range") int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                @SuppressLint("Range") String downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                @SuppressLint("Range") String downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
                if ((downloadStatus == DownloadManager.STATUS_SUCCESSFUL) && downloadLocalUri != null) {
                    openDownloadedAttachment(context, Uri.parse(downloadLocalUri), downloadMimeType);
                    mUri = String.valueOf(Uri.parse(downloadLocalUri));
                }
            }
            cursor.close();
        }
        

		//fileprovider로 열기
        private void openDownloadedAttachment(final Context context, Uri attachmentUri, final String attachmentMimeType) {
            if(attachmentUri!=null) {
                // Get Content Uri.
                if (ContentResolver.SCHEME_FILE.equals(attachmentUri.getScheme())) {
                    // FileUri - Convert it to contentUri.
                    File file = new File(attachmentUri.getPath());
                    attachmentUri = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext()
                            .getPackageName()+".provider", file);
                }

                Intent openAttachmentIntent = new Intent(Intent.ACTION_VIEW);
                openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType);
                openAttachmentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                try {
                    context.startActivity(openAttachmentIntent);
                } catch (ActivityNotFoundException e) {
                    Toast.makeText(context, "error", Toast.LENGTH_LONG).show();
                }
            }
        }

 

예전에는  file:/// 형태의 uri 로 가능했다고 하는데

이젠 content://로 바뀌어야해서 fileprovider를 사용해줍니다. 

저는 이 방법을 통해 파일 다운로드 후 pdf파일 열기까지 성공했습니다

hakusyu위스키 공장에서 시음

 

728x90
728x90
반응형

안드로이드는 업데이트가 잦아서 무슨 기능을 검색해서 쓰려고하면

버전이 안맞아서 검색의 무한루프에 빠져버린다

제가 하고 있는 건 웹은 작동하고 있는 환경에서

추가로 어플을 만드는 하이브리드 어플을 만들고 있는 상황입니다.

최신 코드라고 해도 startactivityforresult deprecated되어서 가져다 쓸 수 없었으므로,,

일단 manefest에서 커미션은 허용했다는 전제하에

public class MyWebChromeClient extends WebChromeClient  안에 넣어 주면 됩니다.

  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {

            //파일 업로드 
            if (mFilePathCallback != null) {
                //파일을 한번 열면 초기화 시킬것 안하면 두번째는 반응이 없음
                mFilePathCallback.onReceiveValue(null);
            }
            mFilePathCallback = filePathCallback;

			//WEBVIEW에서 파일을 선택하는 INTENT 작동
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("*/*");  
            
            //이부분이 startactivityforresult을 쓴 사람들이 많았음 deprecated된 부분
            startActivityIntent.launch(intent);
            
            return true;
        }

startactivityforresult deprecated 대체를 검색해서 맞춰서 만든 코드

        ActivityResultLauncher<Intent> startActivityIntent = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                new ActivityResultCallback<ActivityResult>() {
                    @Override
                    public void onActivityResult(ActivityResult result) {
                        if(result.getResultCode() == RESULT_OK) {
                            //파일 선택완료
                            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                mFilePathCallback.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(result.getResultCode(), result.getData()));
                            }else{
                                mFilePathCallback.onReceiveValue(new Uri[]{result.getData().getData()});
                            }
                            mFilePathCallback = null;
                        } else {
                            //취소했을 경우
                            if(mFilePathCallback != null) {
                                mFilePathCallback.onReceiveValue(null);
                                mFilePathCallback = null;
                            }
                        }
                    }
                });

포켓몬 카페 갔을 때 찍은 피카츄

 

 

728x90
728x90
반응형

I was impressed with your presentation

너의 프레젠테이션에 감명을 받았어

I believe in your ability to come out ahead.

결국에는 잘 될 거라고 믿어.

You did a great job on the assignment.

너 과제를 정말 잘했어.

I know that it's hard to hear no all the time.

늘 거절당하는 게 어려운 거 알아.

But we've made it this far.

하지만 우리 여기까지 왔잖아

I believe in your ability to improve.

난 너가 나아질 거라고 믿어.

We're almost there.

우리 거의 다 왔어.

I believe in you.

난 네가 할 수 있을 거라 믿어

I like the way you dress.

네 스타일이 맘에 들어.

I like the way you think.

네 사고방식이 좋아

I like the way you speak with confidence.

네가 자신감을 갖고 말하는 방식이 맘에 들어.

I appreciate it.

정말 고맙게 생각해요.

I appreciate your honesty.

솔직하게 말해줘서 고마워요

I know that it's hard.

어려운걸 알아

I know that it's hard to get over a breakup.

실연을 극복하는 게 어려운 걸 알아.

I know that it's hard to lose someone.

누군가를 잃는다는 게 어려운 걸 알아.

I want you to know that you can call me any time.

네가 언제든지 전화해도 좋단 걸 알아줬으면 해

I know that it's hard to say no.

거절하기 어렵단걸 알아.

I want you to know that we can get through this.

우리가 이겨낼 수 있다는 걸 알아줬으면 해

This too shall pass.

이 또한 지나가리

It couldn't be any better.

더 나을 수 없었어.

I couldn't have done it without you.

너의 도움없이는 못했을 거야.

I'm happy to see that.

 보게 되서 기뻐.

I'm happy to see that you're improving.

네가 발전하는 걸 보게 돼서 기뻐.

I'm happy to see that you're learning new things.

네가 새로운 걸 배우는 걸 보게 돼서 기뻐

I'm happy to see that you've overcome your fear of English.

네가 영어공포증을 극복한 게 보여서 기뻐

I can tell.

알 수 있어 . 느껴져.

I can tell that you worked really hard on this.

네가 이걸 정말 열심히 한 게 보여.

I can tell that you put a lot of thought on this.

네가 신경을 많이 쓴 게 보여.

I want you to know that I'm always here for you/

내가 늘 널 위해 여기 있다는 걸 알아줬으면 해.

 

 

 

 

 

728x90

'영어' 카테고리의 다른 글

[SPEAK어플]고민에 대해 말하고 조언하기  (1) 2022.12.10
728x90
반응형

https://start.spring.io/ 

spring Boot 버전은 최신걸로 선택하지만 SNAPSHOT은 제외

dependencies에서 add를 눌러 web을 추가하고 generate 해서 zip 파일 다운로드하기

Inellij에서 압축해제한 파일 open 하기

스프링부트는 내부 서버에 자동으로 연결된다.

java spring boot로 hello world 출력하기

 

728x90

'JAVA Spring FRAMEWORK' 카테고리의 다른 글

[JAVA]JDBC란?  (0) 2024.11.13
[SQL]Inner Join vs Outer Join  (1) 2024.08.31
디자인 패턴이란?  (0) 2024.06.24
[Spring]FormTag & DataBinding - (1)TextField  (1) 2021.11.29
[Spring MVC]Developing Spring Controllers and Views  (0) 2021.11.17

+ Recent posts