Android/소스코드 | Posted by 덩치 2014. 3. 26. 13:21

화면캡쳐 방지 소스코드

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

어플 화면이 캡쳐되지 않도록 해달라는 요청을 받고 검색하다가 발견한 소스코드.


불가능할줄 알았는데 api level 1부터 이런게 있었다니 .. 충격


getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);


정확한 원리는 모르겠는데 몇몇 기종으로 테스트 해 본 결과


어떤 폰에서는 캡쳐기능을 사용할 수 없습니다 라는 토스트를 출력하고


어떤 폰에서는 캡쳐 직전 바로 검은 화면을 띄워서 해당 화면이 캡쳐되도록 하는 듯 하다.



위 코드 한줄만 넣어주면 적용 완료.


특정 영역에서만 캡쳐를 방지하고싶다면, 이외의 영역에는

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);

를 추가하면 된다.


참고로 액티비티가 액티브되고 있는 상태에서만 적용. 즉 홈화면으로 나가서 캡쳐를하면 제대로 캡쳐가 된다.


펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO



startActivity(new Intent(android.provider.Settings."액션"));


한줄만 넣어주면 원하는 설정창을 띄워줄 수 있다.


예를들어 GPS설정창을 띄우고 싶은 경우


startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));


데이터네트워크 설정창을 띄우고 싶은 경우


startActivity(new Intent(android.provider.Settings.ACTION_DATA_ROAMING_SETTINGS));



이외에도 Settings 하위에 액션들이 많으니 필요한 액션을 찾아서 적용시켜주면 유용하게 쓰일듯 하다.




펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


JSONObjectJSON형태의 데이터를 관리해 주는 메서드이다.

주의점은 맵의 특성으로 인해 순서를 보장하지 않는다는것. 즉 똑같이 뽑아내도 내용물의 순서가 섞일 수 있다.



간단한 사용법은 다음과 같다.


먼저 제이슨 생성 후 데이터 집어넣기


JSONObject obj = new JSONObject();

obj.put("이름","덩치");

obj.put("거주지","서울");


출력해보면


String data = obj.toString();

System.out.println(data);


결과값 - {"이름":"덩치","거주지":"서울"} 

이렇게 표시된다.


키값에 해당하는 벨류만 뽑고싶다면

String data = obj.get("key");

하면 "key"에 해당하는 벨류를 반환한다.



JSON형태의 StringJSONobject에 넣는법은


String data = {"이름":"덩치","거주지":"서울"};

