2015년 5월 15일 금요일

android 화면 잠그기( 디바이스 관리자 )

안드로이드에서 디바이스 관리자란 무엇일까?

설명이 어려운데 보안 관련(패스워드 정책...,카메라 잠금,... 기타), 화면잠그기, 데이터 지우기등을 하는 동작이라고 생각하면된다.
자세한 설명은 아래 링크를 참고하면 되는데
http://developer.android.com/guide/topics/admin/device-admin.html

이딴걸 어디에 쓸까?

단말 분실서비스, locker, MDM, 어플이 지워지지 않게 하는등 기타 보안이나 사생활 보호등이 필요한 곳에서 잠금 및 제한을 하는 용도로 사용하게 된다.

이중 즉시 잠그는 예제를 만들어 보겠다.

이중 훌륭하게 작성한 예제를 찾았다.
https://github.com/xcoda/screenLock/wiki/Developing-SreenLock-(%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0)


public class MainActivity extends Activity {
 DevicePolicyManager mDPM;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  int id = item.getItemId();
  if (id == R.id.action_menu1) {
   ComponentName comp = new ComponentName(this, ScreenLockDeviceAdminReceiver.class);
  
   mDPM = (DevicePolicyManager) this
      .getSystemService(Context.DEVICE_POLICY_SERVICE);
   if( !mDPM.isAdminActive(comp) ){
    Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, comp);
    intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "message string");
    startActivityForResult(intent, 101);
   }else{
    mDPM.lockNow();
   }
   return true;
  }
  if (id == R.id.action_menu2) {
   ComponentName comp = new ComponentName(this, ScreenLockDeviceAdminReceiver.class);
  
   mDPM = (DevicePolicyManager) this
      .getSystemService(Context.DEVICE_POLICY_SERVICE);
   if( mDPM.isAdminActive(comp) ){
    mDPM.removeActiveAdmin(comp);
   }else{
    Uri uri = Uri.fromParts("package", "com.example.phonetest", null);
    Intent i = new Intent(Intent.ACTION_DELETE,uri );
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    this.startActivity(i);
   }
   return true;
  }
  return super.onOptionsItemSelected(item);
 }
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode,
   Intent intent) {
  super.onActivityResult(requestCode, resultCode, intent);
  if( requestCode == 101 ) {
   if (resultCode == RESULT_OK) {
    mDPM.lockNow();
   } else {
    Toast.makeText(this, "fail", Toast.LENGTH_LONG)
      .show();
   }
  }
 }
}

소스 설명
위 소스는 main 소스이다.
R.id.action_menu1 부분의 코드를 보면 mDPM.lockNow(); 이 부분이 lock을 하는 곳인데, mDPM.isAdminActive 함수를 호출하여 해당 app이 admin이 된건지 확인한다. 없다면 조건문 안으로 들어가서 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 인텐트를 보내 권한을 획득하도록 하는 창을 띄운다. startActivityForResult(intent, 101); 그리고 처리가 완료되면 101번의 리턴값을 가지고 onActivityResult 여기에서 잠금 처리를 한다.
id == R.id.action_menu2 이 조건을 만족하는 부분은 admin에서 제거할때 사용하는 코드이다.

추가로 작업해야하는것은 ComponentName(this, ScreenLockDeviceAdminReceiver.class); 이 부분인데 Recevier class를 만들어야 한다.


public class ScreenLockDeviceAdminReceiver extends DeviceAdminReceiver {
 @Override
 public void onEnabled(Context context, Intent intent) {
  super.onEnabled(context, intent);
  Toast.makeText(context, "enable", Toast.LENGTH_LONG).show();

 }
 
 @Override
 public void onDisabled(Context context, Intent intent) {
  super.onDisabled(context, intent);
  Toast.makeText(context, "disable", Toast.LENGTH_LONG).show();
 }
 
}

AndroidManifest.xml에 아래 항목을 추가한다.


     <receiver
            android:name=".ScreenLockDeviceAdminReceiver"
            android:label="sample_device_admin"
            android:permission="android.permission.BIND_DEVICE_ADMIN" >
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/screenlock_admin" />

            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>

그리고 마지막으로 resource xml파일을 만들어야 한다.


<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
    <force-lock />
  </uses-policies>
</device-admin>

댓글 1개:

  1. public boolean onCreateOptionsMenu(Menu menu) 이 메소드에

    getMenuInflater().inflate(R.menu.main, menu);이거에
    R.menu.main에 빨간줄 가는데 왜그런거죠?

    답글삭제