반응형

안드로이드 앱설치 여부를 확인하기 위해서는 해당앱의 패키지 명을 알고 있어야합니다.


isInstallPackage_2(this,"com.test.pkgname");

/**
* 설치여부를 판단한다
* @param context context
* @param pkgName 패키지명
* @return 설치여부
*/
public static String isInstallPackage_2(Context context, String pkgName){
PackageManager manager = context.getPackageManager();
PackageInfo pi;
try {
pi = manager.getPackageInfo(pkgName, PackageManager.GET_META_DATA);
if(pi!=null){
return pi.versionName+"";
}
} catch (NameNotFoundException e) {
}
return null;
}


반응형
반응형

매니페스트에 다음과 같이 밑줄 된 값이 필요할때 다음과 같이 가져온다.


AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.si.pe.shin.library"
android:versionCode="1"
android:versionName="3.7.0" >

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:description="@string/app_name"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.MainActivity"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

/**
* 매니페스트 버전을 얻는다
* @param context context
* @return 버전
*/
public static String getVersionName(Context context) {
String version = "";
try {
PackageInfo i = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
version = i.versionName + "";
} catch(NameNotFoundException e) {
}
return version;
}
/**
* 매니페스트 버전코드를 얻는다
* @param context context
* @return 버전코드
*/
public static int getVersionCode(Context context) {
int versionCode = 1;
try {
PackageInfo i = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
versionCode = i.versionCode;
} catch(NameNotFoundException e) {
}
return versionCode;
}
/**
* 매니페스트 Description를 얻는다
* @param context context
* @return 어플아이디
*/
public static String getDescription(Context context) {
String appId = "";
try {
PackageManager pm = context.getPackageManager();
PackageInfo i = pm.getPackageInfo(context.getPackageName(), 0);
appId = i.applicationInfo.loadDescription(pm) + "";
} catch(NameNotFoundException e) {
}
return appId;
}

/**
* 매니페스트 Label을 얻는다
* @param context context
*/
public static String getAppLabel(Context context) {
String appName = "";
try {
PackageManager pm = context.getPackageManager();
PackageInfo i = pm.getPackageInfo(context.getPackageName(), 0);
appName = i.applicationInfo.loadLabel(pm) + "";
} catch(NameNotFoundException e) {
}
return appName;
}


반응형
반응형

개발을 하다보면 특정앱은 백그라운드에 남기지 말아야할때가 있습니다.


그럴때는 


        <activity

            android:name=".MainActivity"

            android:label="@string/app_name" 

            android:excludeFromRecents="true"

            >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>


밑에 코드를 매니페스트 액티비티에 사용해주시면 앱이 백그라운드에 남아 있지않게 됩니다.

android:excludeFromRecents="true"


밑에 그림을 보시면 현재 저는 Test을 실행시키고 스마트폰 백그라운드를 열었습니다.

이렇게 그림만 보면 모르겠지만 원래는 Test앱이 네이버앱 앞에 표시되어야합니다.

하지만 저는 android:excludeFromRecents="true"해당 코드를 사용하여

앱이 백그라운드에 표시되지 않도록 하였습니다.

반응형
반응형

첫문자를 숫자를 입력할 경우숫자만 입력되고

첫문자를 영어를 입력할 경우 영어만 입력되는 예제


private EditText mEdit;


@Override

protected void onCreateX(Bundle savedInstanceState) {

mEdit = (EditText)findViewById(R.id.test_edit);

mEdit.addTextChangedListener(new TextWatcher() {

@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

// TODO Auto-generated method stub

if(count == 0){

mEdit.setFilters(new InputFilter[]{filterAll});

}else if(count == 1){

if(isNumber(s.toString())){

mEdit.setFilters(new InputFilter[]{filterNum});

}else{

mEdit.setFilters(new InputFilter[]{filterEng});

}

}

}

@Override

public void beforeTextChanged(CharSequence s, int start, int count,

int after) {

// TODO Auto-generated method stub

}

@Override

public void afterTextChanged(Editable s) {

// TODO Auto-generated method stub

}

});

}

   public static boolean isNumber(String str){

       boolean result = false;

       try{

           Double.parseDouble(str) ;

           result = true ;

       }catch(Exception e){}


       return result ;

   }

    

    private InputFilter filterNum = new InputFilter() {

@Override

public CharSequence filter(CharSequence source, int start, int end,

Spanned dest, int dstart, int dend) {

// TODO Auto-generated method stub

Pattern ps = Pattern.compile("^[0-9]+$");

if(!ps.matcher(source).matches()){

return "";

}

return null;

}

};

    private InputFilter filterEng = new InputFilter() {

@Override

public CharSequence filter(CharSequence source, int start, int end,

Spanned dest, int dstart, int dend) {

// TODO Auto-generated method stub

Pattern ps = Pattern.compile("^[a-zA-Z]+$");

if(!ps.matcher(source).matches()){

return "";

}

return null;

}

};

    private InputFilter filterAll = new InputFilter() {

@Override

public CharSequence filter(CharSequence source, int start, int end,

Spanned dest, int dstart, int dend) {

return source;

}

};




반응형
반응형

안드로이드 타겟버전은 정하지않고 최소버전이 12인 상태에서 Theme.Holo.Light 테마를 쓰는 상태일경우

DatePickerDialog, DatePickerDialog가 앱이 죽는 현상 발생


현재 매니페스트 상태

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testdatepicker"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="12"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


해결방법

날짜

private void showCalendarDialog() {
Context context = null;
DatePickerDialog dialog = null;
Calendar calendar = Calendar.getInstance();

// 안드로이드 7.0버전부터 Theme.Holo.Light를 지원하지 않음
if (Build.VERSION.SDK_INT >= 24) {
context = new ContextThemeWrapper(mContext, android.R.style.Theme_DeviceDefault_Light_Dialog);
}else{
context = mContext;
}

dialog = new DatePickerDialog(context, mDateSetListener, calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
dialog.show();
}


private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub

}

};


