2019. 11. 11. 21:01

얼마전 "가족 정책 요구사항 위반" 으로 앱 업데이트가 안되는 현상이 있었습니다.

 

구글에서 받은 메일입니다.

 

구글에 정책 문의를 해서 받은 결론은,  어린이가 사용하는 앱에 민감한광고(대출, 데이트앱, 성인 광고 등) 가 노출되는 문제가 있다고 합니다.

 

이곳 저곳에 문의 하고, 관련된 글을 읽었더니, 아래와 같은 문구를 발견했습니다.

Google Play 인증 광고 네트워크를 사용하면 된다.

 

Google Admob 이 Google Play 인증 광고 네트워크 이기 때문에 문제가 없을 거라고 판단되어어서

다시 메일을 보냈습니다.

 

 

 

 

 

구글에서 아직 답변을 기다리는 중입니다. 

답변이 오면 글을 업데이트 하도록 하겠습니다.

 

해결하신분은 댓글 부탁드립니다.

 

 

 

 

Posted by hoonihoon
2018. 4. 17. 15:13
remount 한다.
1
>adb remount


안드로이드에 있는 host 파일을 받는다.
1
>adb pull /system/etc/hosts D:\TDPlatform\android_home\backup\


hosts 파일 수정한다.
---------------------------------------
기본적으로 로컬만 등록되어 있음.
127.0.0.1      localhost
---------------------------------------

host 파일을 넣는다.
1
>adb push D:\TDPlatform\android_home\work\hosts /system/etc/



hosts 파일 수정 확인해보기

>adb -e shell
#cat /system/etc/hosts



[출처] https://hooni.net/2254



Posted by hoonihoon
2016. 4. 22. 16:03

Sparse arrays can be used to replace hash maps when the key is a primitive type. There are some variants for different key/value type even though not all of them are publicly available.

Benefits are:

  • Allocation-free
  • No boxing

Drawbacks:

  • Generally slower, not indicated for large collections
  • They won't work in non-android project

HashMap can be replaced by the followings:

SparseArray          <Integer, Object>
SparseBooleanArray   <Integer, Boolean>
SparseIntArray       <Integer, Integer>
SparseLongArray      <Integer, Long>
LongSparseArray      <Long, Object>
LongSparseLongArray  <Long, Long>   //this is not a public class                                 
                                    //but can be copied from  Android source code 

In terms of memory here is an example of SparseIntArray vs HashMap for 1000 elements

SparseIntArray:

class SparseIntArray {
    int[] keys;
    int[] values;
    int size;
}

Class = 12 + 3 * 4 = 24 bytes
Array = 20 + 1000 * 4 = 4024 bytes
Total = 8,072 bytes

HashMap:

class HashMap<K, V> {
    Entry<K, V>[] table;
    Entry<K, V> forNull;
    int size;
    int modCount;
    int threshold;
    Set<K> keys
    Set<Entry<K, V>> entries;
    Collection<V> values;
}

Class = 12 + 8 * 4 = 48 bytes
Entry = 32 + 16 + 16 = 64 bytes
Array = 20 + 1000 * 64 = 64024 bytes
Total = 64,136 bytes

Source: Android Memories by Romain Guy from slide 90.

The numbers above are the amount of memory (in bytes) allocated on heap by JVM. They may vary depending on the specific JVM used.

java.lang.instrument package contains some helpful methods for advanced operation like checking the size of an object with getObjectSize(Object objectToSize).

Extra info are available from official Oracle documentation

Class = 12 byte + (n instance variables) * 4 byte
Array = 20 byte + (n elements) * (element size)
Entry = 32 byte + (1st element size) + (2ns elements size)




After some googling I try to add some information to the already posted anwers:

Isaac Taylor made a performance comparision for SparseArrays and Hashmaps. He states that

the Hashmap and the SparseArray are very similar for data structure sizes under 1,000

and

when the size has been increased to the 10,000 mark [...] the Hashmap has greater performance with adding objects, while the SparseArray has greater performance when retrieving objects. [...] At a size of 100,000 [...] the Hashmap loses performance very quickly

An comparision on Edgblog shows that a SparseArray need much less memory than a HashMap because of the smaller key (int vs Integer) and the fact that

a HashMap.Entry instance must keep track of the references for the key, the value and the next entry. Plus it also needs to store the hash of the entry as an int.

As a conclusion I would say that the difference could matter if you are going to store a lot of data in your Map. Otherwise, just ignore the warning.

Posted by hoonihoon
2015. 10. 23. 10:06


서버에서 응답받은 json 을 


오브젝트 리스트형태로 변경하는법!

ArrayList<MyObject> list = new Gson().fromJson(jsonString, new TypeToken<List<MyObject>>() { }.getType());




