Move IMAP Mail Message: The requested folder could not be found.

 

 

메일함을 못찾아와서 발생하는 에러....

뻔히 있는데 왜 찾질 못하니..... 너만 못찾아ㅠㅠ

 

해결방안 : 속성창을 잘 확인해보자~

Move IMAP Mail Message To Folder 액티비티 속성

- FromFolder : 이동할 메일이 있는 폴더

- MailFolder : 메일이 이동할 폴더

 

 

두 가지 속성을 잘 확인해봐야한다...!!

그리고 폴더명의 스펠링같은걸 잘 확인해야하고,

예를 들어 A안에 B에 넣어야하면 A\B를 해야한다

 

 

 

서버나, 오케스트레이터를 일체 사용하지 않고 프로젝트를 진행해야 하며, 로봇의 형태는 Attended.

Window에 있는 "자격 증명 관리자" 에서 크리덴셜을 관리하는 방법이다!!

 

윈도우 자격 증명 관리지 (웹 자격 증명이 아닌 Window 자격 증명에서 작업을 해야한다.)

 

근데 여기서 일일이 추가해줄 필요는 없고, 액티비티로 Window 자격 증명을 추가해줄 수 있다.

 

 

** 관련 페이지

https://www.uipath.com/kb-articles/how-to-work-with-windows-credentials

 

How to work with Windows Credentials

Work with Windows Credentials in UiPath. Train and design robots that drive the user interface like humans. Automate rule based business and IT processes

www.uipath.com

https://docs.uipath.com/activities/docs/add-credential

 

Add Credential

UiPath.Credentials.Activities.AddCredential Stores a specified credential in the Windows Credential Manager with a custom persistence type, and returns a boolean value to let you know if the process was successful or not. Properties Input Username - The us

docs.uipath.com

https://docs.uipath.com/activities/docs/get-secure-credential

 

Get Secure Credential

UiPath.Credentials.Activities.GetSecureCredential Retrieves the credentials from a specified target from the Windows Credential Manager as a secure string (password) and a string (username). Additionally, a boolean value is returned to let you know if the

docs.uipath.com

 

 

1. 일단 첫번째로 Credential 과 관련된 패키지를 설치해야한다.

 

 

 

2. 두번째는 자격증명을 추가해주는, Add Credential 액티비티이다.

Add credemtial 액티비티
Add Credential 액티비티 속성

 

여기에 나와있는 username이 아이디와 이메일이 되고, password는 비밀번호가 된다.

Target은 이 크리덴셜의 이름이라고 생각하면 된다.

 

주의해야할점이 Credential Type 과 Persistance Type 속성인데 다음을 참고하시길...

CredentialType : 추가 할 자격 증명 유형입니다. 다음과 같은 옵션을 사용할 수 있습니다.
None  자격 증명 유형이 적용되지 않습니다. 이로 인해 자격 증명이 저장되지 않을 수 있습니다.
Generic (일반적으로 Generic을 사용한다.) 특정 인증 패키지에서 사용하지 않는 일반 자격 증명입니다.
DomainPassword  Microsoft 인증 패키지 (NTLM, Kerberos, Negotiate)에 특정한 암호 자격 증명입니다.
DomainCertificate  Microsoft 인증 패키지 (Kerberos, Negotiate, Schannel)와 관련된 인증서 자격 증명입니다.
DomainVisiblePassword
Microsoft 인증 패키지 (여권)와 관련된 암호 자격 증명입니다.

 

PersistanceType : 주어진 자격 증명이 저장되는 규칙을 정의합니다. 다음과 같은 옵션을 사용할 수 있습니다.
Session  자격 증명은 현재 로그온 세션 동안 만 Windows 자격 증명 관리자에 저장됩니다. 동일한 사용자의 다른 로그온 세션에는 표시되지 않습니다. 이 사용자가 로그 오프했다가 다시 로그온 한 후에는 존재하지 않습니다.
LocalComputer  자격 증명은이 동일한 컴퓨터에서 모든 후속 로그온 세션에 대해 유지됩니다. 동일한 시스템에서이 동일한 사용자의 다른 로그온 세션에서는 볼 수 있지만 다른 시스템에서이 사용자의 로그온 세션에서는 볼 수 없습니다.
Enterprise 자격 증명은 동일한 컴퓨터에서 모든 후속 로그온 세션에 대해 유지됩니다. 동일한 컴퓨터에서 동일한 사용자의 다른 로그온 세션과 다른 컴퓨터에서이 사용자의 세션에 표시됩니다.

 

Add Credential 에서 지정해주는 세 개의 속성 Username, password, Target은

Window 자격 증명 관리에서 직접 추가해주는 credential 의 속성과 매칭된다!!!

그래서 add credential 안해주고 직접 credential을 만들어 줘도 되지만, Get 할때 속성을 똑같이 입력해야한다는것!!

요런 식으로 각 id, password, 인터넷 또는 네트워크주소(= Target) 값이 매칭이 된다!!

 

 

 

3. 세번째는 추가한 자격증명을 가져와주는 get secure Credential 액티비티이다.

Get secure credential 액티비티
Get secure Credential 액티비티 속성

 

이렇게 만들었던 속성값을 똑같이 주어서 데려온다!

그려면 최종적으로 오케스트레이터의 사용 없이 크리덴셜을 사용할 수 있다.

 

 

credential_practice.xaml
0.00MB

 

 

이제까지 outlook만 사용해봐서 pop3 메일 관련한 액티빝티를 써보지 못했다.

근데 pop3는 outlook처럼 어떤 특정한 프로그램이 없어도

포트번호, 서버, 이메일, 패스워드만 있으면 메일 기능을 사용할 수 있었다.

 

 

POP3 액티비티

 

POP3 액티비티 속성

 

이런 방식으로 사용할 수 있었고,

Top 속성을 이용해서 상위 몇개부터 가져올 수 있는지도 설정할 수 있었다.

Options 속성에 나와있는 것들대로 속성을 주면 그만큼 필터링 된 정보를 얻을 수 있다.

 

이 액티비티는 내가 받은 메일 등을 가져올 수 있는 액티비티 이기 때문에, 보내는 것은 할 수 없다.

받은 메일은 List 형식으로 저장이 되는데, Type Argument는 <MailMessage> 이다.

 

연습했던 파일을 첨부하겠다.

 

pop3_practice.xaml
0.01MB

 

Caused by: java.lang.IllegalStateException: Not allowed to start service Intent : app is in background uid UidRecord{72d8d10 u0a147 TRNB idle procs:1 seq(0,0,0)}

 

환경 : 앱이 종료된 상태에서 이벤트를 실행

오류 원인 : Android O 버전 이상에서의 백그라운드 실행 거부

해결방안 : https://deje0ng.tistory.com/51

 

(다음 포스팅을 참고 했습니다. -> https://parkho79.tistory.com/12)

 

 

백그라운드 상태에서 (앱이 완전히 종료된 상태)

서비스를 실행할 수 있는 이벤트를 주었더니 다음과 같은 에러문이 나왔다.

Caused by: java.lang.IllegalStateException: Not allowed to start service Intent

 

찾아보니, Android O 버전 이상부터는 백그라운드 실행이 제한되었다고 한다.

그래서 Foreground service 를 사용해야한다.

 

관련 Android Developers 문서는 다음과 같다.

https://developer.android.com/about/versions/oreo/background?hl=ko#services

 

백그라운드 실행 제한  |  Android 개발자  |  Android Developers

Android 8.0 이상을 대상으로 하는 앱에 대한 새로운 백그라운드 제한.

developer.android.com

 

서비스를 호출해야한다면, 다음과 같이 코드를 변경해야한다.

1. 서비스 호출

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(new Intent(context, TestService.class));
} else {
    context.startService(new Intent(context, TestService.class));
}

2. 서비스 실행

public class TestService extends Service
{
    @Override
    public void onCreate() {
        super.onCreate();
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            final String strId = getString(R.string.noti_channel_id);
            final String strTitle = getString(R.string.app_name);
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel channel = notificationManager.getNotificationChannel(strId);
            if (channel == null) {
                channel = new NotificationChannel(strId, strTitle, NotificationManager.IMPORTANCE_HIGH);
                notificationManager.createNotificationChannel(channel);
            }
 
            Notification notification = new NotificationCompat.Builder(this, strId).build();
            startForeground(1, notification);
        }
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            stopForeground(true);
        }
    }
}

 

 