시간

private void showTimeDialog() {

Context context = null;
TimePickerDialog dialog = null;
Calendar calendar = Calendar.getInstance();

// 안드로이드 7.0버전부터 Theme.Holo.Light를 지원하지 않음
if (Build.VERSION.SDK_INT >= 24) {
context = new ContextThemeWrapper(mContext, android.R.style.Theme_DeviceDefault_Light_Dialog);
}else{
context = mContext;
}

dialog = new TimePickerDialog(context, mTimeSetListener, calendar.get(Calendar.HOUR_OF_DAY), 0, true);
dialog.show();
}

private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// TODO Auto-generated method stub

}

};



어떤 테마스타일 이쁜지 확인하고 싶을경우

MainActivity.class


import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity implements OnItemClickListener {
private final static boolean isShowDatePickerDialog = true; // DatePickerDialog 노출여부

private Context mContext = null;
private LinearLayout mLinearLayout = null;
private ListView mListView = null;
private int[] mStyleIdArr = {
android.R.style.Theme,
android.R.style.Theme_Black,
android.R.style.Theme_Black_NoTitleBar,
android.R.style.Theme_Black_NoTitleBar_Fullscreen,
android.R.style.Theme_DeviceDefault,
android.R.style.Theme_DeviceDefault_Dialog,
android.R.style.Theme_DeviceDefault_Dialog_MinWidth,
android.R.style.Theme_DeviceDefault_Dialog_NoActionBar,
android.R.style.Theme_DeviceDefault_Dialog_NoActionBar_MinWidth,
android.R.style.Theme_DeviceDefault_DialogWhenLarge,
android.R.style.Theme_DeviceDefault_DialogWhenLarge_NoActionBar,
android.R.style.Theme_DeviceDefault_InputMethod,
android.R.style.Theme_DeviceDefault_Light,
android.R.style.Theme_DeviceDefault_Light_DarkActionBar,
android.R.style.Theme_DeviceDefault_Light_Dialog,
android.R.style.Theme_DeviceDefault_Light_Dialog_MinWidth,
android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar,
android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth,
android.R.style.Theme_DeviceDefault_Light_DialogWhenLarge,
android.R.style.Theme_DeviceDefault_Light_DialogWhenLarge_NoActionBar,
android.R.style.Theme_DeviceDefault_Light_NoActionBar,
android.R.style.Theme_DeviceDefault_Light_NoActionBar_Fullscreen,
android.R.style.Theme_DeviceDefault_Light_Panel,
android.R.style.Theme_DeviceDefault_NoActionBar,
android.R.style.Theme_DeviceDefault_NoActionBar_Fullscreen,
android.R.style.Theme_DeviceDefault_Panel,
android.R.style.Theme_DeviceDefault_Wallpaper,
android.R.style.Theme_DeviceDefault_Wallpaper_NoTitleBar,
android.R.style.Theme_Dialog, android.R.style.Theme_Holo,
android.R.style.Theme_Holo_Dialog,
android.R.style.Theme_Holo_Dialog_MinWidth,
android.R.style.Theme_Holo_Dialog_NoActionBar,
android.R.style.Theme_Holo_Dialog_NoActionBar_MinWidth,
android.R.style.Theme_Holo_DialogWhenLarge,
android.R.style.Theme_Holo_DialogWhenLarge_NoActionBar,
android.R.style.Theme_Holo_InputMethod,
android.R.style.Theme_Holo_Light,
android.R.style.Theme_Holo_Light_DarkActionBar,
android.R.style.Theme_Holo_Light_Dialog,
android.R.style.Theme_Holo_Light_Dialog_MinWidth,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth,
android.R.style.Theme_Holo_Light_DialogWhenLarge,
android.R.style.Theme_Holo_Light_DialogWhenLarge_NoActionBar,
android.R.style.Theme_Holo_Light_NoActionBar,
android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen,
android.R.style.Theme_Holo_Light_Panel,
android.R.style.Theme_Holo_NoActionBar,
android.R.style.Theme_Holo_NoActionBar_Fullscreen,
android.R.style.Theme_Holo_Panel,
android.R.style.Theme_Holo_Wallpaper,
android.R.style.Theme_Holo_Wallpaper_NoTitleBar,
android.R.style.Theme_InputMethod, android.R.style.Theme_Light,
android.R.style.Theme_Light_NoTitleBar,
android.R.style.Theme_Light_NoTitleBar_Fullscreen,
android.R.style.Theme_Light_Panel,
android.R.style.Theme_Light_WallpaperSettings,
android.R.style.Theme_NoDisplay, android.R.style.Theme_NoTitleBar,
android.R.style.Theme_NoTitleBar_Fullscreen,
android.R.style.Theme_NoTitleBar_OverlayActionModes,
android.R.style.Theme_Panel, android.R.style.Theme_Translucent,
android.R.style.Theme_Translucent_NoTitleBar,
android.R.style.Theme_Translucent_NoTitleBar_Fullscreen,
android.R.style.Theme_Wallpaper,
android.R.style.Theme_Wallpaper_NoTitleBar,
android.R.style.Theme_Wallpaper_NoTitleBar_Fullscreen,
android.R.style.Theme_WallpaperSettings,
android.R.style.Theme_WithActionBar };

private String[] mStyleNameArr = { "Theme", "Theme_Black",
"Theme_Black_NoTitleBar", "Theme_Black_NoTitleBar_Fullscreen",
"Theme_DeviceDefault", "Theme_DeviceDefault_Dialog",
"Theme_DeviceDefault_Dialog_MinWidth",
"Theme_DeviceDefault_Dialog_NoActionBar",
"Theme_DeviceDefault_Dialog_NoActionBar_MinWidth",
"Theme_DeviceDefault_DialogWhenLarge",
"Theme_DeviceDefault_DialogWhenLarge_NoActionBar",
"Theme_DeviceDefault_InputMethod", "Theme_DeviceDefault_Light",
"Theme_DeviceDefault_Light_DarkActionBar",
"Theme_DeviceDefault_Light_Dialog",
"Theme_DeviceDefault_Light_Dialog_MinWidth",
"Theme_DeviceDefault_Light_Dialog_NoActionBar",
"Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth",
"Theme_DeviceDefault_Light_DialogWhenLarge",
"Theme_DeviceDefault_Light_DialogWhenLarge_NoActionBar",
"Theme_DeviceDefault_Light_NoActionBar",
"Theme_DeviceDefault_Light_NoActionBar_Fullscreen",
"Theme_DeviceDefault_Light_Panel",
"Theme_DeviceDefault_NoActionBar",
"Theme_DeviceDefault_NoActionBar_Fullscreen",
"Theme_DeviceDefault_Panel", "Theme_DeviceDefault_Wallpaper",
"Theme_DeviceDefault_Wallpaper_NoTitleBar", "Theme_Dialog",
"Theme_Holo", "Theme_Holo_Dialog", "Theme_Holo_Dialog_MinWidth",
"Theme_Holo_Dialog_NoActionBar",
"Theme_Holo_Dialog_NoActionBar_MinWidth",
"Theme_Holo_DialogWhenLarge",
"Theme_Holo_DialogWhenLarge_NoActionBar", "Theme_Holo_InputMethod",
"Theme_Holo_Light", "Theme_Holo_Light_DarkActionBar",
"Theme_Holo_Light_Dialog", "Theme_Holo_Light_Dialog_MinWidth",
"Theme_Holo_Light_Dialog_NoActionBar",
"Theme_Holo_Light_Dialog_NoActionBar_MinWidth",
"Theme_Holo_Light_DialogWhenLarge",
"Theme_Holo_Light_DialogWhenLarge_NoActionBar",
"Theme_Holo_Light_NoActionBar",
"Theme_Holo_Light_NoActionBar_Fullscreen",
"Theme_Holo_Light_Panel", "Theme_Holo_NoActionBar",
"Theme_Holo_NoActionBar_Fullscreen", "Theme_Holo_Panel",
"Theme_Holo_Wallpaper", "Theme_Holo_Wallpaper_NoTitleBar",
"Theme_InputMethod", "Theme_Light", "Theme_Light_NoTitleBar",
"Theme_Light_NoTitleBar_Fullscreen", "Theme_Light_Panel",
"Theme_Light_WallpaperSettings", "Theme_NoDisplay",
"Theme_NoTitleBar", "Theme_NoTitleBar_Fullscreen",
"Theme_NoTitleBar_OverlayActionModes", "Theme_Panel",
"Theme_Translucent", "Theme_Translucent_NoTitleBar",
"Theme_Translucent_NoTitleBar_Fullscreen", "Theme_Wallpaper",
"Theme_Wallpaper_NoTitleBar",
"Theme_Wallpaper_NoTitleBar_Fullscreen", "Theme_WallpaperSettings",
"Theme_WithActionBar" };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mListView = (ListView) findViewById(R.id.test_list);
for (int i = 0; i < mStyleIdArr.length; i++) {
Button btnButton = new Button(this);
btnButton.setText(mStyleNameArr[i]);
}
ArrayAdapter<String> testAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mStyleNameArr);
mListView.setAdapter(testAdapter);
mListView.setOnItemClickListener(this);

}

