팝업

반응형





https://blog.stylingandroid.com/permissions-part-3/

위 블로그 글을 참고 하였고 

프로젝트는 작성자의 깃허브 사이트 

https://github.com/StylingAndroid/Permissions/tree/Part3

를 참고 하였다.


프로젝트를 실행하면 이러한 모습이다



코드를 참고하면서 내 프로젝트에 필요한 것만 참고함.


먼저

PermissionsActivity.java 와 PermissionsChecker.java를 프로젝트에 붙여넣기 하였다.

추가 설명은 코드 내 주석을 달아놓았다.



PermissionsActivity.java

37라인

setContentView(R.layout.new_custom_full);

이 부분은 팝업을 표시할 액티비티의 xml 파일명으로 변경해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
 
 
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
 
public class PermissionsActivity extends AppCompatActivity {
    public static final int PERMISSIONS_GRANTED = 0;
    public static final int PERMISSIONS_DENIED = 1;
 
    private static final int PERMISSION_REQUEST_CODE = 0;
    private static final String EXTRA_PERMISSIONS = "com.stylingandroid.permissions.EXTRA_PERMISSIONS";
    private static final String PACKAGE_URL_SCHEME = "package:";
 
    private PermissionsChecker checker;
    private boolean requiresCheck;
 
    public static void startActivityForResult(Activity activity, int requestCode, String... permissions) {
        Intent intent = new Intent(activity, PermissionsActivity.class);
        intent.putExtra(EXTRA_PERMISSIONS, permissions);
        ActivityCompat.startActivityForResult(activity, intent, requestCode, null);
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {
            throw new RuntimeException("This Activity needs to be launched using the static startActivityForResult() method.");
        }
        setContentView(R.layout.new_custom_full); //xml 파일명 변경 필요
 
        checker = new PermissionsChecker(this);
        requiresCheck = true;
    }
 
    @Override
    protected void onResume() {
        super.onResume();
        if (requiresCheck) {
            String[] permissions = getPermissions();
 
            if (checker.lacksPermissions(permissions)) {
                requestPermissions(permissions);
            } else {
                allPermissionsGranted();
            }
        } else {
            requiresCheck = true;
        }
    }
 
    private String[] getPermissions() {
        return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);
    }
 
    private void requestPermissions(String... permissions) {
        ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
    }
 
    private void allPermissionsGranted() {
        setResult(PERMISSIONS_GRANTED);
        finish();
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {
            requiresCheck = true;
            allPermissionsGranted();
        } else {
            requiresCheck = false;
            showMissingPermissionDialog();
        }
    }
 
    private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }
 
    //모두 거부 하였을 때 나타나는 팝업 창 설정입니다.
    private void showMissingPermissionDialog() {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(PermissionsActivity.this);
        dialogBuilder.setTitle(R.string.help); //팝업 창 타이틀
        //팝업 안내 메시지 부분으로 string.xml에서 설정한 메시지를 노출합니다.
        dialogBuilder.setMessage(R.string.string_help_text);
        //팝업 창 버튼 2개를 노출합니다.
        //확인버튼을 누르면 앱 종료?인데 저는 팝업 창만 사라졌네요
        dialogBuilder.setNegativeButton(R.string.quit, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                setResult(PERMISSIONS_DENIED);
                finish();
            }
        });
        //설정 버튼을 누르면 설정 화면으로 이동합니다.
       dialogBuilder.setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startAppSettings();
            }
        });
        dialogBuilder.show();
    }
 
     private void startAppSettings() {
        Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));
        startActivity(intent);
    }
}
cs



PermissionsChecker.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.content.ContextCompat;
 
class PermissionsChecker {
    private final Context context;
 
    public PermissionsChecker(Context context) {
        this.context = context;
    }
 
    public boolean lacksPermissions(String... permissions) {
        for (String permission : permissions) {
            if (lacksPermission(permission)) {
                return true;
            }
        }
        return false;
    }
 
    private boolean lacksPermission(String permission) {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_DENIED;
    }
 
}
 
cs


발생하는 에러는 알맞게 처리한 다음

AndroidMenifest.xml 에 PermissionsActivity를 추가해준다.

1
2
3
4
5
6
7
8
9
10
        <!--PermissionsActivity 를 추가해줍니다.-->
        <!--팝업 적용을 위해 @style:AppTheme 추가해줍니다-->
        <activity
            android:name="com.yonoo.my.PermissionsActivity"
            android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
            android:label="@string/app_name"
            android:theme="@style/AppTheme"
            android:screenOrientation="nosensor" >
        </activity>
 
cs


권한도 추가

1
2
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
cs



앱 테마 적용을 위해 style.xml에 다음을 추가해준다.

(다국어 설정이 되어있다면 국가별 style.xml에도 추가해준다.)

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<resources>
 
    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>
    <!--팝업 호출을 위해 아래 스타일이 필요합니다.-->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    </style>
