androidX 인지 뭣인지 ConstraintLayout의 package 경로가 바뀌었다.

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

build.gradle 에서 androidx. 으로 사용한다면

implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

layout xml 파일에서도

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

와 같이 다른 package로 사용해야 한다.

728x90

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync

NullPointerException 이라는데

소스는 동일하게

// Build the map.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.google_map);
mapFragment.getMapAsync(this);  // 여기가 nullPointerException 지점

문제는 xml 이다.

예제 : https://github.com/googlemaps/android-samples/blob/master/tutorials/CurrentPlaceDetailsOnMap/app/src/main/java/com/example/currentplacedetailsonmap/MapsActivityCurrentPlace.java

<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />

이렇게 되어 있는데

다음과 같이 변경하면 된다. : supportFragment 관련 내용이 있어야 함.

<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />

 

728x90

잘 동작하던 App인데 배포할 때 28이상을 권장하길래

TargetSDK 버전을 28로 바꾼 것 밖에는 없다.

그런데

java.lang.ClassNotFoundException: Didn't find class "org.apache.http.params.BasicHttpParams"

알고보니 28부터는 http 호출 안되게 변경되었다나?

Manifest 파일을 변경해야 한다.

application tag 안에 추가하면 됨.

 

 <application
        android:usesCleartextTraffic="true"

 >
 <uses-library android:name="org.apache.http.legacy" android:required=false"

</application>

 

 

728x90

오랜만에 이전 앱의 소스를 찾아서 다시 배포하려고 보니
keystore password를 잊어버린것이다. ㅡㅡ

어디 적어놓은 곳도 기억이 안나고...

해결법이 있다.
https://code.google.com/archive/p/android-keystore-password-recover/wikis/HowTo.wiki

 

Google Code Archive - Long-term storage for Google Code Project Hosting.

 

code.google.com

먼저 java가 깔려있는 상태에서

위 링크의 AndroidKeystoreBrute_xxx.jar 를 다운받는다.(가능하면 keystore 파일이 있는곳으로 옮긴다)

윈도우 + R 누른 뒤 command 를 입력하고 엔터를 치면 커맨드 창이 나온다
keystore 파일이 있는곳으로 이동 cd c:\keystore 같이

찾는방법이 3가지 있는데 파일명이 xxx.keystore 을 입력하면된다.
1. java -jar AndroidKeystoreBrute_v1.05.jar -m 1 -k <...keystore> -start AAAAAA

java -jar AndroidKeystoreBrute_v1.05.jar -m 1 -k "testkeystore.keystore" -start AAAAAA
입력하면 AAAAAA -> AAAAAB -> AAAAAC 와 같이 일일이 대입하는 방식이다.

추천하는 방법은 3번. wordlist.txt 파일을 만든 뒤에
가능성 있는 단어들을 입력한다.(한줄에 한단어씩)
java -jar AndroidKeystoreBrute_v1.05.jar -m 3 -k "C:\\mykeystore.keystore" -d "wordlist.txt"
그러면 wordlist.txt의 단어를 대입하여 찾는다.

찾게되면
Password is : xxx for alias mykeystore

alias가 mykeystore
여기에 대한 password가 xxx

 

 

 

 

 

 

728x90

xml에 정의

<View
        android:id="@+id/view"
        class="android.support.v4.view.ViewPager" ... </View>

java에서 사용

import android.support.v4.view.ViewPager;

ViewPager viewPager = (ViewPager) findViewById(R.id.view); 

위와 같이 했는데

Caused by: java.lang.ClassCastException: android.view.View cannot be cast to android.support.v4.view.ViewPager

오류가 난다...

이럴 때는 xml에 class를 별도로 지정하지 않고 Tag에 전체경로를 쓰면 된다.

<android.support.v4.view.ViewPager
        android:id="@+id/view"  ...
728x90

Android 에서 파일 저장할 떄

1. 권한이 있는가?

AndroidManifest.xml 에 권한 설정 확인

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


권한이 부여되어 있다면 저장 경로확인

일반적으로 저장할 때 사용하는 경로는 getAbsolutePath() 아래에 파일명을 추가하면 된다.

String path = Environment.getExternalStorageDirectory().getAbsolutePath()

storage/emulated/0번째 아래에 myaudio.3gp 로(파일명은 다르겠지만) 저장된다.

그런데 내가 원하는 경로로 했을 때 해당 경로가 없으면 저장이 되지 않는다.

abc라는 폴더가 있는지 확인하고 없으면 생성하도록 한다.

String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/abc/";
File dir = new File(path);
if(!dir.exists()) {
dir.mkdirs();
}

filename = path + "myaudio.3gp"



728x90

RecyclerView 를 사용할 때

build.gradle 에 depencies 에 정의를 추가해야 하는데

버전 설정이 중요하다.