//날짜 다이얼로그
private void showCalendarDialog(int style) {
Calendar calendar = Calendar.getInstance();

DatePickerDialog dialog = null;

dialog = new DatePickerDialog(mContext, style, mDateSetListener,
calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));

dialog.show();

}

//시간 다이얼로그
private void showTimeDialog(int style) {
Calendar calendar = Calendar.getInstance();
TimePickerDialog dialog = null;
dialog = new TimePickerDialog(mContext, style, mTimeSetListener,
calendar.get(Calendar.HOUR_OF_DAY), 0, true);

dialog.show();

}

private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub

}

};

private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// TODO Auto-generated method stub

}

};

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(this, "position" + position, Toast.LENGTH_SHORT).show();
if(isShowDatePickerDialog) {
showCalendarDialog(mStyleIdArr[position]);
}else{
showTimeDialog(mStyleIdArr[position]);
}
}


}


activity_main.xml

<RelativeLayout 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" >


<ListView
android:id="@+id/test_list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>

</RelativeLayout>


반응형
반응형

Random random = new Random();

//0~100 랜덤

int num1 = random.nextInt(100);

//1~100 랜덤

int num2 = random.nextInt(100)+1;

//50~100 랜덤

int num3 = random.nextInt(50)+51;

//70~100 랜덤

int num4 = random.nextInt(70)+31;

//20~30 랜덤

int num5 = random.nextInt(10)+21;

//100~120 랜덤

int num6 = random.nextInt(20)+101;

 System.out.println("1번 = "+num1);

 System.out.println("2번 = "+num2);

 System.out.println("3번 = "+num3); 

 System.out.println("4번 = "+num4); 

 System.out.println("5번 = "+num5); 

 System.out.println("6번 = "+num6);


결과

1번 = 41

2번 = 76

3번 = 67

4번 = 54

5번 = 28

6번 = 112



반응형

'Java' 카테고리의 다른 글

안드로이드 특수문자 체크 로직  (2) 2019.06.10
java 정렬  (0) 2017.05.23
java 파일용량 계산  (0) 2017.05.23
액티비티 할당된 메모리 즉시 반환하기  (0) 2016.01.12
Java Null Check 코드  (0) 2015.06.29
반응형