(실제로는 자바에서는 "를 못읽기때문에  String data = "{\"이름\":\"덩치\",\"거주지\":\"서울\"}";  이런식으로 해줘야 될것임)

JSONObject obj = new JSONObject(data);

쓸때는 위와 같이 뽑아서 사용하면 된다.



JSONArray 는 JSONObject가 들어가는 배열이라고 보면 된다.


예제를 먼저 보자

- 예제출처 : (http://aroundck.tistory.com/215)


String Json = "[{\"Product\" : \"Mouse\", \"Maker\":\"Samsung\", \"Price\":23000},"
               + "{\"Product\" : \"KeyBoard\", \"Maker\":\"LG\", \"Price\":12000},"
               + "{\"Product\":\"HDD\", \"Maker\":\"Western Digital\", \"Price\":156000}]";
try{
   String result = "";
   JSONArray ja = new JSONArray(Json);
   for (int i = 0; i < ja.length(); i++){
      JSONObject order = ja.getJSONObject(i);
      result += "product: " + order.getString("Product") + ", maker: " + order.getString("Maker") +
                  ", price: " + order.getInt("Price") + "\n";
   }
}
catch (JSONException e){ ;}


결과값 :   result : product: Mouse, maker: Samsung, price: 23000
product: KeyBoard, maker: LG, price: 12000
product: HDD, maker: Western Digital, price: 156000

이렇게 만들어진 JSONArray 객체를 JSONObject에 넣을 수 있으며

위와같은 방식으로 제이슨오브젝트에 그냥 오브젝트와 어레이를 모두 넣어가며
작업할 수 있다.






'Android > 입/출력' 카테고리의 다른 글

SharedPreferences 사용법을 알아보자.  (1) 2014.01.14

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

몇개 안되는 포스팅 퍼가시는건 정말 기쁜일입니다.

제가 쓴 글이 유용하게 쓰일 수 있다는뜻이니까요. 


그대로 긁어가시라고 불펌방지도 안했습니다.


그런데 한번씩 보면 토씨하나 안틀리고 그대로 긁어다가 본인 블로그에 개시하시고 출처도 안밝히고


자기가 쓴것마냥 해놓은분들이 계십니다.



제가 올린 포스팅은 모두 제가 직접 타이핑해서 친것들이고,


직접 프로젝트 생성해서 테스트 다시한번 해 보고 올린것들입니다.


때문에 간단한 소스코드를 올린 포스팅도 수십분씩 걸려요



그런거 3분만에 글하나 뚝딱 퍼가시는거 좋은데 출처라도 남겨주세요


방명록에 퍼갔다고 감사인사라도 써주시면 저도 참 보람찰것 같습니다.

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


작업을 하다가 바이트로 저장된 .dat파일을 수정할 일이 생겼다.


아예 파일을 다시 생성해버릴까 하다가 멘탈을 다잡고 생각해 보니 생각보다 간단한문제였다.


먼저 파일을 열어야 하는데


static public byte [] openUploadPacket(Context ctx, String name) {

String filename = name + "_packet.dat" ;

byte [] list = null ;

try {

File cellFile = ctx.getFileStreamPath(filename);

ObjectInputStream is = new ObjectInputStream(new FileInputStream(

cellFile));

list = (byte []) is.readObject();

is.close();

return list;

} catch (Exception e) {

log.err("openUploadPacket = " + e) ;

return null;

}

}


이렇게하면 바이트배열에 파일의 내용이 전부 들어간다.


( 파일을 저장하는것은 InputStream 대신 OutputStream을 사용해서 write해주면 된다. )



나는 오픈한 파일의 164 ~ 175 번 값을 바꿔줘야 했다.



byte [] packet = Common.openUploadPacket(mContext, workNum) ;

byte [] editByte = et_nis.getText().toString().getBytes();


for (int i = 0; i < editeByte.length; i++) {

packet [164 + i] = editeByte[i];

}


먼저 바이트배열 packet에 파일 읽어온다

그럼 파일의 length만큼 배열크기가 할당되고 데이터가 들어가고,


내가 수정할 데이터가 들어갈 editByte도 하나 만들어줬다.


et_nis라는 EditView에 입력한 값이 저기에 들어가게 될텐데,


et_nis에 어떤 데이터형이 들어갈 지 모르기때문에 일단 스트링으로 받은 다음, getBytes()를 이용해

바이트형식으로 배열에 넣어줬다.


그리고 164번부터 et_nislength만큼 반복을 돌려서 기존 packet 배열에 수정할 데이터 배열을 넣어준다


위와같이 하면 원하는 길이만큼 원하는 데이터로 수정해 줄 수 있다.


소켓통신할 때 자주 사용될 것 같다




펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO




Study_ListView.zip


리스트뷰를 텍스트2개 , 이미지뷰1개로 커스텀 하여 출력한 예제입니다.


소스 돌려보시고 궁금한점 있으면 댓글 주세요 


요즘 일이 바빠서 자세히 포스팅을 못하고 예제만 올리네요 ..



Android/소스코드 | Posted by 덩치 2014. 2. 20. 09:07

XmlPullParser 사용하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO



Study_Parsing.zip


한경닷컴 뉴스 rss페이지를 파싱하여 출력하는 예제


퍼미션은 android.permission.INTERNET


예제를 실행시켜보고 소스를 뜯어보고


이해 안가는부분은 질문 주세요




Android/View | Posted by 덩치 2014. 2. 4. 11:50

레이아웃의 종류와 사용법

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

자주 사용하게 되는 레이아웃 3가지만 다루겠다.


1. LinearLayout

뷰가 가로 또는 세로로 순차적으로 나열되는 레이아웃.



보는바와 같이 android:orientation 옵션을 통해 가로(horizontal) 또는 세로(vertical)로 설정할 수 있으며

따로 선언하지 않는다면 디폴트로 horizontal이 적용된다.

가장 사용하기 편리한 레이아웃이라고 생각함



2. RelativeLayout

따로 위치를 지정하지 않으면 뷰가 0,0 위치에 계속 쌓이는 레이아웃으로,

최상위 부모 레이아웃 상대위치 또는 id를 참조해 특정 뷰에 대해 상대적인 위치를 지정할 수 있다.

약간 까다로울 수 있는 레이아웃인데 예제를 보자.




위와같이 따로 위치를 지정하지 않으면 저렇게 다 겹쳐서 출력된다.

위치를 지정해 보자.


(클릭해서 보세요)

이런식으로 지정해 줄 수 있다.

RelativeLayout은 사용법이 까다로운만큼 완벽히 이해하고 넘어가길 바란다.



3. FrameLayout

같은 자리의 자식 뷰들을 겹치도록 놓고, VISIBLE, INVISIBLE, GONE 등의 옵션으로 교차하면서 보여줄 수 있음

아래쪽에서 선언된 뷰가 가장 위에 표시



주로 버튼클릭시 기존의 뷰를 숨기고 다른 뷰를 표시하는 탭기능에서 사용된다.

(텝1페이지 레이아웃과 2페이지 레이아웃을 인클루드하여 사용하는 방식 등)


소스코드에서는 View.setVisibility("GONE"); 형식으로 사용한다.


visible = 보이기  invisible = 뷰의 영역은 가지고 숨기기  gone = 뷰를 숨기고 영역도 해제함


직접 사용해보면서 차이점을 느끼기 바란다.


질문사항 있으면 댓글로 남겨주세요

-끝-



Android/기본스킬 | Posted by 덩치 2014. 1. 27. 15:28

기본적인 뷰 조작

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


Study_exam_01.zip


예제파일 import해서 실행시켜보시기 바랍니다.

해석은 주석에 다 달려 있으니, 응용하여 연습하시면 더 좋으리라 생각됩니다.




package com.example.study_exam_01;


import com.example.study_1st.R;


import android.app.Activity;

import android.graphics.Color;

import android.os.Bundle;

import android.util.TypedValue;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;


public class MainActivity extends Activity implements OnClickListener {

private Button text_edit_bt;

private Button color_edit_bt;

private Button size_edit_bt;

private TextView tv1;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main); //이 액티비티는 activity_main.xml 파일의 뷰를 가집니다.

tv1 = (TextView) findViewById(R.id.tv1); //xml파일에서 설정한 뷰를 소스코드에서 사용하기 위해 ID로 연결하는 과정입니다.

text_edit_bt = (Button) findViewById(R.id.text_edit_bt);

color_edit_bt = (Button) findViewById(R.id.color_edit_bt);

size_edit_bt = (Button) findViewById(R.id.size_edit_bt);

text_edit_bt.setOnClickListener(this);

color_edit_bt.setOnClickListener(this);

size_edit_bt.setOnClickListener(this);

// text_edit_bt.setOnClickListener(new View.OnClickListener() {  //이렇게 각각의 리스너를 등록해서 사용 할 수도 있습니다.

// @Override

// public void onClick(View v) {

// tv1.setText(tv1.getText() + "+");

// }

// });

}


//온클릭을 오버라이드 하기 위해서는 클래스에 OnClickListener를 implements해야합니다. 11번째줄 참조.

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.text_edit_bt :

tv1.setText(tv1.getText() + "+");  //기존 텍스트를 얻어와서(tv1.getText()) 뒤에 +를 추가합니다.

// tv1.setText("원하는 텍스트");

break;

case R.id.color_edit_bt :

tv1.setTextColor(Color.BLUE);  //Color 클래스에 들어있는 BLUE 색상으로 변환합니다.

// tv1.setTextColor(Color.parseColor("#FF0000")); //직접 색상코드를 입력하여 원하는 색으로도 설정 가능합니다.

break;

case R.id.size_edit_bt :

tv1.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv1.getTextSize() + 1); //기존 텍스트사이즈를 얻어와서 + 1만큼 사이즈를 키웁니다.