The given artifact contains a string literal with a package reference 'Android.support.v4.content' that cannot be safely rewritten. Libraries using reflection such as annotation processors need to be updated manually to add support for androidx.

 

환경 : Butterknife 사용

오류 원인 : Butterknife 가 최신 버전이 아니라서 andoidx 를 지원해주지 않음.

해결방안 : 

Build(.app) 에 다음과 같이 Butterknife 를 최신 버전으로 업그레이드.

dependencies {
	implementation 'com.jakewharton:butterknife:10.0.0'
	annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'
}

 

+) 최신 Android Studio 에서는 complie 대신에 implementation을 사용하라는 에러가 발생하기 시작함

+) 기존의 Butterknife 를 사용한 블로거들의 포스팅 날짜를 잘 살펴봐야함!! 그들의 포스팅이 도움은 되나, 2020 최신 포스팅이 아니기 때문에 Butterknife 버전도 다르고, Butterknife의 버전을 높였을 때의 사용하는 메서드도 달라짐ㅜ 결국 Butterknife를 버전 업그레이드 했다면, 기존에 썻던 Butterknife 관련 메서드들을 바꿔야함.

Static interface methods are only supported starting with Android N (--min-api 24): void butterknife.Unbinder.lambda$static$0()

 

환경 : Butterknife 사용

오류 원인 : Build(.app) 에 complie 옵션을 지정해주지 않음.

해결방안 : 

Build(.app) 의 android { } 안에 다음과 같이 명시

android {

	...

	// 아래와 같이 명시 !!
	compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    
}

 

 

.... 살면서 이렇게 조급하게 삽질 해봤을까 싶다.

결론은 기본에 충실해야한다는 것을 깨달았다......

 

 

1. Manifest.xml - Permission 정의

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="패키지명">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyReceiver"
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE"></action>
            </intent-filter>
        </receiver>

    </application>

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

</manifest>

https://developer.android.com/reference/android/telephony/TelephonyManager#EXTRA_INCOMING_NUMBER

다음의 Android Developer에 명시되어있었다.

이전까지는 READ_PHONE_STATE READ_CALL_LOG 를 permission을 허용해야한다는 것을..... 

 

 

2. MyReceiver.java - Broadcast Receiver 명시

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
        // 리시버 상태 체크
        //Toast.makeText(context, "Event !!!", Toast.LENGTH_SHORT).show();

        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
        String phoneNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

        if (phoneNumber == null ) {
            Log.i("call-state", " : NULL");
        } else {
            if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)) {
                Toast.makeText(context, "call Active", Toast.LENGTH_SHORT).show();
            } else if (TelephonyManager.EXTRA_STATE_IDLE.equals(state)) {
                Toast.makeText(context, "No call", Toast.LENGTH_SHORT).show();
            } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
                Toast.makeText(context, "Ringing State", Toast.LENGTH_SHORT).show();
                Toast.makeText(context, phoneNumber, Toast.LENGTH_SHORT).show();
            }
        }

    }
}

if (phoneNumber == null ) 은 수신이 두 번 호출될 때를 위해서 사용한다.

if문 없이 Toast로 띄워보면 알겠지만, 수신이 2번 호출이 된다.

그래서 처음에는 공백으로, 두번째에 되서야 전화번호를 읽어온다.

그렇기 때문에 처음에 phoneNumber가 공백일때를 처음 if문 처리를 해주면 된다.

 

 

3. 앱에서의 Permission 허용하기

다음과 같이 실제로 앱에 permission을 줘야한다.

직접적으로 이렇게 눌러서 권한을 주는 방법도 있지만,

 

 

선호하는 방법은 사용자에게 권한을 부여해달라고 직접 코드를 짜는 것 이다. (사용자에게 편리하도록..ㅋㅋ)

사용자에게 권한을 주는 코드는 다음과 같다.

 

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(MainActivity.this
                    , new String[]{Manifest.permission.READ_CALL_LOG
                            , Manifest.permission.READ_PHONE_STATE}
                            ,1);
        }


    }
}

 

 

폰넘버가 뭐라고 이게 이렇게 어려웠을까.....

ㅠㅠ 역시 게을렀기 때문이라고 한다....ㅎ

 

 

+ Recent posts