public class TestData {
private String name = null;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
/**
* 이름 정렬
* @param isSort true=내림차순 false=오름차순

*/
public static ArrayList<?> testNameSort(boolean isSort,ArrayList<?> list){
Comparator<Object> nameSortConparator= new Comparator<Object>() {

private final Collator collator = Collator.getInstance();

@Override

public int compare(Object object1, Object object2) {
int i = 0;
i = collator.compare(((TestData)object1).getName(), ((TestData)object2).getName());
return i;
}

};

if(list !=null)
{
//Comparator 를 만든다.
Collections.sort(list, nameSortConparator);
if(isSort) {
Collections.reverse(list);
}
}

return list;
}



반응형

'Java' 카테고리의 다른 글

안드로이드 특수문자 체크 로직  (2) 2019.06.10
자바 랜덤  (0) 2017.05.23
java 파일용량 계산  (0) 2017.05.23
액티비티 할당된 메모리 즉시 반환하기  (0) 2016.01.12
Java Null Check 코드  (0) 2015.06.29
반응형

/**파일 확장자 가져오기
* @param fileStr 경로나 파일이름
* @return*/
public static String getExtension(String fileStr){
String fileExtension = fileStr.substring(fileStr.lastIndexOf(".")+1,fileStr.length());
return TextUtils.isEmpty(fileExtension) ? null : fileExtension;
}

/**파일 이름 가져오기
* @param fileStr 파일 경로
* @param isExtension 확장자 포함 여부
* @return */
public static String getFileName(String fileStr , boolean isExtension){
String fileName = null;
if(isExtension)
{
fileName = fileStr.substring(fileStr.lastIndexOf("/"),fileStr.lastIndexOf("."));
}else{
fileName = fileStr.substring(fileStr.lastIndexOf("/")+1);
}
return fileName;
}


반응형
반응형


FileCache.java

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public interface FileCache {

public FileEntry get(String key);

public void put(String key, ByteProvider provider) throws IOException;

public void put(String key, InputStream is) throws IOException;

public void put(String key, File sourceFile, boolean move) throws IOException;

public void remove(String key);

public void clear();

public boolean has(String key);
}


FileEntry.java

public class FileEntry {

private String key;
private File file;

public FileEntry(String key, File file) {
this.key = key;
this.file = file;
}

public InputStream getInputStream() throws IOException {
return new BufferedInputStream(new FileInputStream(file));
}

public String getKey() {
return key;
}

public File getFile() {
return file;
}

}


FileCacheImpl.java

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class FileCacheImpl implements FileCache {

private CacheStorage cacheStorage;

public FileCacheImpl(File cacheDir, int maxKBSizes) {
long maxBytesSize = maxKBSizes <= 0 ? 0 : maxKBSizes * 1024;
cacheStorage = new CacheStorage(cacheDir, maxBytesSize);
}

@Override
public FileEntry get(String key) {
File file = cacheStorage.get(keyToFilename(key));
if (file == null) {
return null;
}
if (file.exists()) {
return new FileEntry(key, file);
}
return null;
}

@Override
public void put(String key, ByteProvider provider) throws IOException {
cacheStorage.write(keyToFilename(key), provider);
}

@Override
public void put(String key, InputStream is) throws IOException {
put(key, ByteProviderUtil.create(is));
}

@Override
public void put(String key, File sourceFile, boolean move)
throws IOException {
if (move) {
cacheStorage.move(keyToFilename(key), sourceFile);
} else {
put(key, ByteProviderUtil.create(sourceFile));
}
}

@Override
public void remove(String key) {
cacheStorage.delete(keyToFilename(key));
}

private String keyToFilename(String key) {
String filename = key.replace(":", "_");
filename = filename.replace("/", "_s_");
filename = filename.replace("\\", "_bs_");
filename = filename.replace("&", "_bs_");
filename = filename.replace("*", "_start_");
filename = filename.replace("?", "_q_");
filename = filename.replace("|", "_or_");
filename = filename.replace(">", "_gt_");
filename = filename.replace("<", "_lt_");
return filename;
}

@Override
public void clear() {
cacheStorage.deleteAll();
}

@Override
public boolean has(String key) {
return cacheStorage.has(key);
}


}


IOUtils.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

public abstract class IOUtils {

public static String read(InputStream is) throws IOException {
InputStreamReader reader = null;
try {
reader = new InputStreamReader(is);
StringBuilder builder = new StringBuilder();
char[] readDate = new char[1024];
int len = -1;
while ((len = reader.read(readDate)) != -1) {
builder.append(readDate, 0, len);
}
return builder.toString();
} finally {
close(reader);
}
}

public static void copy(InputStream is, OutputStream out)
throws IOException {
byte[] buff = new byte[4096];
int len = -1;
while ((len = is.read(buff)) != -1) {
out.write(buff, 0, len);
}
}


public static void copy(File source, OutputStream os) throws IOException {
BufferedInputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(source));
IOUtils.copy(is, os);
} finally {
IOUtils.close(is);
}
}

public static void copy(InputStream is, File target) throws IOException {
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(target));
IOUtils.copy(is, os);
} finally {
IOUtils.close(os);
}
}

public static void copy(String str, OutputStream os) throws IOException {
os.write(str.getBytes());
}

public static void close(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
}
}
}

}


FileCacheFactory.java

import android.content.Context;
import java.io.File;
import java.util.HashMap;