</resources>
 
cs


그리고 권한 팝업 노출시 권한 설명을 위한 메시지를 string.xml에 추가하여준다. 마찬가지로 다국어 string에도 추가

이 메시지는 PermissonsActivity의 showMissingPermissionDialog에서 사용된다.

1
2
3
4
5
6
    <!--권한 팝업에서 노출될 메시지를 설정합니다.-->
    <string name="settings">설정</string>
    <string name="help">Help</string>
    <string name="string_help_text"> 저장소와 카메라 권한이 필요합니다. </string>
    <string name="quit">확인</string>
 
cs


그리고 권한 팝업을 띄울 액티비티파일에 다음 코드를 추가해준다.

ex) NewCustomFullActivity 에 권한 팝업을 띄울거라면 변수를 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class NewCustomFullActivity implements OnClickListener{
 
    //권한 체크를 위한 값 선언
    private static final int REQUEST_CODE = 0;
    /*요청받은 권한을 설정합니다. 여기선 저장소와 카메라를 설정
    * android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    * android.Manifest.permission.CAMERA
    * */
    private static final String[] PERMISSIONS = 
            new String[]{
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    android.Manifest.permission.CAMERA
            };
    //PermissionChecker를 사용하기 위해 선언
    private PermissionsChecker checker;
cs


OnCreate에 다음 코드 추가

1
2
//Oncreate 에서 Checker를 호출
checker = new PermissionsChecker(this);
cs


그리고 다음 함수를 추가해준다.

1
2
3
    private void startPermissionsActivity() {
        PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);
    }
cs


이제 팝업을 어디서 띄울지 결정해야했는데 카메라를 선택했을 때 띄우기로 결정

그래서 startActivityForResult(intent, PICK_FROM_CAMERA); 이 부분이 호출될 때 팝업이 뜨게 하였다.

권한 때문에 SecurtiyException 이 발생할 때

1
2
3
4
    //권한을 체크
    if (checker.lacksPermissions(PERMISSIONS)) {
        startPermissionsActivity();
    }
cs

이 부분을 추가해주어 권한 허용 유무를 체크하여 미허용상태면 팝업을 띄우도록 startPermissionsActivity() 을 요청한다.


추가된 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//카메라를 호출할 때 권한이 없으면 권한요청팝업이 뜨도록 설정
try{
    startActivityForResult(intent, PICK_FROM_CAMERA);
}catch (SecurityException e) {
    //권한을 체크
    if (checker.lacksPermissions(PERMISSIONS)) {
        startPermissionsActivity();
    }
    //토스트로 안내메시지도 같이 호출해보았습니다.
    e.printStackTrace();
    if(language.equals("en"|| language.equals("th"|| language.equals("vi"))
        Toast.makeText(getApplicationContext(),
                "check phone settinig >  application manager > app permission Camera approve",
                Toast.LENGTH_LONG).show();
    else
        Toast.makeText(getApplicationContext(),
                "설정 > 애플리케이션 관리자 >앱권한에서 카메라 권한을 허용해주세요",
                Toast.LENGTH_LONG).show();
}
cs


이렇게 해주면 카메라를 킬 때 허용 팝업이 노출된다.


외국인 블로거가 짜놓은 코드를 사용하였기 때문에 자세한 설명보다는 크게 크게 이해해보려고 하였다.

나중을 위해서 적어 놓은건데 빼 먹은 건 없나 모르겠다.


원래는 앱 시작하자마자 팝업 띄우려고 헀는데 뭔가 계속 안된다.. 

그래서 그냥 해당기능 켤 때  띄우는 걸로..


이런 걸 취미로 포스팅 하는 개발자들은 참 대단하다.

난 아무리 봐도 이해가 안가는데..





반응형
반응형



안드로이드 팝업창 띄우기


일단 팝업창 띄우기 예제는 많기는 한데 용도가 경고하거나 알림용이다


나는 그런 용도보다는 설명용이라 아예 xml파일을 팝업창에 보여주고 싶었다.


우선 팝업창을 만드는 작업이 필요하다.





일단 팝업창 띄우기 위한 버튼


버튼을 만들 xml파일에 만들어준다.

ex)hidden.xml



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/alert"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="히든설명" />
  
</LinearLayout>



이제 액티비티 설정부분

버튼 만든 해당 액티비티에 만들어준다.


ex)HiddenActivity.java



import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MessageDemo extends Activity implements View.OnClickListener{
	Button alert; //팝업버튼선언

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		//팝업버튼 설정
		alert=(Button)findViewById(R.id.alert);//R.id.alert는 팝업버튼 아이디
		alert.setOnClickListener(this);
		
	}
	public void onClick(View view){
		if(view==alert){ //view가 alert 이면 팝업실행 즉 버튼을 누르면 팝업창이 뜨는 조건
			new AlertDialog.Builder(this)
			.setTitle("히든목록") //팝업창 타이틀바
			.setMessage("FinessShot")  //팝업창 내용
			.setNeutralButton("닫기",new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dlg, int sumthin) {
					//닫기 버튼을 누르면 아무것도 안하고 닫기 때문에 그냥 비움

				}
			})
			.show(); // 팝업창 보여줌
		}
		
	}
}