Posted by hoonihoon
2015. 7. 9. 10:30
  1. SparseArray

    • SparseArray는 Map과 사용방법이 같으며, 안드로이드에서 제공한다. (안드로이드에서는 HashMap보다 SparseArray의 사용을 권장한다.)
    • SparseArray는 Key가 int, long, boolean 으로 Object가 아닌 Primitive type으로 강제되어 있으며, 이는 Integer, Float 등 Wrapper 클래스의 대한 boxing,unboxing 오버헤드와 Object의 대한 메모리 소모를 줄일 수 있다.
    • SparseArray의  Key는 유일해야 한다. 내부 소스를 잠시 본 결과 Key가 같은경우 데이터를 덮어 씌운다.
    • SparseArray는 찾기 알고리즘으로 binarySerch를 사용한다. 
    • 클래스 관계도를 보면 Collection을 구현하고 있지 않으므로 사용시 주의해야 한다.

  2. 결론 
    • 많은 데이터를 Map의 사용방법으로 쓰고자 할 때 SparseArray 사용을 생각해 보자.
    • HashMap을 사용하는 경우 Java가 지원하는 표준 컬렉션으로 이점이 아예없는 것이 아니기 때문에, 데이터의 크기가 많지 않은경우 HashMap을 사용하는 것도 나쁘지는 않다



출저 : http://freegramer.tistory.com/16  자유로운 프로그래머

Posted by hoonihoon
2014. 12. 3. 16:37

아래와 같은 솔루션을 이용하자.


setonItemselectedListener 전에  setselection(position, false); 를 넣으면 된다.



The use of Runnables is completely incorrect.

Use setSelection(position, false); in the initial selection before setOnItemSelectedListener(listener)

This way you set your selection with no animation which causes the on item selected listener to be called. But the listener is null so nothing is run. Then your listener is assigned.

So follow this exact sequence:

Spinner s = (Spinner)Util.findViewById(view, R.id.sound, R.id.spinner);
s.setAdapter(adapter);
s.setSelection(position, false);
s.setOnItemSelectedListener(listener);


Posted by hoonihoon
2014. 12. 3. 14:32

volley post get 방법


출저  : http://stackoverflow.com/questions/16626032/volley-post-get-parameters


For the GET parameters there are two alternatives:

First: As suggested in a comment bellow the question you can just use String and replace the parameters placeholders with their values like:

String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s&param2=%2$s",
                           num1,
                           num2);

StringRequest myReq = new StringRequest(Method.GET,
                                        uri,
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener());
queue.add(myReq);

where num1 and num2 are String variables that contain your values.

Second: If you are using newer external HttpClient (4.2.x for example) you can use URIBuilder to build your Uri. Advantage is that if your uri string already has parameters in it it will be easier to pass it to the URIBuilder and then use ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8"));to add your additional parameters. That way you will not bother to check if "?" is already added to the uri or to miss some & thus eliminating a source for potential errors.

For the POST parameters probably sometimes will be easier than the accepted answer to do it like:

StringRequest myReq = new StringRequest(Method.POST,
                                        "http://somesite.com/some_endpoint.php",
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener()) {

    protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
        Map<String, String> params = new HashMap<String, String>();
        params.put("param1", num1);
        params.put("param2", num2);
        return params;
    };
};
queue.add(myReq);

e.g. to just override the getParams() method.

You can find a working example (along with many other basic Volley examples) in the Andorid Volley Examples project.



출저  : http://stackoverflow.com/questions/16626032/volley-post-get-parameters

Posted by hoonihoon
2014. 11. 27. 15:10




주제:   안드로이드에서 로그인 관련 기능 중에 핸드폰 고유값을 서버에 전송할 수 있을지 알아 보았다.


분석:    아래와 같은 코드로 핸드폰 고유의 값 3가지를 가져올수 있다.


TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);


// IMEI 

Log.d("kth", "telephonyManager.getDeviceId(); " + telephonyManager.getDeviceId());

// 핸드폰 번호

Log.d("kth", "telephonyManager.getLine1Number(); " + telephonyManager.getLine1Number());


// UDID 

String deviceId= Secure.getString(G.mainactivity.getContentResolver(), Secure.ANDROID_ID); 

Log.d("kth", "deviceId: " + deviceId);


결론:  위에 사용 되는 코드는 모두 서버로 전송하면 안된다. 


[테스트 내역]


1. IMEI 수집시에 압수수색  http://www.asiae.co.kr/news/view.htm?idxno=2010083114402683628

    md5 암호화해도 불법.


2. 폰 번호 수집  불법  

  http://lab.gamecodi.com/board/zboard.php?id=GAMECODILAB_QnA_etc&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=3188


3. 다비이스 고유값 (UDID)

   애플에서 UDID 값 수집시 마켓 등록 거절.



다른방법 :  GCM에서 생성해준 디바이스key 값을 이용하는 방법으로 선택.

                단, 어플을 지우고 새로 받으면 디바이스 key 값을 새로 받기 때문에 주의해야 한다.

Posted by hoonihoon