public class FileCacheFactory {

private static boolean initialized = false;
private static FileCacheFactory instance = new FileCacheFactory();

public static void initialize(Context context, String file_dir) {
if (!initialized) {
synchronized (instance) {
if (!initialized) {
instance.init(context,file_dir);
initialized = true;
}
}
}
}

public static FileCacheFactory getInstance() {
if (!initialized) {
throw new IllegalStateException(
"Not initialized. You must call FileCacheFactory.initialize() before getInstance()");
}
return instance;
}

private HashMap<String, FileCache> mCacheMap = new HashMap<String, FileCache>();
private File mCacheBaseDir;

private FileCacheFactory() {
}

private void init(Context context) {
mCacheBaseDir = context.getCacheDir();
}

private void init(Context context, String file_dir) {
// cacheBaseDir = context.getCacheDir();
mCacheBaseDir = new File(file_dir);
}

public FileCache create(String cacheName, int maxKbSizes) {
synchronized (mCacheMap) {
FileCache cache = mCacheMap.get(cacheName);
File cacheDir = new File(mCacheBaseDir, cacheName);
if (cache != null) {
try {
cache = new FileCacheImpl(cacheDir, maxKbSizes);
mCacheMap.put(cacheName, cache);
} catch (Exception e) {
String.format("FileCache[%s] Aleady exists", cacheName);
}
}


return cache;
}
}

public FileCache get(String cacheName) {
synchronized (mCacheMap) {
FileCache cache = mCacheMap.get(cacheName);
if (cache == null) {
try {

}catch (Exception e)
{
String.format("FileCache[%s] not founds.", cacheName);
}
}
return cache;
}
}

public void destroy(String cacheName)
{
FileCache cache = mCacheMap.get(cacheName);

File file = new File(mCacheBaseDir+File.separator+cacheName);
if(file.exists())
{
file.delete();
}
}

public void clear(){
mCacheMap.clear();
}

public boolean has(String cacheName) {
return mCacheMap.containsKey(cacheName);
}
}

설명

캐시 디렉토리 안에 캐시파일이 여러개 저장되는 방식입니다. 


사용방법

1. 캐시 디렉토리

private FileCache mFileCache = null;

public static final String CACHE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "FolderName" + File.separator + ".cache"; //캐시 기본폴더

FileCacheFactory.initialize(mContext, CACHE_PATH);
if (!FileCacheFactory.getInstance().has(zipDirName)) // 해당 키의 캐시 디렉토리가 있는지 확인
{
FileCacheFactory.getInstance().create(zipDirName, 0); // 캐시디렉토리가 없을경우 만든다.
}
mFileCache = FileCacheFactory.getInstance().get(zipDirName); // 해당 파일의 캐시 디렉토리를 가져온다.


- 캐시 객체 생성

FileCacheFactory.initialize(mContext, CACHE_PATH);

- 캐시디렉토리 존재 여부 체크

FileCacheFactory.getInstance().has(Dirkey)

- 캐시디렉토리 생성

FileCacheFactory.getInstance().create(Dirkey, 0); // 캐시디렉토리가 없을경우 만든다.

- 캐시디렉토리 가져오기

mFileCache = FileCacheFactory.getInstance().get(Dirkey); // 해당 파일의 캐시 디렉토리를 가져온다.


2. 캐시 

-캐시 저장

/**
* @param key cache
* @param val cache 내용
* @param isMove ture = val파일이 캐시경로로 이동됨, false = val파일이 캐시경로로 복사됨
*/
private void setCacheFile(String key, File val, boolean isMove) {
if (!mFileCache.has(key)) {
try {
mFileCache.put(key, val, isMove);
} catch (IOException e) {
e.printStackTrace();
}
}
}

-캐시 가져오기

/**
* 캐시내용을 가져온다.
* @param key cache
* @return
*/
public FileEntry getCacheFile(String key) {

return mFileCache.get(key);
}


chche.zip


반응형
반응형
/**
* 용량계산
* @param size
* @return
*/
public static String sizeCalculation(long size) {
String CalcuSize = null;
int i = 0;

double calcu = (double) size;
while (calcu >= 1024 && i < 5) { // 단위 숫자로 나누고 한번 나눌 때마다 i 증가
calcu = calcu / 1024;
i++;
}
DecimalFormat df = new DecimalFormat("##0.0");
switch (i) {
case 0:
CalcuSize = df.format(calcu) + "Byte";
break;
case 1:
CalcuSize = df.format(calcu) + "KB";
break;
case 2:
CalcuSize = df.format(calcu) + "MB";
break;
case 3:
CalcuSize = df.format(calcu) + "GB";
break;
case 4:
CalcuSize = df.format(calcu) + "TB";
break;
default:
CalcuSize="ZZ"; //용량표시 불가

}
return CalcuSize;
}




반응형

'Java' 카테고리의 다른 글

자바 랜덤  (0) 2017.05.23
java 정렬  (0) 2017.05.23
액티비티 할당된 메모리 즉시 반환하기  (0) 2016.01.12
Java Null Check 코드  (0) 2015.06.29
Java 인스턴스 하나만 사용하기(싱글턴 패턴)  (0) 2015.06.29
반응형

Apache Commons Compress 1.14

라이브러리를 import 해줍니다.

jar파일 다운로드 url


import org.apache.commons.compress.utils.IOUtils;

/**
* 파일 복사
*
* @return exist 복사 성공 여부

*/
public synchronized boolean copyFile(String inFilePath, String outFilePath) {
FileInputStream fis = null;
FileOutputStream fos = null;
File file = null;
boolean exist = false;
try {
fis = new FileInputStream(inFilePath);
fos = new FileOutputStream(outFilePath);
IOUtils.copy(fis, fos);

file = new File(outFilePath);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
// 마지막에 FileInputStream / FileOutputStream을 닫아준다.
if (fis != null) try {
fis.close();
}
catch (IOException e) {
Log.i("파일복사", "fileInput error");
}

if (fos != null)
try {
fos.close();
}
catch (IOException e) {
Log.i("파일복사", "fileOutput error");
}
if (file != null) {                 // 복사한 경로에 File있는지 확인
if (file.exists()) {
exist = true;
}
else {
exist = false;
}
}

}
return exist;
}



반응형
반응형

이번에 알림기능을 넣고 앱을 테스트 하면서

안드로이드 ics 버전에서 앱이 죽는 현상이 발생하여 다음과 같이 해결

public static void ViewNotice(String notiTitle ,String notiContent,Context context){ NotificationManager mNM; mNM = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);         Intent mI = new Intent(); mI.setClass(context, NotiViewActivity.class); mI.putExtra("NOTICE", notiContent); mI.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, mI, PendingIntent.FLAG_UPDATE_CURRENT);     Notification notification = null;                 //안드로이드 버전 체크 if(Build.VERSION_CODES.KITKAT<Build.VERSION.SDK_INT){                     //킷켓보다 버전 보다 높을 경우