먼저 appcompat와 버전을 동일하게 해야 한다고 한다.

그런데 v7:28로 recycleview를 맞췄는데도 안되더라...


그래서 아래와 같이 v7:+ 로 하니까 됨.

dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
// implementation 'com.android.support:recyclerview-v7:28.1.0'
implementation 'com.android.support:recyclerview-v7:+'

}

 


728x90

버튼의 경우 기본 속석으로 enable 속성이 있다.

다른 View 들도 마찬가지인데 button의 경우 enable(false)로 하게되면 error가 자꾸 나면서 App이 종료된다.


자꾸 종료되고 재시작되고...

결국 찾은 결론은 button의 경우는 click이 기본 기능이므로 clickable로 대체하는 것이다.

//btnStop.setEnabled(false);
btnStop.setClickable(false);

이렇게 하면 click 했을 때, true/false로 제어는 가능하지만 보이기로는 구분이 되지 않는다.

그래서 true일 때 보여주는 이미지, false일 때 보여주는 이미지를 같이 설정하도록 하면 된다.


728x90

ADMob 설정

2019. 3. 6. 00:41

admob 설정은 크게 두 개의 id 를 어디에 넣느냐에 달려있다.

string.xml 에 admob_app_id 와 banner_add_unit_id 값을 추가하면되는데



1. admob_app_id

admob 사이트에서

해당 앱의 앱설정에 나오는 앱 ID


androidManifest.xml 에 정의하는 값.

<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/admob_app_id"/>


2. banner_add_unit_id

해당앱의 광고단위에 나오는 해당 단위에 나오는 값 ca-app-pub-xxx 값


activity 내 view로 정의할 때 사용

test용 banner_id 는 ca-app-pub-3940256099942544/6300978111

<com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="@+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
ads:adSize="SMART_BANNER"
ads:adUnitId="@string/banner_ad_unit_id"><!-- @string/admob_app_id, banner test id : ca-app-pub-3940256099942544/6300978111 -->

</com.google.android.gms.ads.AdView>

3. activity내에서 사용시

MobileAds.initialize(this, getString(R.string.admob_app_id));
mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);


728x90

다운로드 링크

https://play.google.com/store/apps/details?id=com.nobang.callforone


콜포원의 기능은 단순하다.

빅스비 버튼을 누르면 지정된 번호로 전화걸기.


이를 위해서 어플 설치 후 빅스비 설정을 해야 한다.

1. 설정 > 유용한 기능 > 빅스비 버튼을 터치


2. 빅스비는 무조건 사용해야 된다.

 - 시작하기 버튼 터치



3. 한번 눌렀을 때 실행 또는 두번 눌렀을 때 실행을 선택하면

나머지 경우에 콜포원을 지정하여 사용할 수 있다.


예로 다음과 같이 설정한다.

한번 눌렀을 때 : 콜포원 실행

두번 눌렀을 때 : 빅스비 실행


- 두번 눌러서 빅스비 열기 선택

- 한번 누르기 사용을 활성화



3. 한 번 누르기 사용 활성화

 - 사용안함 -> 사용함으로 바꾸면 앱열기도 활성화 됨.


4. 앱 열기 선택 후 톱니바퀴를 터치하면 실행할 앱목록이 나옴.


콜포원 ( call for one ) 을 선택



5. 설정에 맞게 빅스비 버튼을 누르면 (한번 또는 두번)

콜포원 설정화면이 나온다.

- 전화번호를 입력한다.

- 자동 전화걸기를 활성화 해야 5초 후 자동으로 전화가 걸린다.


6. 설정이 끝났으면 종료 후 다시 빅스비 버튼을 누르면

카운트 다운 5,4,3,2,1 이후 지정한 번호로 전화를 건다.

아래 3가지 경우에 전화걸기가 되지 않는다.


- 전화번호가 입력되지 않으면 동작하지 않음.

- 자동 전화걸기 활성화 되어있지 않으면 동작하지 않음.

- 통화중인 경우 동작하지 않음.




728x90
BLOG main image
"그게 뭐 어쨌다는 거냐?" 늘 누가 나에게 나에대한 말을할 때면 이말을 기억해라. by nobang

카테고리

nobang이야기 (1933)
Life With Gopro (7)
Life With Mini (79)
Diary (971)
너 그거 아니(do you know) (162)
난 그래 (159)
Study (290)
Cloud (26)
Go lang (30)
Front-end (27)
Device (3)
MAC (1)
Spring framework (49)
Java (13)
English (39)
SOA (0)
Idioms (7)
모르는거 (5)
WriteEnglish (10)
Android (56)
속지말자 (10)
Project (34)
Poem (15)
Song (0)
Photo (113)
낙서장 (45)
일정 (0)
C.A.P.i (2)
PodCast (0)
nobang (27)
고한친구들 (4)
recieve (0)
History (0)
android_app (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :