카카오톡 몰래보기 어플 분석 [CapturedMsgViewActivity.java]
package com.irihon.katalkcapturer;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.mocoplex.adlib.AdlibActivity;
import com.mocoplex.adlib.AdlibConfig;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
public class CapturedMsgViewActivity extends AdlibActivity
implements View.OnClickListener
{
private MessageAdapter mAdapter = null;
private boolean mIsStartFromLock = false;
private ContentObserver mMessageObserver = new ContentObserver(new Handler())
private ContentObserver mMessageObserver = new ContentObserver(new Handler())
{
public void onChange(boolean paramBoolean)// 모니터링 도중 컨텐츠의 변경이 감지되면 자동으로 호출되는 메소드
{
super.onChange(paramBoolean);
//패키지내부의 CaptureedMessage 경로를 변수로 지정
Uri localUri = Uri.parse("content://com.irihon.katalk.provider/capturedmessage/preview_message");
//메세지ID ,받은시간, 받은메세지 내용 ,보낸이 이름 의 문자 배열을 만듬
String[] arrayOfString = { "id", "receive_time", "msg", "sender_name" };
//localCursor 라는 변수에 localUri에 해당하는 위치의 arrayOfString 형식의 데이터를 내림차순으로 가져온다.
Cursor localCursor = CapturedMsgViewActivity.this.getContentResolver().query(localUri, arrayOfString, null, null, "receive_time DESC");
//가져온데이터가 비어있지않고 가장처음커서를 가르키고 있는경우
if ((localCursor != null) && (localCursor.moveToFirst()))
{/*받아온 메세지를 처리하기 시작*/
//가져온데이터가 현재 가리키는 msg열의 인덱스를 가짐
int i = localCursor.getColumnIndex("msg");
//가져온데이터가 현재 가리키는 id열의 인덱스를 가짐
int j = localCursor.getColumnIndex("id");
//가져온데이터가 현재 가리키는 보낸이를 가짐
String str = localCursor.getString(localCursor.getColumnIndex("sender_name"));
//가져온데이터의 id열의 j의 위치에 해당하는 값을 가져옴
int k = localCursor.getInt(j);
//클래스의 mSenderName변수의 내용과 가져온 보낸이가 같고 k가 id번호가 클래스의 mTopMsgId 변수보다 클때
//즉 가져온 메세지의 정보가 신규메세지일 경우를 구분하는 부분이라고 추측됨.
if ((CapturedMsgViewActivity.this.mSenderName.equals(str)) && (k > CapturedMsgViewActivity.this.mTopMsgId))
{/*신규 메세지일경우의 처리*/
//mTopMsgId를 최신의 메세지ID값을 저장
CapturedMsgViewActivity.this.mTopMsgId = k;
//m 에 받아온 받은시간값의 인덱스를 저장함.
int m = localCursor.getColumnIndex("receive_time");
//클래스의 mMsgList변수가 비어있지 않다면
if (CapturedMsgViewActivity.this.mMsgList != null)
//mMsgList에 localCursor.getString(i),localCursor.getLong(m)형식의 데이터를 추가함 (i위치의 메세지내용, m위치의 받은시간)형식으로 저장됨
CapturedMsgViewActivity.this.mMsgList.add(0, new CapturedMessage(localCursor.getString(i), localCursor.getLong(m)));
}/*신규 메세지일경우의 처리끝*/
//가져온 데이터를 닫음
localCursor.close();
}/*받아온 메세지를 처리하기 끝*/
//클래스의 mAdapter가 널이 아니라면
if (CapturedMsgViewActivity.this.mAdapter != null)
//mAdapt에게 data가 변경되었다는 사실을 알려준다.
CapturedMsgViewActivity.this.mAdapter.notifyDataSetChanged();
}
};
//받아온메세지를 저장할 어레이리스트를 선언함.
private ArrayList<CapturedMessage> mMsgList = null;
//보낸이를 저장할 문자열변수를 선언함.
private String mSenderName = null;
//최신문자ID 가질 변수를 선언함.
int mTopMsgId = -1;
private ArrayList<CapturedMessage> mMsgList = null;
private String mSenderName = null;
int mTopMsgId = -1;
//대화목록삭제를 선택했을시의 경우 다이얼로그 출력으로 추측함.
private AlertDialog buildDeleteDialog(String paramString)
{
//대화목록삭제여부를 묻는 다이얼로그그 문자열의 타이틀과 내용을 설정해줌
return new AlertDialog.Builder(this).setTitle(paramString + " 대화 목록 삭제").setMessage("선택하신 대화 목록을 삭제하시겠습니까?").setPositiveButton("Ok", new DialogInterface.OnClickListener(paramString)
{
//선택했을시 처리해주는 부분
public void onClick(DialogInterface paramDialogInterface, int paramInt)
{
//클래스의 메세지삭제 deleteMessages(this.val$name)결과가 참이면
if (CapturedMsgViewActivity.this.deleteMessages(this.val$name))
{
//인텐트 선언
Intent localIntent = new Intent();
//인텐트 내용 설정
localIntent.putExtra("sender_name", CapturedMsgViewActivity.this.mSenderName);
CapturedMsgViewActivity.this.setResult(-1, localIntent);
CapturedMsgViewActivity.this.finish();
}
}
//취소버튼 선택시 액션 설정
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface paramDialogInterface, int paramInt)
{//아무동작 하지않음
}
}).create();// 다이얼로그 생성
}
/*메세지를 삭제하는 메소드*/
private boolean deleteMessages(String paramString)
{
//paramString의 '를 ''로 모두 변경하여 str1에 저장
String str1 = paramString.replaceAll("'", "''");
//sneder_name=' + str1 + ' 를 해서 str2에 저장
String str2 = "sender_name='" + str1 + "'";
//delete(CapturedMessageProvider.MESSAGE_CONTENTS_URI, str2, null)의 결과값을 리턴함.
return getContentResolver().delete(CapturedMessageProvider.MESSAGE_CONTENTS_URI, str2, null) > 0;
}
/*이미 캡쳐되어 저장된 메세지목록을 불러오는 메서드로 추측됨*/
private ArrayList<CapturedMessage> getCapturedMessageList(String paramString)
{
//로컬어레이리스트 라는 어레이리스트를 만듬
ArrayList localArrayList = new ArrayList();
//아이디 메세지 받은시간 의 배열을 만듬
String[] arrayOfString = { "id", "msg", "receive_time" };
//paramString의 '를 모두 ''로 치환하여 str1에 반환한다
String str1 = paramString.replaceAll("'", "''");
//"sender_name='" + str1 + "'" 을 str2 에 반환한다.
String str2 = "sender_name='" + str1 + "'";
//localCursor 라는 변수에 CapturedMessageProvider.MESSAGE_CONTENTS_URI에 해당하는 위치의 arrayOfString 형식의 데이터중 str2 조건에 해당하는 데이터를 내림차순으로 가져온다.
Cursor localCursor = getContentResolver().query(CapturedMessageProvider.MESSAGE_CONTENTS_URI, arrayOfString, str2, null, "receive_time DESC");
//가져온데이터가 비어있지않고 가장처음커서를 가르키고 있는경우
if ((localCursor != null) && (localCursor.moveToFirst()))
{
//i 는 가져온데이터가 현재 가리키는 msg열의 인덱스를 가짐
int i = localCursor.getColumnIndex("msg");
//j 는 가져온데이터가 현재 가리키는 id열의 인덱스를 가짐
int j = localCursor.getColumnIndex("id");
//가져온데이터가 현재 가리키는 receive_time열의 인덱스를 가짐
int k = localCursor.getColumnIndex("receive_time");
//클래스의 mTopMsgId에 가져온데이터의 j에 해당하는 데이터를가짐
this.mTopMsgId = localCursor.getInt(j);
do//가져온데이터의 끝이 될때까지 로컬어레이리스트에 getstring(i),getstring(k) 즉 메세지,받은시간 형식으로 추가한다
localArrayList.add(new CapturedMessage(localCursor.getString(i), localCursor.getLong(k)));
while (localCursor.moveToNext());
//가져온데이터를 닫는다.
localCursor.close();
}
//정리가된 어레이리스트를 반환한다.
return localArrayList;
}
/*카카오톡을 실행시키는 메소드로 추측됨*/
private void startKakaoTalk()
{
//카카오톡실행할 인텐트를 설정
Intent localIntent = getPackageManager().getLaunchIntentForPackage("com.kakao.talk");
//로컬인텐트가 널이라면 즉 카카오톡의 정보를 받아오지 못했을경우(카카오톡이 깔려있지 않은경우로 추측)
if (localIntent == null)
//그냥 리턴함.
return;
//인텐트에 플래그를 추가함
localIntent.addFlags(268435456);
localIntent.addFlags(536870912);
//인텐트를 실행한다. (카카오톡 정보를 정상적으로받아왔기떄문에 정상실행이 될것으로추측)
startActivity(localIntent);
}
//메모리 누수를 방지하는 메소드로 추측됨
private void unbindDrawables(View paramView)
{
//paramView 가 널이 아니라면
if (paramView != null)
try
{
//praramView의 백그라운드가 널이 아니라면
if (paramView.getBackground() != null)
//paramView의 백그라운드의 콜백을 null로 설정해준다
paramView.getBackground().setCallback(null);
//paramView가 ViewGroup형으로 형변환이 가능하면?
if ((paramView instanceof ViewGroup))
{
//paramView가 가지고있는 뷰의 개수를 i에 대입한다.
int i = ((ViewGroup)paramView).getChildCount();
//j를 1씩 증가하며 조건없이 반복한다.
for (int j = 0; ; j++)
{
//j가 i이상이면
if (j >= i)
{
//paramView의 모든 뷰를 삭제한다.
((ViewGroup)paramView).removeAllViews();
//리턴
return;
}
//paramView의 j번째의 뷰를 가져옴
unbindDrawables(((ViewGroup)paramView).getChildAt(j));
}
}
}
catch (Exception localException)
{
}
}
/*광고를 실행하는 메소드로 추정*/
protected void initAds()
{
AdlibConfig.getInstance().bindPlatform("INMOBI", "com.adlib.adviews.SubAdlibAdViewInmobi");
AdlibConfig.getInstance().bindPlatform("ADAM", "com.adlib.adviews.SubAdlibAdViewAdam");
AdlibConfig.getInstance().bindPlatform("ADMOB", "com.adlib.adviews.SubAdlibAdViewAdmob");
AdlibConfig.getInstance().bindPlatform("NAVER", "com.adlib.adviews.SubAdlibAdViewNaverAdPost");
AdlibConfig.getInstance().setAdlibKey("501244330cf220394aba0547");
}
/*서브엑티비티의 결과값을 받는데 사용하는 메소드라고 함.*/
protected void onActivityResult(int paramInt1, int paramInt2, Intent paramIntent)
{
super.onActivityResult(paramInt1, paramInt2, paramIntent);
//리퀘스트코드1이 KatalkCapturerActivity.REQUEST_CODE_LOCK 이면
if (paramInt1 == KatalkCapturerActivity.REQUEST_CODE_LOCK)
{
//리퀘스트코드2가 -1이면
if (paramInt2 == -1)
//클래스내의 mlsStartFromLock 을 true로 바꿈
this.mIsStartFromLock = true;
}
//아니면
else
//리턴
return;
//호출한 엑티비티에 result코드와 인텐트를 전달함.
setResult(0);
finish();
}
/**/
public void onClick(View paramView)
{
//입력받은뷰의 아이디를 얻어옴
int i = paramView.getId();
//얻어온 id가 2131230772 이면
if (i == 2131230772)
//buildDeleteDialog에 선택한 뷰의 보낸이를 입력하여 출력함.
buildDeleteDialog(this.mSenderName).show();
do//i가 2131230773이 아닐때까지 반복함
return;
while (i != 2131230773);
//startkakaoTalk메서드를 호출
startKakaoTalk();
}
/*기본 창이 출력되었을때 기본동작*/
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
//2130903046에 해당하는 레이아웃을 출력
setContentView(2130903046);
//전달된 값을 받을 localintent를 만든다
Intent localIntent = getIntent();
//받아온 데이터에 "sender_name"가 있으면
if (!localIntent.hasExtra("sender_name"))
//종료
finish();
//클래스의 mSenderName 변수에 "sender_name"의 내용을 가져온다
this.mSenderName = localIntent.getStringExtra("sender_name");
//뷰에 텍스트를 mSenderName로 설정해준다.
((TextView)findViewById(2131230770)).setText(this.mSenderName);
//클래스의 mMsgList를 getCaptureedMessageList에 mSenderName을 넣어서 반환받은 값을 저장한다.
this.mMsgList = getCapturedMessageList(this.mSenderName);
//클래스의 mAdapter 설정
this.mAdapter = new MessageAdapter(this, this.mSenderName, 2130903042, 2131230732, this.mMsgList);
//mAdapter에 변화되엇다는 알림을 보내줌
this.mAdapter.setNotifyOnChange(true);
//리스트뷰에 어댑터를 설정해줌
((ListView)findViewById(2131230774)).setAdapter(this.mAdapter);
//
getContentResolver().registerContentObserver(CapturedMessageProvider.MESSAGE_CONTENTS_URI, false, this.mMessageObserver);
//레이아웃에 클릭리스너를 담
findViewById(2131230772).setOnClickListener(this);
findViewById(2131230773).setOnClickListener(this);
//클래스에 mlsStartFromLock을 True를 넣어줌
this.mIsStartFromLock = true;
//설명이 없음
setAdsContainer(2131230769);
}
/*파괴되엇을때*/
protected void onDestroy()
{
super.onDestroy();
//destroyAdsContainer()를 호출함
destroyAdsContainer();
//mAdapter를 클리어함.
this.mAdapter.clear();
//mAdapter 를 널로 설정해줌
this.mAdapter = null;
//getContentResolver()를 컨텐츠옵저버에서 제거함
getContentResolver().unregisterContentObserver(this.mMessageObserver);
//메모리 누수방지를위해 파괴된 뷰에 unbindDrawables를 호출함
unbindDrawables(findViewById(2131230768));
}
/*터치했다가 뗏을때의 상태를 반환해주는 메소드로 추측됨*/
public boolean onKeyUp(int paramInt, KeyEvent paramKeyEvent)
{
if (paramInt == 4)
{
setResult(-1);
finish();
return false;
}
return super.onKeyUp(paramInt, paramKeyEvent);
}
/*포커스를 잃었다가 다시 얻었을때의 작동하는 메소드로 추측*/
protected void onResume()
{
super.onResume();
//클래스의 mIsStartFromLock가 True면
if (this.mIsStartFromLock)
//mIsStartFromLock를 false로 변형
this.mIsStartFromLock = false;
do
return;
//KatalkMoleSettings클래스의 isEnable메소드의 결과가Enable일 때까지 반복
while (!KatalkMoleSettings.isEnable(getApplicationContext(), "ENABLE_LOCK"));
//엑티비티가 실행된후 결과물을 받아서 반환함
startActivityForResult(new Intent(this, KatalkPasswordActivity.class), KatalkCapturerActivity.REQUEST_CODE_LOCK);
}
private class MessageAdapter extends ArrayAdapter<CapturedMessage>
{
private LayoutInflater mLayoutInflater = null;
private String mSenderName = null;
/*메세지어댑터를 설정함.*/
public MessageAdapter(String paramInt1, int paramInt2, int paramList, List<CapturedMessage> arg5)
{
super(paramList, i, localList);
this.mSenderName = paramInt2;
}
/*카톡을통해 얻은 받은시간정보를 변환하여 반환*/
private String getTime(long paramLong)
{
SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat("a HH:mm");
GregorianCalendar localGregorianCalendar = new GregorianCalendar();
localGregorianCalendar.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));
localGregorianCalendar.setTimeInMillis(paramLong);
return localSimpleDateFormat.format(localGregorianCalendar.getTime());
}
/*입력받은 paramint를 CapturedMessage 로 변환하여 반환함*/
public CapturedMessage getItem(int paramInt)
{
return (CapturedMessage)super.getItem(paramInt);
}
/*입력받은paramInt의 ID를 반환함*/
public long getItemId(int paramInt)
{
return super.getItemId(paramInt);
}
/*입력한 정보의 뷰를 반환함*/
public View getView(int paramInt, View paramView, ViewGroup paramViewGroup)
{
View localView = super.getView(paramInt, paramView, paramViewGroup);
if (localView == null)
localView = this.mLayoutInflater.inflate(2130903042, null);
CapturedMessage localCapturedMessage = (CapturedMessage)super.getItem(paramInt);
((TextView)localView.findViewById(2131230731)).setText(this.mSenderName);
((TextView)localView.findViewById(2131230732)).setText(localCapturedMessage.getMessage());
((TextView)localView.findViewById(2131230733)).setText(getTime(localCapturedMessage.getTime()));
return localView;
}
/*paramint의 Enabled상태를 boolean형으로 반환함*/
public boolean isEnabled(int paramInt)
{
return super.isEnabled(paramInt);
}
}
'여러가지 > 잡담' 카테고리의 다른 글
달팽이가 알을 낳았습니다 ㄷㄷㄷ (3) | 2014.06.13 |
---|---|
[LOL]볼리베어 일러스트 채색연습 (0) | 2013.08.07 |
Application Framework 부분 분석 (0) | 2013.07.31 |
티스토리 RSS 피드와 네이버 검색등록에 관한 상식 (0) | 2013.06.09 |
옥상정원일기 2013/6/7 35일째 (0) | 2013.06.07 |