Notification.Builder builder = new Notification.Builder(context); builder.setSmallIcon(R.drawable.icon_t); builder.setWhen(System.currentTimeMillis()); builder.setContentTitle("공지 제목"); builder.setContentText("공지 내용"); builder.setContentIntent(contentIntent); notification = builder.build(); }else{                     //킷켓 버전이하일 경우

    notification = new Notification(R.drawable.icon_t, null, System.currentTimeMillis());     notification.setLatestEventInfo(context, "공지 제목","공지 내용", contentIntent); } notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE; notification.defaults |= Notification.DEFAULT_SOUND; mNM.notify(0, notification); }


특정버전 이하에서는 Notification notification = builder.build(); 지원하지 않는것 같음

안드로이드 ics 버전에서는 다음과 같이 정의하면 오류가 나지 않는다.

		    notification = new Notification(R.drawable.icon_t, null, System.currentTimeMillis());
	            notification.setLatestEventInfo(context, "공지 제목","공지 내용", contentIntent);




반응형
반응형

https://developer.android.com/preview/features/working-with-fonts.html?hl=ko#fonts-in-xml 

해당 페이지에서 번역하여 저 나름대로의 주관적인 의견을 더한 게시물입니다.


Android O에는 XML안에서 font리소스를 사용할 수 있는 새로운 기능이 추가되었습니다.

이제 색다른 글씨체로 안드로이드 앱을 구현할 수 있습니다.(일이 늘어날거 같은 느낌...)

Android O는 시스템 font와 관련된 정보를 검색하고 파일 설명자를 제공하는 메커니즘도 제공합니다.


Font 및 XML

Android O를 사용하면 font파일을 res / font / (요기)  해당 경로에 font를 추가하여 글꼴들을 한데 모아놓을 수 있습니다. 

이 글꼴은 R 파일에서 컴파일되며 Android Studio에서 자동으로 사용할 수 있습니다.

기존에 리소스 R.id 처럼 글꼴을 인식할 수 있습니다.

@font/myfont, or R.font.myfont.

font를 리소스로 추가하려면 Android Studio에서 다음 단계를 수행하십시오.

1. res 폴더를 마우스 오른쪽 버튼으로 클릭하고 새로 만들기> Android 리소스 디렉토리로 이동하십시오. New Resource Directory 창이 나타납니다.

2. 리소스 종류 목록에서 font을 선택한 다음 확인을 누릅니다.

참고: font파일을 넣을 디렉토리의 이름은 무조건 font여야합니다.


font 디렉토리를 만든다.


3. font 디렉토리에 font파일 추가 합니다.

아래 그림처럼 font 디렉토리에 font파일을 넣어 두면 R.font.dancing_scriptR.font.lobster 해당이름으로 font를 불러올 수 있습니다.



4. font파일을 두번 클릭하면 편집기에서 해당 파일의 font를 미리볼 수 있습니다.


XML 레이아웃에서 font를 사용

TextView 객체나 style에서 font를 쉽게 사용할 수 있습니다.

TextView 객체나 style에서 font를 연결하려면 fontFamily 특성을 사용하면 됩니다.

- TextView에 font 추가

<TextView
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:fontFamily="@font/lobster"/>

- Style에 font 추가

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
   
<item name="android:fontFamily">@font/lobster</item>
</style>

- 코드에서 font 추가

Typeface typeface = getResources().getFont(R.font.myfont);
textView
.setTypeface(typeface);


더욱 자세한 사항은 해당페이지에서 확인 하세요.

https://developer.android.com/preview/features/working-with-fonts.html?hl=ko#retrieving-system-fonts

반응형
반응형


public abstract class BaseActivity extends AppCompatActivity {

protected ProgressDialog mProgressDialog = null;

protected abstract Context getContext();

/**
* 프로그래스를 보여준다.
*/
public void showProgressDialog() {
if (mProgressDialog == null) {
if (Build.VERSION_CODES.KITKAT < Build.VERSION.SDK_INT) {

//             R.style.ProgressDialogStyle은 커스텀으로 정의한 스타일임
mProgressDialog = new ProgressDialog(getNowContext(), R.style.ProgressDialogStyle);

} else {
mProgressDialog = new ProgressDialog(getNowContext());
}
mProgressDialog.setMessage(getString(R.string.progress_message));
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
}
mProgressDialog.show();
}

/**
* 프로그래스를 숨긴다.
*/
public void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}

}


R.style.ProgressDialogStyle

<style name="ProgressDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:layout_centerVertical">true</item>
<item name="android:layout_centerHorizontal">true</item>
<item name="colorAccent">@color/colorPrimary</item>
</style>


사용 할 때

private class DownloadTask extends AsyncTask{


@Override
protected void onPreExecute() {
showProgressDialog(); // 작업 시작


//작업 준비 코드 작성
super.onPreExecute();
}


@Override
protected Object doInBackground(Object[] params) {
//작업 중
return null;
}

@Override
protected void onPostExecute(Object o) {
//작업 끝 코드 작성

hideProgressDialog(); // 작업 끝
super.onPostExecute(o);
}
}

 이런 느낌으로 사용하시면 됩니다.

반응형
반응형

많은 앱들이 카카오톡 처럼 탭 뷰페이저 형식을 사용합니다.



그래서 간단히 TabLayout + ViewPager + fragment 형식의 앱을 만들어서 공유드립니다.


다음과 같이 만들었는데요 


1. 라이브러리 셋팅


compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support:support-v4:25.2.0'
compile 'com.android.support:recyclerview-v7:25.2.0'
compile 'com.android.support:design:25.2.0'


- AppCompatActivity클래스는 appcompatV7 라이브러리에 포함되어 있습니다.