// tv1.setTextSize(16); //원하는 고정수치(px)로도 텍스트 크기를 변경 가능합니다.

break;

}

}

}








<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <Button
        android:id="@+id/text_edit_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="글 변경" />
    
    <Button
        android:id="@+id/color_edit_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="글씨 색 변경" />
    
    <Button
        android:id="@+id/size_edit_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="글씨 크기 변경" />
    
</LinearLayout>


Android/기본스킬 | Posted by 덩치 2014. 1. 27. 14:46

안드로이드 생명주기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


안드로이드도 다른 프로세스와 마찬가지로 태어나고 죽기까지의 생명주기(life cycle)가 존재합니다.

위 다이어그램은 액티비티가 생성되고 죽기까지의 과정을 순서적으로 나타낸것입니다.


우선 액티비티에 대해 설명하자면, 액티비티는 단말 화면상으로 보이는 뷰(View) 즉 화면을 뜻합니다.

액티비티 위에는 다른 뷰들이 올라가게 되고, 그런 뷰들로 화면이 구성됩니다. 즉 액티비티는 도화지, 뷰(버튼,텍스트 등)는

그림이라고 생각하시면 이해하기 편합니다.


위 그림을 해석해 보면


onCreate - 액티비티가 시작되면 제일 먼저 onCreate()가 호출됩니다.

이 영역에서 어플이 켜짐과 동시에 실행되어야 하는 작업들을 실행하게 됩니다.

어플 최초 실행시의 로딩화면 등을 예로 들 수 있겠습니다.


onStart() - onCreate가 호출 된 후 바로 실행됩니다. 

(onCreate에 의해 실행되는것은 아닙니다. 모든 생명주기는 독립적입니다.)


onPause() - 다른 액티비티가 기존 액티비티 위에 생성되어 포커스를 잃은상태. 

반투명 또는 일부영역만 차지하는 액티비티가 호출 된 상태로, 액티비티의 일부가 화면상에 노출되고있는 상태입니다.


onReasure() - Pause상태에서 다시 액티비티가 활성화되면 호출됩니다.


onStop() - 액티비티가 가려지거나 숨겨졌을 때 호출됩니다. 

일반적으로 홈키를 눌렀을때 어플의 상태를 생각하시면 됩니다.


onRestart() - stop상태에서 다시 액티비티가 실행되면 호출됩니다.


onDeastroy() - 메모리상에서 액티비티의 자원이 완전 해제될 때 호출됩니다.

즉 어플을 종료할 때 사용됩니다. 어플 종료시 자원의 해제와 같은 기능을 여기에서 주로 실행하게 됩니다.