More actions
설명
제작 과정
- 어플에 필요한 배울것 체크
- Android의 기본 어플로 장착되어있는 Gallery 어플로 Intent넘긴후 리스트 다시 받아오기.
- Android의 Wallpaper 바꾸는 API찾아보기
- 특정시간되면 작동되게하는 알람기능 써보기
- 설계 후 통합 제작
- 디버그를 하겠지
어플에 필요한 배울것 체크
Android의 기본 어플로 장착되어있는 Gallery 어플로 Intent넘긴후 리스트 다시 받아오기
- Android Provider 믿을것이 못되더라.
- Stack Overflow에서 참조
package june.my.testdroid;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
public class TestdroidActivity extends Activity {
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
openPhotoLibrary();
}
private void openPhotoLibrary() {
//Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent i = new Intent();
i.setType("image/*");
//i.setType(MediaStore.Images.Media.CONTENT_TYPE);
i.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(i, "Select Picture"), SELECT_PICTURE);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
Android의 Wallpaper 바꾸는 API찾아보기
- Wallpaper바꾸는데 Permission 필요하더라 (Androidmenifest.xml파일 수정 요함)
- WallpaperManager 클래스를 통해 할수 있더라
- BitmapFactory를 통해 이미지 바꿀수 있더라
manager.setBitmap(Bitmap.createScaledBitmap(b, d.getWidth()*4, d.getHeight(), true));
왜 * 4냐면 내 폰에 배경화면이 4칸이라 답하겠더라
package june.mywallpaper.com;
import java.io.IOException;
import android.app.Activity;
import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MywallpaperActivity extends Activity {
private static final Button Button = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView img1 = (ImageView)findViewById(R.id.imageView1);
img1.setImageResource(R.raw.wall1);
img1.setVisibility(View.VISIBLE);
Button btn1 = (Button)findViewById(R.id.button1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Bitmap b = BitmapFactory.decodeStream(getResources().openRawResource(R.raw.wall1));
WallpaperManager manager = WallpaperManager.getInstance(MywallpaperActivity.this);
final Display d = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
try{
manager.setBitmap(Bitmap.createScaledBitmap(b, d.getWidth()*4, d.getHeight(), true));
Toast.makeText(getApplicationContext(), "배경화면 지정 성공", 1).show();
}catch(IOException e){
e.printStackTrace();
Toast.makeText(getApplicationContext(), "배경화면 지정 실패", 1).show();
}
}
});
}
}
특정시간되면 작동되게하는 알람기능 써보기
- 안드로이드의 서비스를 이용해서 구현.
- Service는 안드로이드 Activity와 별도로 구현해야 하며 2.3.3버전 이후 단독 실행이 불가능하다고 하다.
- 또한 Service는 AndroidManifest.xml파일에 당연히 등록을 해야한다. (Application탭 -> Service등록)
- 액티비티 클래스
package june.myservice.com;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MyserviceActivity extends Activity {
ComponentName mService; // 시작 서비스의 이름
TextView mTextView; // 서비스 상태 표시
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView)findViewById(R.id.text_view);
Button start = (Button)findViewById(R.id.start_button);
start.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
startHelloService();
}});
Button stop = (Button)findViewById(R.id.stop_button);
stop.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
stopHelloService();
}});
}
// 서비스 시작 요청
private void startHelloService() {
mService = startService(new Intent(this, MyService.class));
mTextView.append(mService.toShortString()+" started.\n");
}
// 실행한 서비스 중지 요청
private void stopHelloService() {
if (mService == null) {
mTextView.append("No requested service.\n");
return;
}
Intent i = new Intent();
i.setComponent(mService);
if (stopService(i))
mTextView.append(mService.toShortString()+" is stopped.\n");
else
mTextView.append(mService.toShortString()+" is alrady stopped.\n");
}
}
- 서비스 클래스
package june.myservice.com;
import java.io.IOException;
import android.app.Service;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;
public class MyService extends Service implements Runnable{
// 시작 ID
private int mStartId;
// 서비스에 대한 스레드에 연결된 Handler. 타이머 이용한 반복 처리시 사용.
private Handler mHandler;
// 서비스 동작여부 flag
private boolean mRunning;
// 타이머 설정 (2초)
private static final int TIMER_PERIOD = 2 * 1000;
private static final int COUNT = 10;
private int mCounter;
// 서비스를 생성할 때 호출
public void onCreate() {
Log.e("MyService", "Service Created.");
super.onCreate();
mHandler = new Handler();
mRunning = false;
}
// 서비스 시작할 때 호출. background에서의 처리가 시작됨.
// startId : 서비스 시작요구 id. stopSelf에서 종료할 때 사용.
//onStart는 여러번 호출될 수 있기 때문에 식별자로 사용.
public void onStart(Intent intent, int startId) {
Log.e("MyService", "Service startId = " + startId);
super.onStart(intent, startId);
mStartId = startId;
mCounter = COUNT;
// 동작중이 아니면 run 메소드를 일정 시간 후에 시작
if (!mRunning) {
// this : 서비스 처리의 본체인 run 메소드. Runnable 인터페이스를 구현 필요.
// postDelayed : 일정시간마다 메소드 호출
mHandler.postDelayed(this, TIMER_PERIOD);
mRunning = true;
}
}
// 서비스의 종료시 호출
public void onDestroy() {
// onDestroy가 호출되어 서비스가 종료되어도
// postDelayed는 바로 정지되지 않고 다음 번 run 메소드를 호출.
mRunning = false;
super.onDestroy();
}
// 서비스 처리
public void run() {
if (!mRunning) {
// 서비스 종료 요청이 들어온 경우 그냥 종료
Log.e("MyService", "run after destory");
return;
} else if (--mCounter <= 0) {
// 지정한 횟수 실행하면 스스로 종료
Log.e("MyService", "stop Service id = "+mStartId);
stopSelf(mStartId);
} else {
// 다음 작업을 다시 요구
Log.e("MyService", "mCounter : " + mCounter);
mHandler.postDelayed(this, TIMER_PERIOD);
}
}
// 원격 메소드 호출을 위해 사용
// 메서드 호출을 제공하지 않으면 null을 반환
public IBinder onBind(Intent intent) {
return null;
}
}
배워보기에서 하지 않은 예상 고려점
- 그림파일을 불러왔을경우 BitmapFactory에서의 이미지 사이즈 변경은 이미지를 늘리고 줄이기 때문에 기존 안드로이드 어플 배경화면에서 자르기로 들어간것과는 다르다.
- 서비스를 등록시키고 Reciever를 통해 안드로이드 시작후에 자동 작동하게 해놓는것.
프로그램 시나리오
- 프로그램을 켠다.
- 창이 뜬다.
- 현재 설정되어있는 파일 리스트 보기
- 파일 리스트 화면
- 파일 리스트 추가/삭제
- 시간 주기 설정
- 몇초 주기로 바뀌는지. 10초 20초 30초 60초. 120초 180초.
- 현재 서비스 해지.