- ViewPager클래스는 supportV4 라이브러리에 포함되어 있습니다.

- TabLayout은 design 라이브러리에 포함되어 있습니다.

2. 소스코드

MainActivity.java

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.adapter.MainTabPagerAdapter;
import pe.sk.com.myapplication.data.DummyContent;
import pe.sk.com.myapplication.listener.OnListFragmentInteractionListener;

public class MainActivity extends AppCompatActivity implements OnListFragmentInteractionListener {
private TabLayout mTabLayout = null; // 탭 레이아웃
private ViewPager mViewPager = null; // 뷰 페이저
private MainTabPagerAdapter mPagerAdapter = null; // 탭 어댑터

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabLayout = (TabLayout) findViewById(R.id.main_tab);
mViewPager = (ViewPager) findViewById(R.id.main_viewpager);
mTabLayout.setupWithViewPager(mViewPager);

mPagerAdapter = new MainTabPagerAdapter(getSupportFragmentManager(), this);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {

}

@Override
public void onTabReselected(TabLayout.Tab tab) {

}
});
}

@Override
public void onListFragmentInteraction(DummyContent.DummyItem item) {
Toast.makeText(this,item.content,Toast.LENGTH_SHORT).show();
}
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.TabLayout
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="@+id/main_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#ff880033"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="#bbdefa"
app:tabSelectedTextColor="#ffffff"
app:tabTextColor="#88ffffff"
/>


<android.support.v4.view.ViewPager
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_tab"
/>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>

MainTabPagerAdapter.java


import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.fragment.FirstFragment;
import pe.sk.com.myapplication.fragment.TwoFragment;

/**
* Created by P092613 on 2017-03-09.
*/

public class MainTabPagerAdapter extends FragmentStatePagerAdapter {
private final static int TAB_COUNT = 2;     // 탭의 개수


private Context mContext;
private FirstFragment mFirstFragment = null;
private TwoFragment mTwoFragment = null;

private int[] mTabTitle = {R.string.first, R.string.two};

public MainTabPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.mContext = context;
}

@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
mFirstFragment = FirstFragment.newInstance(1);
return mFirstFragment;
default:
mTwoFragment = TwoFragment.newInstance(1);
return mTwoFragment;
}
}

@Override
public CharSequence getPageTitle(int position) {
return mContext.getString(mTabTitle[position]);
}

@Override
public int getCount() {
return TAB_COUNT;
}
}


FirstFragment.java 와 TwoFragment.java 코드는 동일함

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.adapter.FirstRecyclerViewAdapter;
import pe.sk.com.myapplication.data.DummyContent;
import pe.sk.com.myapplication.listener.OnListFragmentInteractionListener;

/**
* A fragment representing a list of Items.
* <p/>
* Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener}
* interface.
*/
public class FirstFragment extends Fragment {

// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
// TODO: Customize parameters
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;

/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public FirstFragment() {
}

// TODO: Customize parameter initialization
@SuppressWarnings("unused")
public static FirstFragment newInstance(int columnCount) {
FirstFragment fragment = new FirstFragment();
Bundle args = new Bundle();
args.putInt(ARG_COLUMN_COUNT, columnCount);
fragment.setArguments(args);
return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (getArguments() != null) {
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first_list, container, false);

// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
recyclerView.setAdapter(new FirstRecyclerViewAdapter(DummyContent.ITEMS, mListener));
}
return view;
}


@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}

@Override
public void onDetach() {
super.onDetach();
mListener = null;
}


}


FirstRecyclerViewAdapter.java 와 TwoRecyclerViewAdapter.java 코드는 동일함


import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.data.DummyContent.DummyItem;
import pe.sk.com.myapplication.listener.OnListFragmentInteractionListener;

/**
* {@link RecyclerView.Adapter} that can display a {@link DummyItem} and makes a call to the
* specified {@link OnListFragmentInteractionListener}.
* TODO: Replace the implementation with code for your data type.
*/
public class FirstRecyclerViewAdapter extends RecyclerView.Adapter<FirstRecyclerViewAdapter.ViewHolder> {

private final List<DummyItem> mValues;
private final OnListFragmentInteractionListener mListener;

public FirstRecyclerViewAdapter(List<DummyItem> items, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_first, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).content);

holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
}

@Override
public int getItemCount() {
return mValues.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public DummyItem mItem;

public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}

@Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}


fragment_first_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:name="pe.sk.com.myapplication.fragment.FirstItemFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context="pe.sk.com.myapplication.fragment.FirstFragment"
tools:listitem="@layout/fragment_first"/>


fragment_first.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"/>

<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"/>
</LinearLayout>


반응형
반응형

간혹 안드로이드 스튜디오를 실행해보면 다음과 같은 오류를 만날 수 있습니다.

Error:Unable to start the daemon process.

This problem might be caused by incorrect configuration of the daemon.

For example, an unrecognized jvm option is used.

Please refer to the user guide chapter on the daemon at https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html

Please read the following process output to find out more:

-----------------------

Error occurred during initialization of VM

Could not reserve enough space for 1572864KB object heap



이럴 경우 당황하지 말고 

gradle.properties 파일로 들어가서 Xmx1536m -> Xmx512m 으로 변경해준다.

저장 후 상단 오른쪽에 Try again을 눌러주면 끝

반응형
반응형

개발을 하다보면 이러한 오류를 만날 수 있습니다.

이럴때는 당황하지 말고

Poject의 build.gradle에 compile 'com.android.support:design:25.2.0' lib를 추가하시면 해결 됩니다.





반응형
반응형

뷰페이저를 사용중에 특정 페이지만 툴바메뉴가 보였으면 좋겠다고 하는 미치광이들이 아주 간혹 있습니다.


이런 미치광이들을 상대하는 개발자들을 위해 공유드립니다


                                        


1번1번  2번





우선 findViewById메서드로 Toolbar객체 DrawerLayout객체를 만들어 줍니다.