여기까지 해주면 히든설명 이라는 버튼을 누르면 팝업창이 뜨게된다.



하지만 팝업창에서 보여줄 내용이 많을때 이렇게 하면 내용이 짤리고 공간이 부족했다.



그래서 이제부터 xml파일을 하나 만들고 그 내용들을 팝업창에 보여주도록 할 것이다.


우선 팝업창에 보여줄 xml파일을 따로 만든다


ex) dialog.xml


내용이 길어서 스크롤뷰를 적용하였다.

23번째 줄 android:text= "여기에 표시해줄 내용을 쓴다"




<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/popup" <!-- 아이디 선언, 액티비티에서 필요함-->
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#191A19"
    android:orientation="vertical"
    tools:context=".HiddenActivity" > <!--해당 액티비티 선언-->    
     <LinearLayout
       
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
   
       
    <TextView
       
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textColor="#B4B4B4"
       android:layout_gravity="center"
       android:textSize="15sp"
       android:text=" -Argues With Officials : 애매한 판정일 경우 심판과 언쟁을 함\n\n -Avoids Using Weaker Foot : 약한발은 잘 사용하지 않음\n\n -Cautious With Crosses : 코너킥 및 크로스에 대해 인터셉트 시도 보단 골 라인을 지키려 한다\n\n -Comes For Crosses : 코너킥 및 크로스에 대해 적극적으로 인터셉트를 시도한다\n\n -Corner Specialist : 코너킥 시 좀더 많은 골 찬스를 발생시킴 \n\n -Counter Attacker : 역습상황으로 전환할때의 반응속도가 향상됨\n\n -Diver : 태클을 당하면 넘어지면서 반칙을 유도함\n\n -Dives Into Tackles : 슬라이딩 태클을 자주 시도함\n\n -Early Crosser : 얼리크로스 능력치 뛰어남\n\n -Fancy Feet : 보다 정교하고 화려한 퍼스트 터치 발동\n\n -Finesse Header : 정확한 헤딩을 시도함\n\n -Finesse Shot : 정확한 슛팅을 시도함\n\n -Flair : 공을 받거나 받은 후에 일정한 공간과 시간이 있다면 자발적으로 트릭을 사용함\n\n -Forward pushes wide left : 공격시 왼쪽을 선호하는 움직임\n\n -Forward pushes wide Right : 공격시 오른쪽을 선호하는 움직임\n\n -Giant Thorw in : 드로잉을 아주 멀리 던짐 \n\n -GK Long Throw : 골킥을 멀리 찰 수 있음\n\n -GK One On One : 1:1상황에서의 방어능력이 뛰어남\n\n -GK Puncher : 펀칭의 능력이 뛰어나고 자주시도함\n\n -GK up for Corners : 키퍼가 경기종료시간이 얼마 안남았을때 코너킥 상황에 공격하러 올라감\n\n -Heel Passer : 힐패스능력이 뛰어남\n\n -High Determination : 지고있는 상황에서 일관성 상향\n\n -Holds Up : 공격상황에서 몸싸움 경합시 밸런스 상향..."
       android:textStyle="bold"
       android:typeface="normal" />
    </LinearLayout>

    
    </ScrollView>




이제 액티비티에 코드를 수정하자


HiddenActivity.java 파일로 돌아가서 onClick 함수에서 선언한 부분을 수정한다.





public void onClick(View view){
		if(view==alert){ //view가 alert 이면 팝업실행 즉 버튼을 누르면 팝업창이 뜨는 조건
			Context mContext = getApplicationContext();
			LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

			//R.layout.dialog는 xml 파일명이고  R.id.popup은 보여줄 레이아웃 아이디
			View layout = inflater.inflate(R.layout.dialog,(ViewGroup) findViewById(R.id.popup));
			AlertDialog.Builder aDialog = new AlertDialog.Builder(CustomActivity.this);
		
			aDialog.setTitle("히든스탯 목록"); //타이틀바 제목
			aDialog.setView(layout); //dialog.xml 파일을 뷰로 셋팅
		
			//그냥 닫기버튼을 위한 부분
			aDialog.setNegativeButton("닫기", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
			}
		});
		//팝업창 생성
		AlertDialog ad = aDialog.create();
		ad.show();//보여줌!
	}




이렇게 해준 뒤 실행해보면





이런 식으로 스크롤 뷰로 팝업창에 나타난다. 

한마디로 팝업창안에 xml 파일내용이 들어가서 보여준다.



반응형

+ Recent posts