/**
* 1번 좌측메뉴, 좌측슬라이드 노출되도록 설정
*/
protected void setToolbarVisibleLeftMenu() {
if (mToolbar != null && mDrawerLayout != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(true);
// 상단 툴바를 이용하여 좌측 메뉴 열기 / 닫기 설정
mActionBarDrawerToggle = new ActionBarDrawerToggle((Activity) getNowContext(), mDrawerLayout, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
// Drawer Toggle Object Made
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle); // Drawer Listener set to the Drawer toggle
mActionBarDrawerToggle.syncState();
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
}

/**
* 2번 좌측메뉴, 좌측슬라이드 노출되지않도록 설정
*/
protected void setToolbarGoneLeftMenu() {
if (mToolbar != null && mDrawerLayout != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
}


반응형
반응형

안드로이드는 다음과 같이 휠을 날짜나 시간, 숫자만 제공해줍니다.


  





글자(String)가 쓰여진 휠뷰는 안드로이드 자체적으로 제공해 주지 않습니다. 그래서 lib를 써야합니다.

많은  lib들이 있지만 그중에 가장 괜찮고 안정성 있는 lib라고 생각되어 소개합니다.



Github 주소

https://github.com/maarek/android-wheel





Demo


@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);


setContentView(R.layout.cities_layout);

String[] locationData= new String[]{"남산", "대구", "부산", "인천", "경주", "안산", "서울", "광주", "충주", "강원"};



WheelView country = (WheelView) findViewById(R.id.country);


  // Cyclic 여부 true일경우 위아래로 값이 생겨서 무제한 스크롤 가능(직접 해보시길 설명을 못하겟음) 

country.setCyclic(false);

country.setCurrentItem(0); // position 설정 혹은 index 설정

country.setVisibleItems(3); // 보여줄 item의 개수(테스트 결과 이 함수는 적용되지 않는다.)

ArrayWheelAdapter<String> adapter = new ArrayWheelAdapter<String>(this, locationData);

adapter.setTextSize(30); // 글씨 크기

country.setViewAdapter(adapter); //어댑터를 설정한다.

country.addScrollingListener( new OnWheelScrollListener() {

@Override

public void onScrollingStarted(WheelView wheel) {

// 스크롤 시작

scrolling = true;

}

@Override

public void onScrollingFinished(WheelView wheel) {

// 스크롤 끝

scrolling = false;

}

});

}




이슈사항


- 아래 그림의 휠 두개는 서로 연동 됩니다. 예를 들어 지역 휠을 컨트롤 하여 "남산"을 선택 시 층은 11층까지 보이도록 갱신됩니다.

 앞에 설명과 같이 지역 휠을 컨트롤 하여 "부산"을 선택 시 1층만 보이도록 갱신됩니다.

ex)

남산 - 1,2,3,4,5,6,7,8,9,10,11층

대구 - 1,2,3층

부산 - 1층

인천 - 1,2,3,4,5,6층

   .

   .

   .



-휠을 두개 쓸 경우 층 휠을 맨 밑으로 내리고 바로 지역 휠을 스크롤 할 경우 층 휠의 층수가 보이지 않는 이슈가 있습니다.




해결방법

-완벽한 해결 방법은 아니지만 onScrollingStarted콜백이 호출 될때마다 층휠을 setCurrentItem(0);으로 초기화 해주면 해당이슈사항은 해결 됩니다. 

반응형
반응형

안드로이드에서는 키보드가 올라가고 내려갈때 콜백 이벤트 필요한 순간이 있을때


이 코드를 사용하시면 됩니다.


우선 구글링으로 찾은 이곳에서 SoftKeyboard 클래스의 용도를 확인합니다.


https://felhr85.net/2014/05/04/catch-soft-keyboard-showhidden-events-in-android/


안에 들어가 보시면 It is available here. 이라고 쓰인 곳을 누르면 SoftKeyboard.java를 다운받을 수 있도록 안내해 줍니다.


SoftKeyboard.java를 다운받고 프로젝트에 넣고 아래 소스를 넣어 줍니다.


TestAct.java


package com.example.testline;


import android.app.Activity;

import android.app.Service;

import android.os.Bundle;

import android.os.Handler;

import android.os.Looper;

import android.view.inputmethod.InputMethodManager;

import android.widget.LinearLayout;


public class TestAct extends Activity {

SoftKeyboard mSoftKeyboard;

LinearLayout mLlEdit;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


mLlEdit = (LinearLayout) findViewById(R.id.ll_edit);


InputMethodManager controlManager = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);

mSoftKeyboard = new SoftKeyboard(mLlEdit, controlManager);

mSoftKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged() {

@Override

public void onSoftKeyboardHide() {

new Handler(Looper.getMainLooper())

.post(new Runnable() {

@Override

public void run() {

// 키보드 내려왔을때

}

});

}


@Override

public void onSoftKeyboardShow() {

new Handler(Looper.getMainLooper())

.post(new Runnable() {

@Override

public void run() {

// 키보드 올라왔을때

}

});

}

});


}


@Override

public void onDestroy() {

super.onDestroy();

mSoftKeyboard.unRegisterSoftKeyboardCallback();

}


}



activity_main.xml 파일


     <LinearLayout

        android:id="@+id/ll_edit"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:focusable="true"

        android:focusableInTouchMode="true"

        android:orientation="horizontal" >

<TextView

          android:layout_width="80dp"

          android:layout_height="41.33dp"

          android:gravity="center_vertical"

          android:text="@string/visit_floor"

          android:textColor="@android:color/black"

          android:textSize="16.67sp" />


      <EditText

          android:id="@+id/EditText"

          android:layout_width="fill_parent"

          android:layout_height="41.33dp"

          android:layout_gravity="center"

          android:gravity="center"

          android:inputType="textAutoComplete"

          android:textSize="16.67sp" />

  </LinearLayout>


SoftKeyboard.java


반응형

+ Recent posts