├── UtilSetInstrumentationTest
├── .gitignore
├── lint.xml
├── ic_launcher-web.png
├── libs
│ ├── android-support-v4.jar
│ └── robotium-solo-4.3.jar
├── lib
│ └── utilset-0.0.1-SNAPSHOT.jar
├── repo
│ └── utilset-0.0.1-SNAPSHOT.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── description.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ └── values-v14
│ │ └── styles.xml
├── .checkstyle
├── project.properties
├── AndroidManifest.xml
├── proguard-project.txt
├── .project
├── src
│ └── com
│ │ └── navercorp
│ │ └── utilsettest
│ │ ├── test
│ │ ├── KeyboardUtilsTestCase.java
│ │ ├── NetworkListenerTestCase.java
│ │ ├── CipherUtilsTestCase.java
│ │ ├── VolumeUpDownTestCase.java
│ │ ├── ScreenUtilsTestCase.java
│ │ └── StringUtilsTestCase.java
│ │ └── introduction
│ │ └── Introduction.java
├── .classpath
└── pom.xml
├── UtilSetSampleApp
├── .gitignore
├── lint.xml
├── ic_launcher-web.png
├── libs
│ ├── android-support-v4.jar
│ └── robotium-solo-4.3.jar
├── lib
│ └── utilset-0.0.1-SNAPSHOT.jar
├── repo
│ └── utilset-0.0.1-SNAPSHOT.jar
├── res
│ ├── drawable-hdpi
│ │ ├── close_button.png
│ │ ├── ic_launcher.png
│ │ ├── progress_bg_holo_dark.9.png
│ │ ├── progress_primary_holo_dark.9.png
│ │ ├── progress_secondary_holo_dark.9.png
│ │ ├── rounded_background.xml
│ │ └── progress_horizontal_holo_dark.xml
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── menu
│ │ └── main.xml
│ ├── layout
│ │ ├── activity_activityutils.xml
│ │ ├── activity_diskutils.xml
│ │ ├── activity_networkutils.xml
│ │ ├── activity_systemutils.xml
│ │ ├── activity_deviceutils.xml
│ │ ├── fragment_reset_screen_on.xml
│ │ ├── fragment_keep_screen_on.xml
│ │ ├── activity_keyboardutils.xml
│ │ ├── activity_network_listener.xml
│ │ ├── acitivty_volumeutils.xml
│ │ ├── dialog_introduction.xml
│ │ ├── activity_cipher.xml
│ │ ├── activity_stringutils.xml
│ │ └── activity_main.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ └── values-v14
│ │ └── styles.xml
├── src
│ └── com
│ │ └── navercorp
│ │ └── utilsettest
│ │ ├── ui
│ │ ├── ActivityUtilsConstants.java
│ │ ├── ActivityUtilsClearScreenOnFragment.java
│ │ ├── ActivityUtilsPagerAdapter.java
│ │ ├── ActivityUtilsTestActivity.java
│ │ └── ActivityUtilsKeepScreenOnFragment.java
│ │ ├── dialog
│ │ ├── IntroductionDialogFactory.java
│ │ ├── IntroductionDialogController.java
│ │ └── IntroductionDialogFragment.java
│ │ ├── ButtonColor.java
│ │ ├── ButtonColorList.java
│ │ ├── string
│ │ └── StringUtilsTestActivity.java
│ │ ├── system
│ │ └── SystemUtilsTestActivity.java
│ │ ├── audio
│ │ └── VolumeUtilsTestActivity.java
│ │ ├── input
│ │ └── KeyboardUtilsTestActivity.java
│ │ ├── device
│ │ └── DeviceUtilsTestActivity.java
│ │ ├── storage
│ │ └── DiskUtilsTestAcitivity.java
│ │ ├── cipher
│ │ └── CipherTestActivity.java
│ │ ├── network
│ │ ├── NetworkMonitorTestActivity.java
│ │ └── NetworkListenerTestActivity.java
│ │ └── MainActivity.java
├── .checkstyle
├── project.properties
├── proguard-project.txt
├── .project
├── .classpath
├── pom.xml
└── AndroidManifest.xml
├── .gitignore
├── UtilSet
├── .gitignore
├── src
│ └── com
│ │ └── navercorp
│ │ └── utilset
│ │ ├── cipher
│ │ ├── CipherMode.java
│ │ ├── CipherObject.java
│ │ ├── CipherObjectFactory.java
│ │ ├── CipherUtils.java
│ │ └── AesCipher.java
│ │ ├── device
│ │ ├── DeviceType.java
│ │ ├── PhoneNumberUtils.java
│ │ ├── LauncherInfo.java
│ │ ├── LauncherTypeDetector.java
│ │ ├── LauncherType.java
│ │ ├── DeviceTypeDetector.java
│ │ └── DeviceUtils.java
│ │ ├── string
│ │ ├── CompressUtils.java
│ │ └── StringCompressor.java
│ │ ├── ui
│ │ ├── ScreenUtils.java
│ │ ├── PixelUtils.java
│ │ └── ActivityUtils.java
│ │ ├── system
│ │ ├── SystemUtils.java
│ │ ├── ProcessorUtils.java
│ │ └── RootChecker.java
│ │ ├── input
│ │ ├── SoftwareKeyDetector.java
│ │ └── KeyboardUtils.java
│ │ ├── storage
│ │ └── DiskUtils.java
│ │ └── audio
│ │ └── VolumeUtils.java
├── .checkstyle
├── project.properties
├── test
│ └── com
│ │ └── navercorp
│ │ └── utilset
│ │ ├── cipher
│ │ ├── CipherObjectFactoryTest.java
│ │ └── CipherUtilsTest.java
│ │ ├── system
│ │ └── SystemUtilsTest.java
│ │ ├── ui
│ │ ├── PixelUtilsTest.java
│ │ ├── ScreenUtilsTest.java
│ │ └── ActivityUtilsTest.java
│ │ ├── storage
│ │ └── DiskUtilsTest.java
│ │ ├── string
│ │ └── CompressUtilsTest.java
│ │ └── audio
│ │ └── VolumeUtilsTest.java
├── pom.xml
└── LICENSE
├── repo
└── utilset-0.0.1-SNAPSHOT.jar
├── .settings
└── org.eclipse.m2e.core.prefs
├── .project
├── README.md
└── LICENSE
/UtilSetInstrumentationTest/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/UtilSetSampleApp/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /target
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | gen
3 | target
4 | .settings
5 | .claspath
6 | .project
7 |
--------------------------------------------------------------------------------
/UtilSetSampleApp/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | * Currently, default cipher algorithm, AES, is solely provided
6 | *
7 | * @author jaemin.woo
8 | */
9 | public enum CipherMode {
10 | AES,
11 | }
--------------------------------------------------------------------------------
/UtilSet/.checkstyle:
--------------------------------------------------------------------------------
1 |
2 |
This method is not guaranteed to cover all the root methods.
20 | * It takes simple approach;
21 | * It tries to finds 'su' command and then executes.
22 | * If 'su' command is not found or unable to execute then an exception will be thrown.
23 | * This indicates that device is rooted.
24 | * Because this is well known way to check root, Root tools today may not be detected by this method.
25 | * For more detailed implementation, refer to 'RootTools' library.
26 | *
27 | * @return true if the device is rooted; false otherwise
28 | * @throws RuntimeException if root check fails
29 | */
30 | public static boolean isRooted() {
31 | return rootChecker.checkRootingDevice();
32 | }
33 |
34 | /**
35 | * Returns the number of cores of device.
53 | *
54 | * Requires READ_PHONE_STATE Permission must be set to use this function
55 | * @param context
56 | * Context to derive device information
57 | * @return true if user device has SMS capability; false otherwise
58 | */
59 | public static boolean hasSmsCapability(Context context) {
60 | return phoneNumberUtils.isAbleToReceiveSms(context);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/UtilSetSampleApp/pom.xml:
--------------------------------------------------------------------------------
1 |
36 | *
37 | * This method always returns path of external storage even if it does not exist.
49 | *
50 | * This method always returns path of external storage even if it does not exist.
63 | *
64 | * This method always returns path of external storage even if it does not exist.
36 | * Requires GET_TASK permission
37 | * @param context Context to get base activity information
38 | * @return String containing base package name
39 | */
40 | public static String getBaseActivityPackageName(Context context) {
41 | ComponentName activity = getBaseActivity(context);
42 | if (activity == null) {
43 | return null;
44 | }
45 | return activity.getPackageName();
46 | }
47 |
48 | /**
49 | * Returns Class name of base activity
50 | * @param context Context to provide activity information
51 | * @return String representing class name of base activity
52 | */
53 | public static String getBaseActivityClassName(Context context) {
54 | ComponentName activity = getBaseActivity(context);
55 | if (activity == null) {
56 | return null;
57 | }
58 | return activity.getClassName();
59 | }
60 |
61 | /**
62 | * Returns Package name of top activity
63 | * @param context Context to provide activity information
64 | * @return String representing package name of top activity
65 | */
66 | public static String getTopActivityPackageName(Context context) {
67 | ComponentName activity = getTopActivity(context);
68 | if (activity == null) {
69 | return null;
70 | }
71 | return activity.getPackageName();
72 | }
73 |
74 | /**
75 | * Returns Class name of top activity
76 | * @param context Context to provide activity information
77 | * @return String representing class name of top activity
78 | */
79 | public static String getTopActivityClassName(Context context) {
80 | ComponentName activity = getTopActivity(context);
81 | if (activity == null) {
82 | return null;
83 | }
84 | return activity.getClassName();
85 | }
86 |
87 |
88 |
89 | /**
90 | * Determines if this application is top activity
91 | * @param context Context to be examined
92 | * @return true if this application is a top activity; false otherwise
93 | */
94 | public static boolean isTopApplication(Context context) {
95 | ComponentName activity = getTopActivity(context);
96 | if (activity == null) {
97 | return false;
98 | }
99 | return activity.getPackageName().equals(context.getApplicationInfo().packageName);
100 | }
101 |
102 |
103 | /**
104 | * Checks if this application is foreground
105 | *
106 | * @param context Context to be examined
107 | * @return true if this application is running on the top; false otherwise
108 | */
109 | public static boolean isContextForeground(Context context) {
110 |
111 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
112 | List
22 | * Look at these examples.
36 | * Until JELLY_BEAN_MR1, It is possible for processors to be off-line for power saving purpose and those off-line CPUs may not be counted.
37 | * Use this method if Runtime.availableProcessors() seems not to return exact core numbers.
38 | *
39 | * @return the number of cores
40 | */
41 | public static int getProcessorNumbers() {
42 | return ProcessorUtils.getNumCores();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/UtilSetSampleApp/src/com/navercorp/utilsettest/string/StringUtilsTestActivity.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilsettest.string;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentActivity;
5 | import android.view.Menu;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.TextView;
11 |
12 | import com.navercorp.utilset.string.CompressUtils;
13 | import com.navercorp.utilsettest.R;
14 |
15 | public class StringUtilsTestActivity extends FragmentActivity {
16 | EditText uncompressedText;
17 | TextView compressedText;
18 | Button submit;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_stringutils);
24 |
25 | uncompressedText = (EditText) findViewById(R.id.uncompressedTextStringUtils);
26 | compressedText = (TextView) findViewById(R.id.compressedTextStringUtils);
27 | submit = (Button) findViewById(R.id.submitButtonStringUtils);
28 | submit.setOnClickListener(onClickListener);
29 | }
30 |
31 | OnClickListener onClickListener = new OnClickListener() {
32 | @Override
33 | public void onClick(View v) {
34 | String s = uncompressedText.getText().toString();
35 | String compressed = CompressUtils.compressString(s);
36 | compressedText.setText(compressed);
37 | }
38 | };
39 |
40 | @Override
41 | public boolean onCreateOptionsMenu(Menu menu) {
42 | // Inflate the menu; this adds items to the action bar if it is present.
43 | getMenuInflater().inflate(R.menu.main, menu);
44 | return true;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/UtilSet/test/com/navercorp/utilset/cipher/CipherUtilsTest.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilset.cipher;
2 |
3 | import static org.hamcrest.Matchers.*;
4 | import static org.junit.Assert.*;
5 |
6 | import org.junit.Before;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 | import org.robolectric.RobolectricTestRunner;
10 | import org.robolectric.annotation.Config;
11 | import org.robolectric.shadows.ShadowLog;
12 |
13 | import com.navercorp.utilset.cipher.CipherMode;
14 | import com.navercorp.utilset.cipher.CipherUtils;
15 |
16 | /**
17 | * @author jaemin.woo
18 | *
19 | */
20 | @RunWith(RobolectricTestRunner.class)
21 | @Config(manifest=Config.NONE)
22 | public class CipherUtilsTest {
23 | private static String SEED = "SEED";
24 | private static String PLAIN_TEXT = "PLAIN_TEXT";
25 |
26 | @Before
27 | public void setUp() {
28 | ShadowLog.stream = System.out;
29 | }
30 |
31 | private String encrypt(String seed, String plainText) {
32 | CipherUtils cipherUtils = new CipherUtils(CipherMode.AES);
33 | return cipherUtils.encrypt(seed, plainText);
34 | }
35 |
36 | @Test
37 | public void shouldEncryptPlainTextWithAESCipher() {
38 | String encrypted = encrypt(SEED, PLAIN_TEXT);
39 | assertThat(encrypted, is(not(PLAIN_TEXT)));
40 | }
41 |
42 | private String decrypt(String seed, String cipherText) {
43 | CipherUtils cipherUtils = new CipherUtils(CipherMode.AES);
44 | return cipherUtils.decrypt(seed, cipherText);
45 | }
46 |
47 | @Test
48 | public void shouldDecryptCipherTextWithAESCipher() {
49 | String encrypted = encrypt(SEED, PLAIN_TEXT);
50 | String decrypted = decrypt(SEED, encrypted);
51 | assertEquals(PLAIN_TEXT, decrypted);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/UtilSet/src/com/navercorp/utilset/system/ProcessorUtils.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilset.system;
2 |
3 | import java.io.File;
4 | import java.io.FileFilter;
5 | import java.util.regex.Pattern;
6 |
7 | import android.util.Log;
8 |
9 | class ProcessorUtils {
10 | /**
11 | http://stackoverflow.com/questions/7962155/how-can-you-detect-a-dual-core-cpu-on-an-android-device-from-code
12 | * Gets the number of cores available in this device, across all processors.
13 | * Requires: Ability to peruse the file system at "/sys/devices/system/cpu"
14 | * @return The number of cores, or Runtime.getRuntime().availableProcessors() if failed to get result
15 | */
16 | public static int getNumCores() {
17 | //Private Class to display only CPU devices in the directory listing
18 | class CpuFilter implements FileFilter {
19 |
20 | @Override
21 | public boolean accept(File pathname) {
22 | //Check if filename is "cpu", followed by a single digit number
23 | if(Pattern.matches("cpu[0-9]", pathname.getName())) {
24 | return true;
25 | }
26 |
27 | return false;
28 | }
29 | }
30 |
31 | try {
32 | //Get directory containing CPU info
33 | File dir = new File("/sys/devices/system/cpu/");
34 |
35 | //Filter to only list the devices we care about
36 | File[] files = dir.listFiles(new CpuFilter());
37 |
38 | if (files == null)
39 | return Runtime.getRuntime().availableProcessors();
40 |
41 | //Return the number of cores (virtual CPU devices)
42 | return files.length;
43 | } catch(Exception e) {
44 | // The number of cores can vary with JVM status
45 | return Runtime.getRuntime().availableProcessors();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/UtilSet/src/com/navercorp/utilset/ui/PixelUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DisplayUtil.java
3 | *
4 | * Copyright 2011 NHN Corp. All rights Reserved.
5 | * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6 | */
7 | package com.navercorp.utilset.ui;
8 |
9 | import android.content.Context;
10 |
11 | /**
12 | *
13 | * @author jaemin.woo
14 | *
15 | */
16 | public class PixelUtils {
17 | private static final float ROUND_FACTOR = 0.5f;
18 | /**
19 | * Converts Pixel to DP
20 | * @param pixel Pixel
21 | * @return DP
22 | * @see http://developer.android.com/guide/practices/screens_support.html#dips-pels
23 | */
24 | public static int getDpFromPixel(Context context, int pixel) {
25 | float scale = context.getResources().getDisplayMetrics().density; // get display density
26 |
27 | return (int)(pixel / scale);
28 | }
29 |
30 | /**
31 | * Converts DP to Pixel
32 | *
33 | * @param dp DP
34 | * @return Pixel
35 | * @see http://developer.android.com/guide/practices/screens_support.html#dips-pels
36 | */
37 | public static int getPixelFromDp(Context context, int dp) {
38 | // Get the screen's density scale
39 | float scale = context.getResources().getDisplayMetrics().density;
40 |
41 | // Convert the dps to pixels, based on density scale
42 | // because dp*scale is cast as an integer value, this will cause the result to be truncated.
43 | // Therefore, Adding ROUND_FACTOR helps the result to have properly rounded integer value.
44 | return (int)(dp * scale + ROUND_FACTOR);
45 | }
46 | }
--------------------------------------------------------------------------------
/UtilSetInstrumentationTest/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
21 | *
22 | * According to the Google API guide,
23 | * devices whose screen size is less than 7 inches will be classified as a handset.
24 | * For example, Huge looking mobile phones like Samsung galaxy Note III will be sorted as a handset by this rule.
25 | * Among the rest, devices with 7 inch screen and LDPI will be classified as a handset too.
26 | * All other devices with 7 or larger screen will be classified as a tablet.
27 | *
28 | * @param context
29 | * Context derived from Activity. ApplicationContext can not be
30 | * used to take advantage of this function.
31 | *
32 | * @return DeviceType.Tablet if the screen size is equal to or larger than
33 | * XLarge, which is defined as display size from 7 to 10 inches;
34 | * DeviceType.Handset if the screen size is smaller than XLarge
35 | */
36 | public static DeviceType getDeviceType(Context context) {
37 | return deviceTypeDetector.getDeviceType(context);
38 | }
39 |
40 | /**
41 | * Returns launcher type.
42 | *
43 | * @param context
44 | * Context to provide package information
45 | * @return LauncherType
46 | */
47 | public static LauncherType getLauncherType(Context context) {
48 | return LauncherTypeDetector.getType(context);
49 | }
50 |
51 | /**
52 | * Determines if user device has capability of SMS.
10 | * External disk do not necessarily mean that it is a SD Card.
11 | *
12 | * Any large size of space can be external disk.
13 | * As such, do not make assumptions that you are working on SDCard.
14 | *
15 | * getMicroSDPath method that finds MicroSDCard path if it exists has been removed since it depends on /system/etc/vold.fstab file.
16 | * Because that file was removed as of JELLY_BEAN_MR2, this function could not work as solid as it should do.
17 | * For that reason, this method is excluded.
18 | *
19 | * @author jaemin.woo
20 | */
21 | public final class DiskUtils {
22 | private static final String DATA_FOLDER = "/Android/data";
23 | protected static final String TEMPORARY_FOLDER = "/temp";
24 | protected static final String CACHE_FOLDER = "/cache";
25 |
26 | /**
27 | * Checks if External storage is mounted
28 | * @return true if mounted; false otherwise
29 | */
30 | public static boolean isExternalStorageMounted() {
31 | return Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
32 | }
33 |
34 | /**
35 | * Returns directory name to save cache data in the external storage
38 | * As such, make sure to call isExternalStorageMounted method as state-testing method and then call this function only if state-testing method returns true.
39 | *
40 | * @param context Context to get external storage information
41 | * @return String containing cache directory name
42 | */
43 | public static String getExternalDirPath(Context context) {
44 | return Environment.getExternalStorageDirectory().getAbsolutePath() + DATA_FOLDER + File.separator + context.getPackageName() + CACHE_FOLDER;
45 | }
46 |
47 | /**
48 | * Returns directory name to save temporary files in the external storage for temporary
51 | * As such, make sure to call isExternalStorageMounted method as state-testing method and then call this function only if state-testing method returns true.
52 | *
53 | * @param context Context to get external storage information
54 | * @return String containing temporary directory name
55 | */
56 | public static String getExternalTemporaryDirPath(Context context) {
57 | return Environment.getExternalStorageDirectory().getAbsolutePath() + DATA_FOLDER + File.separator + context.getPackageName() + TEMPORARY_FOLDER;
58 | }
59 |
60 |
61 | /**
62 | * Returns root directory of the external storage.
65 | * As such, make sure to call isExternalStorageMounted method as state-testing method and then call this function only if state-testing method returns true.
66 | *
67 | * @param context Context to get external storage information
68 | * @return String containing external root directory name
69 | */
70 | public static String getExternalContextRootDir(Context context) {
71 | return Environment.getExternalStorageDirectory().getAbsolutePath() + DATA_FOLDER + File.separator + context.getPackageName();
72 | }
73 | }
--------------------------------------------------------------------------------
/UtilSetSampleApp/src/com/navercorp/utilsettest/dialog/IntroductionDialogFragment.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilsettest.dialog;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.os.Bundle;
6 | import android.os.CountDownTimer;
7 | import android.support.v4.app.DialogFragment;
8 | import android.util.DisplayMetrics;
9 | import android.view.View;
10 | import android.view.View.OnClickListener;
11 | import android.view.ViewGroup.LayoutParams;
12 | import android.widget.Button;
13 | import android.widget.ProgressBar;
14 | import android.widget.TextView;
15 |
16 | import com.navercorp.utilsettest.R;
17 |
18 | public class IntroductionDialogFragment extends DialogFragment {
19 | private static final int DEFAULT_TIMER_UPDATE_INTERVAL = 10;
20 | private String title;
21 | private String content;
22 | private int time;
23 | private Dialog dialog;
24 | private CountDownTimer timer;
25 | private ProgressBar progressBar;
26 |
27 | public IntroductionDialogFragment(String title, String content, int time) {
28 | this.title = title;
29 | this.content = content;
30 | this.time = time;
31 | }
32 |
33 | @Override
34 | public Dialog onCreateDialog(Bundle savedInstanceState) {
35 | Activity activity = getActivity();
36 |
37 | dialog = new Dialog(activity, android.R.style.Theme_Panel);
38 |
39 | dialog.setContentView(R.layout.dialog_introduction);
40 |
41 | // dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
42 | // dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
43 |
44 | TextView titleTextView = (TextView) dialog.findViewById(R.id.titleForDescriptionDialog);
45 | TextView contentTextView = (TextView) dialog.findViewById(R.id.contentForDescriptionDialog);
46 |
47 | titleTextView.setText(title);
48 | contentTextView.setText(content);
49 |
50 | progressBar = (ProgressBar) dialog.findViewById(R.id.progressBarForDescriptionDialog);
51 | progressBar.setMax(time);
52 |
53 | this.timer = new CountDownTimer(time, DEFAULT_TIMER_UPDATE_INTERVAL) {
54 | @Override
55 | public void onTick(long millisUntilFinished) {
56 |
57 | // Not sure if this is called when millisUntilFinished is zero.
58 | // This is to avoid so called "divide by zero" error, just in case.
59 | if (millisUntilFinished == 0)
60 | return;
61 |
62 | progressBar.setProgress(time - (int) millisUntilFinished);
63 | }
64 |
65 | @Override
66 | public void onFinish() {
67 | dismiss();
68 | }
69 | };
70 |
71 | timer.start();
72 |
73 | DisplayMetrics displaymetrics = new DisplayMetrics();
74 | activity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
75 | dialog.getWindow().setLayout(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
76 |
77 |
78 | Button declineButton = (Button) dialog.findViewById(R.id.closeButtonDialog);
79 | // if decline button is clicked, close the custom dialog
80 | declineButton.setOnClickListener(new OnClickListener() {
81 | @Override
82 | public void onClick(View v) {
83 | // Close dialog
84 | timer.cancel();
85 | dismiss();
86 | }
87 | });
88 |
89 | return dialog;
90 | }
91 |
92 | public boolean isShowing() {
93 | return dialog.isShowing();
94 | }
95 |
96 | public void dismiss() {
97 | dialog.dismiss();
98 | }
99 | }
--------------------------------------------------------------------------------
/UtilSetInstrumentationTest/src/com/navercorp/utilsettest/introduction/Introduction.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilsettest.introduction;
2 |
3 | import android.support.v4.app.FragmentActivity;
4 |
5 | import com.navercorp.utilsettest.dialog.IntroductionDialogController;
6 | import com.navercorp.utilsettest.dialog.IntroductionDialogFactory;
7 |
8 | public enum Introduction {
9 | CipherUtilsTestCase_testCipher() {
10 | @Override
11 | public String getIntroduction() {
12 | return "CipherUtils provides simple AES encryption.\n" +
13 | "So this test shows the ciphertext by applying AES encryption utility function on user entered plaintext." +
14 | "Short after the encryption, you can verify the encrypted string can be restored to the exactly same string as the original one by decryption utility function.";
15 | }
16 | },
17 |
18 | VolumeUpDownTestCase_testVolumeUpAndDown() {
19 | @Override
20 | public String getIntroduction() {
21 | return "This method manipulates media volume.\n" +
22 | "Three times of volume up and then the same number of volume down will be done.";
23 | }
24 | },
25 |
26 | KeyboardUtilsTestCase_testKeyboard() {
27 | @Override
28 | public String getIntroduction() {
29 | return "This method shows a software keyboard being shown, hid, and toggled.\n" +
30 | "\n\n*** Should you not see the keyboard appear, when this being run on emulator, uncheck Hardware keyboard present option on your emulator property in AVD Manager. " +
31 | "This will make it work ***";
32 | }//
33 | },
34 |
35 | NetworkListenerTestCase_showIntroductionDialog() {
36 | @Override
37 | public String getIntroduction() {
38 | return "When network state changes, for example, from 3G/4G to WiFi or in the opposite case, INetworkStateChangedListener will be notified if registered.\n" +
39 | "This shows network state change by turning on and off the WiFi Adapter.\n" +
40 | "If USIM is not inserted or no Access Point is near, this test shows nothing more than changing WiFi state.";
41 | }
42 | },
43 |
44 | ScreenUtilsTestCase_testSetBrightness() {
45 | @Override
46 | public String getIntroduction() {
47 | return "This test makes screen the darkest and then the brightest\n";
48 | }
49 |
50 | },
51 |
52 | StringUtils_testHighCompressionRatio() {
53 | @Override
54 | public String getIntroduction() {
55 | return "This test simulates string compression util.\n" +
56 | "This is good example of how efficiently recurring characters can be compressed, " +
57 | "this is not usual case though.\n" +
58 | "Following this test, an inefficient test will be executed.\n";
59 | }
60 | },
61 |
62 | StringUtils_testLowCompressionRatio() {
63 | @Override
64 | public String getIntroduction() {
65 | return "Followed by efficient test previously done, " +
66 | "this test demonstrates how disordered characters serverely affects on compression ratio";
67 | }
68 | }
69 | ;
70 |
71 | abstract public String getIntroduction();
72 |
73 | static public void showIntroductionDialog(FragmentActivity fa, Introduction introduction, int time) {
74 | IntroductionDialogController idc = IntroductionDialogFactory.getInstance(fa, introduction.getIntroduction(), time);
75 |
76 | try {
77 | Thread.sleep(500);
78 | idc.show();
79 | Thread.sleep(500);
80 | } catch (InterruptedException e) {
81 | e.printStackTrace();
82 | }
83 | }
84 |
85 | static public void showIntroductionDialog(FragmentActivity fa, Introduction introduction) {
86 | showIntroductionDialog(fa, introduction, DEFAULT_TIME);
87 | }
88 |
89 | private static int DEFAULT_TIME = 5000;
90 | }
91 |
--------------------------------------------------------------------------------
/UtilSetSampleApp/src/com/navercorp/utilsettest/network/NetworkListenerTestActivity.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilsettest.network;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.v4.app.FragmentActivity;
6 | import android.util.Log;
7 | import android.widget.CompoundButton;
8 | import android.widget.CompoundButton.OnCheckedChangeListener;
9 | import android.widget.TextView;
10 | import android.widget.ToggleButton;
11 |
12 | import com.navercorp.utilset.network.NetworkMonitor;
13 | import com.navercorp.utilsettest.R;
14 |
15 | public class NetworkListenerTestActivity extends FragmentActivity {
16 |
17 | private TextView wifiStateTextView;
18 | private TextView networkStateTextView;
19 | // private TextView unusedTextView;
20 | private ToggleButton toggleWifiButton;
21 | private NetworkMonitor networkUtils;
22 |
23 | private NetworkMonitor.NetworkStateChangedListener networkStateChangedListener = new NetworkMonitor.NetworkStateChangedListener() {
24 | @Override
25 | public void onNetworkStateChanged() {
26 | Log.d("UtilSet", "NetworkStateChanged");
27 | // setWifiStateTextView(networkUtils.isWifiConnected());
28 | setNetworkStateTextView();
29 | }
30 | };
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_network_listener);
36 |
37 | networkUtils = NetworkMonitor.getInstance(this);
38 |
39 | wifiStateTextView = (TextView) findViewById(R.id.network_listener_test_wifi_state);
40 | networkStateTextView = (TextView) findViewById(R.id.network_listener_test_network_state);
41 | // unusedTextView = (TextView) findViewById(R.id.network_listener_test_unused);
42 |
43 | toggleWifiButton = (ToggleButton) findViewById(R.id.network_listener_test_toggle_wifi);
44 | toggleWifiButton.setOnCheckedChangeListener(onCheckedChangeListener);
45 |
46 | init();
47 | }
48 |
49 | private void init() {
50 | boolean isWifiEnabled = networkUtils.isWifiEnabled();
51 | toggleWifiButton.setChecked(isWifiEnabled);
52 |
53 | setWifiStateTextView(isWifiEnabled);
54 |
55 | // unusedTextView.setText("I'm unused");
56 | networkUtils.addWifiStateChangedListener(networkStateChangedListener);
57 | }
58 |
59 | private void setNetworkStateTextView() {
60 | networkStateTextView.setText("Network State has changed");
61 | Handler handler = new Handler();
62 | handler.postDelayed(new Runnable() {
63 | @Override
64 | public void run() {
65 | networkStateTextView.setText("");
66 | }
67 | }, 1500);
68 |
69 | }
70 |
71 | private void setWifiStateTextView(boolean isWifiEnabled) {
72 | wifiStateTextView.setText("WiFi is "
73 | + (isWifiEnabled == true ? "On" : "Off"));
74 | }
75 |
76 | @Override
77 | protected void onDestroy() {
78 | super.onDestroy();
79 | NetworkMonitor.destroy();
80 | networkUtils = null;
81 | }
82 |
83 | OnCheckedChangeListener onCheckedChangeListener = new OnCheckedChangeListener() {
84 | @Override
85 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
86 | // TODO Auto-generated method stub
87 | int id = buttonView.getId();
88 | if (id == R.id.network_listener_test_toggle_wifi) {
89 | if (isChecked) {
90 | networkUtils.setWifiEnabled(NetworkListenerTestActivity.this);
91 | Log.d("UtilSet", "WiFi is enabled");
92 |
93 | } else {
94 | networkUtils.setWifiDisabled(NetworkListenerTestActivity.this);
95 | Log.d("UtilSet", "WiFi is disabled");
96 | }
97 | }
98 | setWifiStateTextView(isChecked);
99 | }
100 | };
101 | }
102 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Utilset
2 |
3 | ### Introduction
4 | Utilset is collections of useful functions to save your valuable time.
5 | Because there are a ton of different ways to implement a method,
6 | we often spend our valuable time to search and test those ways.
7 | Some may work, but some may not work.
8 | As such, we collected, tested and refined methods so as to prevent seeking code snippet.
9 |
10 | -------
11 | ### Overview
12 | Utilset includes:
13 |
14 | * DeviceUtils
15 | + determines whether the device is mobile phone or not
16 | + determines if the phone has SMS capability
17 | + etc...
18 |
19 | * ActivityUtils
20 | + checks if a user specified package is installed
21 | + gets information of base activity package name and class name
22 |
23 | * NetworkUtils
24 | + provides listeners which notify when network state changes, , receives a call, or a connection is made
25 | + checks if WiFi is enabled and if WiFi is connected
26 | + checks if Mobile Network (3G/4G) is connected
27 | + obtains IP Address in either v4 or v6 form
28 | + etc...
29 |
30 | * DiskUtils
31 | + obtains external storage path for caching
32 | + obtains external storage path for temporary files
33 | + obtains MicroSD Card path
34 |
35 | * KeyboardUtils
36 | + shows, hides, and toggles Software keyboards
37 | + checks if a device has software menu/home/back button
38 |
39 | * CipherUtils
40 | + provides simple AES based cryptographic methods
41 |
42 | * StringUtils
43 | + provides string compression/decompression methods
44 |
45 | * SystemUtils
46 | + checks if a device is rooted
47 | + counts the number of processors(more specifically the number of cores)
48 |
49 |
50 | -------
51 | ### Download
52 | The latest version can be downloaded in jar and referenced as a library.
53 | Link is here http://repo.nhncorp.com/maven2/com/navercorp/utilset/utilset/1.0/utilset-1.0.jar
54 | Just add downloaded jar file into libs folder in your android project.
55 |
56 | or
57 |
58 | You can also configure pom.xml if using Maven :
59 | ```xml
60 |
61 |
75 | (2) Import downloaded project as Maven project in Eclipse (Maven plug-in must be installed to run utilset test project)
76 | (3) Right click on utilset-parent in Package Explorer
77 | (4) Select Run As and then Maven Build
78 | (5) If you run utilset-parent for the first time, then Run Configuration will appear
79 | (6) Type clean install to the Goal tab
80 | (7) Click run button on the bottom
81 |
82 | -------
83 | ## License
84 |
85 | Copyright 2013 Navercorp
86 |
87 | Licensed under the Apache License, Version 2.0 (the "License");
88 | you may not use this file except in compliance with the License.
89 | You may obtain a copy of the License at
90 |
91 | http://www.apache.org/licenses/LICENSE-2.0
92 |
93 | Unless required by applicable law or agreed to in writing, software
94 | distributed under the License is distributed on an "AS IS" BASIS,
95 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
96 | See the License for the specific language governing permissions and
97 | limitations under the License.
--------------------------------------------------------------------------------
/UtilSetSampleApp/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
27 | * When setting the value of parameter 'volume' greater than the maximum value of the media volume will not either cause error or throw exception but maximize the media volume.
28 | * Setting the value of volume lower than 0 will minimize the media volume.
29 | *
30 | * @param context Context
31 | * @param volume volume to be changed
32 | */
33 | public static void setVolume(Context context, int volume) {
34 | adjustMediaVolume(context, volume, 0);
35 | }
36 |
37 | /**
38 | * Sets media volume and displays volume level.
39 | * When setting the value of parameter 'volume' greater than the maximum value of the media volume will not either cause error or throw exception but maximize the media volume.
40 | * Setting the value of volume lower than 0 will minimize the media volume.
41 | *
42 | * @param context Context
43 | * @param volume volume to be changed
44 | */
45 | public static void setVolumeWithLevel(Context context, int volume) {
46 | adjustMediaVolume(context, volume, AudioManager.FLAG_SHOW_UI);
47 | }
48 |
49 | /**
50 | * Increases media volume
51 | *
52 | * @param context
53 | */
54 | public static void increaseVolume(Context context) {
55 | adjustMediaVolume(context, getCurrentVolume(context) + 1, 0);
56 | }
57 |
58 | /**
59 | * Increases media volume and displays volume level
60 | *
61 | * @param context
62 | */
63 | public static void increaseVolumeWithLevel(Context context) {
64 | adjustMediaVolume(context, getCurrentVolume(context) + 1, AudioManager.FLAG_SHOW_UI);
65 | }
66 |
67 | /**
68 | * Decreases media volume
69 | *
70 | * @param context
71 | */
72 | public static void decreaseVolume(Context context) {
73 | adjustMediaVolume(context, getCurrentVolume(context) - 1, 0);
74 | }
75 |
76 | /**
77 | * Decreases media volume and displays volume level
78 | *
79 | * @param context
80 | */
81 | public static void decreaseVolumeWithLevel(Context context) {
82 | adjustMediaVolume(context, getCurrentVolume(context) - 1, AudioManager.FLAG_SHOW_UI);
83 | }
84 |
85 | /** Returns maximum volume the media volume can have
86 | *
87 | * @param context Context
88 | * @return Maximum volume
89 | */
90 | public static int getMaximumVolume(Context context) {
91 | return ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE)).getStreamMaxVolume(AudioManager.STREAM_MUSIC);
92 | }
93 |
94 | /** Returns minimum volume the media volume can have
95 | *
96 | * @param context Context
97 | * @return Minimum volume
98 | */
99 | public static int getMinimumVolume(Context context) {
100 | return 0;
101 | }
102 |
103 | private static void adjustMediaVolume(Context context, int volume, int flag) {
104 | final int MAX_VOLUME = getMaximumVolume(context);
105 | final int MIN_VOLUME = 0;
106 |
107 | if( volume < MIN_VOLUME ) {
108 | volume = MIN_VOLUME;
109 | } else if( volume > MAX_VOLUME ) {
110 | volume = MAX_VOLUME;
111 | }
112 |
113 | AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
114 | if (audioManager != null) {
115 | audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, flag);
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/UtilSet/src/com/navercorp/utilset/cipher/AesCipher.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilset.cipher;
2 |
3 | import java.security.InvalidKeyException;
4 | import java.security.NoSuchAlgorithmException;
5 | import java.security.NoSuchProviderException;
6 | import java.security.SecureRandom;
7 |
8 | import javax.crypto.BadPaddingException;
9 | import javax.crypto.Cipher;
10 | import javax.crypto.IllegalBlockSizeException;
11 | import javax.crypto.KeyGenerator;
12 | import javax.crypto.NoSuchPaddingException;
13 | import javax.crypto.SecretKey;
14 | import javax.crypto.spec.SecretKeySpec;
15 |
16 | import android.util.Log;
17 |
18 | /**
19 | * @author jaemin.woo
20 | *
21 | */
22 | public class AesCipher implements CipherObject {
23 | private static final String TAG = AesCipher.class.getSimpleName();
24 | private final static int JELLY_BEAN_MR1 = 17;
25 |
26 | @Override
27 | public String encrypt(String seed, String plaintext) {
28 | byte[] rawKey = getRawKey(seed.getBytes());
29 | byte[] result = encrypt(rawKey, plaintext.getBytes());
30 | return toHex(result);
31 | }
32 |
33 | @Override
34 | public String decrypt(String seed, String ciphertext) {
35 | byte[] rawKey = getRawKey(seed.getBytes());
36 | byte[] enc = toByte(ciphertext);
37 | byte[] result = decrypt(rawKey, enc);
38 | return new String(result);
39 |
40 | }
41 |
42 | private static void handleGettingAesFailure() {
43 | Log.d(TAG, "Getting AES provider has failed but this can't be happened");
44 | }
45 |
46 | private static byte[] getRawKey(byte[] seed) {
47 | KeyGenerator kgen = null;
48 |
49 | try {
50 | kgen = KeyGenerator.getInstance("AES");
51 | SecureRandom sr = null;
52 | if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_MR1) {
53 | sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
54 | } else {
55 | sr = SecureRandom.getInstance("SHA1PRNG");
56 | }
57 | if (sr == null) {
58 | Log.d(TAG, "Failed to get SecureRandom Crypto Algorithm");
59 | return null;
60 | }
61 | sr.setSeed(seed);
62 | kgen.init(128, sr); // 192 and 256 bits may not be available
63 | } catch (NoSuchAlgorithmException e) {
64 | // Impossible
65 | handleGettingAesFailure();
66 | } catch (NoSuchProviderException e) {
67 | // Android whose version is equal or above than JELLY_BEAN_MR1 provides Crypto provider
68 | // If it doesn't, this method can work as it is supposed to do
69 | throw new RuntimeException(e);
70 | }
71 |
72 | if (kgen != null) {
73 | SecretKey skey = kgen.generateKey();
74 | return skey.getEncoded();
75 | } else {
76 | return null;
77 | }
78 | }
79 |
80 | private byte[] encrypt(byte[] raw, byte[] clear) {
81 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
82 | Cipher cipher;
83 | byte [] encrypted = null;
84 | try {
85 | cipher = Cipher.getInstance("AES");
86 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
87 | encrypted = cipher.doFinal(clear);
88 | } catch (NoSuchAlgorithmException e) {
89 | // Android provides AES Encryption by default
90 | handleGettingAesFailure();
91 | }
92 | // Exceptions under here occurs because of programming error
93 | catch (NoSuchPaddingException e) {
94 | throw new RuntimeException(e);
95 | } catch (InvalidKeyException e) {
96 | throw new RuntimeException(e);
97 | } catch (IllegalBlockSizeException e) {
98 | throw new RuntimeException(e);
99 | } catch (BadPaddingException e) {
100 | throw new RuntimeException(e);
101 | }
102 |
103 | return encrypted;
104 | }
105 |
106 | private byte[] decrypt(byte[] raw, byte[] encrypted) {
107 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
108 | Cipher cipher;
109 | byte [] decrypted = null;
110 | try {
111 | cipher = Cipher.getInstance("AES");
112 | cipher.init(Cipher.DECRYPT_MODE, skeySpec);
113 | decrypted = cipher.doFinal(encrypted);
114 | } catch (NoSuchAlgorithmException e) {
115 | // Can't be happened
116 | handleGettingAesFailure();
117 | }
118 | // Exceptions under here occurs because of programming error
119 | catch (NoSuchPaddingException e) {
120 | throw new RuntimeException(e);
121 | } catch (InvalidKeyException e) {
122 | throw new RuntimeException(e);
123 | } catch (IllegalBlockSizeException e) {
124 | throw new RuntimeException(e);
125 | } catch (BadPaddingException e) {
126 | throw new RuntimeException(e);
127 | }
128 |
129 | return decrypted;
130 | }
131 |
132 | private byte[] toByte(String hexString) {
133 | int len = hexString.length() / 2;
134 | byte[] result = new byte[len];
135 | for (int i = 0; i < len; i++) {
136 | result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
137 | }
138 | return result;
139 | }
140 |
141 | private String toHex(byte[] buf) {
142 | if (buf == null) {
143 | return "";
144 | }
145 | StringBuffer result = new StringBuffer(2 * buf.length);
146 | for (int i = 0; i < buf.length; i++) {
147 | appendHex(result, buf[i]);
148 | }
149 | return result.toString();
150 | }
151 |
152 | private final static String HEX = "0123456789ABCDEF";
153 |
154 | private static void appendHex(StringBuffer sb, byte bt) {
155 | sb.append(HEX.charAt((bt >> 4) & 0x0f)).append(HEX.charAt(bt & 0x0f));
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/UtilSet/src/com/navercorp/utilset/ui/ActivityUtils.java:
--------------------------------------------------------------------------------
1 | package com.navercorp.utilset.ui;
2 |
3 | import java.util.List;
4 |
5 | import android.app.ActivityManager;
6 | import android.app.ActivityManager.RunningAppProcessInfo;
7 | import android.app.ActivityManager.RunningTaskInfo;
8 | import android.content.ComponentName;
9 | import android.content.Context;
10 | import android.content.Intent;
11 | import android.content.pm.PackageManager;
12 | import android.content.pm.ResolveInfo;
13 |
14 | /**
15 | *
16 | * @author jaemin.woo
17 | *
18 | */
19 | public class ActivityUtils {
20 | /** Checks if a package is installed.
21 | *
22 | * @param context Context to be used to verify the existence of the package.
23 | * @param packageName Package name to be searched.
24 | * @return true if the package is discovered; false otherwise
25 | */
26 | public static boolean isPackageInstalled(Context context, String packageName) {
27 | try {
28 | context.getPackageManager().getApplicationInfo(packageName, 0);
29 | return true;
30 | } catch (Exception e) {
31 | return false;
32 | }
33 | }
34 |
35 | /** Returns Package name of base activity.
20 | * When string to be compressed neither lengthy nor repeated at all, then that is not the case for this method to be utilized.
21 | * Long repeated string is where this method really shines.
23 | * A long repeated string 'aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbcccccccccc' will be compressed into 'H4slAAAAAAAAAEtMxAKSslBkOAAA0lkFljMAAAA=' which is shorter than original one.
24 | * In contrast, A short but not repeated string 'abcdefghijklmnopqrstuvwxyz' will be compressed into 'H4slAAAAAAAAAEtMSk5JTUvPyMzKzsnNyy8oLCouKS0rr6isAgC9UCdMGgAAAA==' which is longer than original string.
25 | *
26 | * @author jaemin.woo
27 | *
28 | */
29 | public class StringCompressor {
30 | private static final int BUFFER_SIZE = 2 * 1024;
31 |
32 | public String compress(String str) {
33 | if (str == null || str.length() == 0) {
34 | return str;
35 | }
36 |
37 | String compressBase64EncodeStr = null;
38 | InputStream is = null;
39 | ByteArrayOutputStream baos = null;
40 | GZIPOutputStream gzos = null;
41 |
42 | try {
43 | is = new ByteArrayInputStream(str.getBytes("UTF-8"));
44 | baos = new ByteArrayOutputStream();
45 | gzos = new GZIPOutputStream(baos);
46 | byte buffer[] = new byte[BUFFER_SIZE];
47 | int count = -1;
48 | while ((count = is.read(buffer, 0, BUFFER_SIZE)) != -1) {
49 | gzos.write(buffer, 0, count);
50 | }
51 | gzos.finish();
52 | compressBase64EncodeStr = new String(Base64.encode(
53 | baos.toByteArray(), Base64.DEFAULT));
54 | } catch (UnsupportedEncodingException e1) {
55 | // This can't be happened
56 | throw new RuntimeException("This would never be happened");
57 | } catch (IOException e) {
58 | throw new RuntimeException(String.format("Exception occured while compressing String \"%s\"", str));
59 | } finally {
60 | if (is != null) {
61 | try {
62 | is.close();
63 | } catch (IOException e) {
64 | throw new RuntimeException("Exception occured while closing InputStream");
65 | }
66 | }
67 |
68 | if (gzos != null) {
69 | try {
70 | gzos.close();
71 | } catch (IOException e) {
72 | throw new RuntimeException("Exception occured while closing GZIPOutputStream");
73 | }
74 | }
75 | }
76 |
77 | return compressBase64EncodeStr;
78 | }
79 |
80 | private static String urlDecode(String src) {
81 | String dst = null;
82 | try {
83 | dst = URLDecoder.decode(src, "UTF-8");
84 | } catch (UnsupportedEncodingException e) {
85 | Log.e("UtilSet",
86 | "An UnsupportedEncodingException occured in "
87 | + StringCompressor.class
88 | + ".urlDecode. However, it does not terminate application and continues decode with default encoding character set.");
89 | dst = Uri.decode(src);
90 | }
91 |
92 | return dst;
93 | }
94 |
95 | public String decompress(String str) {
96 | if (str == null || str.length() == 0) {
97 | return str;
98 | }
99 |
100 | String decompressStr = null;
101 | InputStream is = null;
102 | GZIPInputStream gzis = null;
103 | ByteArrayOutputStream baos = null;
104 |
105 | try {
106 | is = new ByteArrayInputStream(Base64.decode(urlDecode(str)
107 | .getBytes(), Base64.DEFAULT));
108 | gzis = new GZIPInputStream(is);
109 | baos = new ByteArrayOutputStream();
110 |
111 | byte buffer[] = new byte[BUFFER_SIZE];
112 | int count = -1;
113 | while ((count = gzis.read(buffer, 0, BUFFER_SIZE)) != -1) {
114 | baos.write(buffer, 0, count);
115 | }
116 |
117 | decompressStr = new String(baos.toByteArray(), "UTF-8");
118 | } catch (IOException e) {
119 | throw new RuntimeException(String.format("Exception occured while decompressing string \"%s\""));
120 | }
121 | finally {
122 | if (baos != null) {
123 | try {
124 | baos.close();
125 | } catch (IOException e) {
126 | throw new RuntimeException("Exception occured while closing ByteArrayOutputStream");
127 | }
128 | }
129 |
130 | if (gzis != null) {
131 | try {
132 | gzis.close();
133 | } catch (IOException e) {
134 | throw new RuntimeException("Exception occured while closing GZIPInputStream");
135 | }
136 | }
137 | }
138 |
139 | return decompressStr;
140 | }
141 |
142 | public InputStream decompress(InputStream is) {
143 | if (is == null) {
144 | return is;
145 | }
146 |
147 | InputStream retIs = null;
148 | ByteArrayInputStream bais = null;
149 | GZIPInputStream gzis = null;
150 | ByteArrayOutputStream baos = null;
151 |
152 | try {
153 | bais = new ByteArrayInputStream(Base64.decode(
154 | convertStreamToByteArray(is), Base64.DEFAULT));
155 | gzis = new GZIPInputStream(bais);
156 | baos = new ByteArrayOutputStream();
157 |
158 | byte buffer[] = new byte[BUFFER_SIZE];
159 | int count = -1;
160 | while ((count = gzis.read(buffer, 0, BUFFER_SIZE)) != -1) {
161 | baos.write(buffer, 0, count);
162 | }
163 |
164 | retIs = new ByteArrayInputStream(baos.toByteArray());
165 | } catch (IOException e) {
166 | throw new RuntimeException("Exception occured while decompressing InputStream");
167 | } finally {
168 | if (baos != null) {
169 | try {
170 | baos.close();
171 | } catch (IOException e) {
172 | throw new RuntimeException("Exception occured while closing ByteArrayOutputStream");
173 | }
174 | }
175 |
176 | if (gzis != null) {
177 | try {
178 | gzis.close();
179 | } catch (IOException e) {
180 | throw new RuntimeException("Exception occured while closing GZIPInputStream");
181 | }
182 | }
183 | }
184 |
185 | return retIs;
186 | }
187 |
188 | private byte[] convertStreamToByteArray(InputStream is) throws IOException {
189 | BufferedReader reader = new BufferedReader(new InputStreamReader(is));
190 | StringBuilder sb = new StringBuilder();
191 | String line = null;
192 |
193 | try {
194 | while ((line = reader.readLine()) != null) {
195 | sb.append(line);
196 | }
197 | } catch (IOException e) {
198 | // Just bypasses exception so that the caller can handle finalization works or propagate exception
199 | throw e;
200 | } finally {
201 | try {
202 | is.close();
203 | } catch (IOException e) {
204 | // This barely happens.
205 | // Just bypasses exception so that the caller can handle finalization works or propagate exception
206 | throw e;
207 | }
208 | }
209 |
210 | return sb.toString().getBytes();
211 | }
212 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License, Version 2.0
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
13 |
14 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
15 |
16 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
17 |
18 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
19 |
20 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
21 |
22 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
23 |
24 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
25 |
26 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
27 |
28 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
29 |
30 | 2. Grant of Copyright License.
31 |
32 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
33 |
34 | 3. Grant of Patent License.
35 |
36 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
37 |
38 | 4. Redistribution.
39 |
40 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
41 |
42 | You must give any other recipients of the Work or Derivative Works a copy of this License; and
43 | You must cause any modified files to carry prominent notices stating that You changed the files; and
44 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
45 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
46 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
47 |
48 | 5. Submission of Contributions.
49 |
50 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
51 |
52 | 6. Trademarks.
53 |
54 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
55 |
56 | 7. Disclaimer of Warranty.
57 |
58 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
59 |
60 | 8. Limitation of Liability.
61 |
62 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
63 |
64 | 9. Accepting Warranty or Additional Liability.
65 |
66 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
67 |
68 | END OF TERMS AND CONDITIONS
69 |
70 | APPENDIX: How to apply the Apache License to your work
71 |
72 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
73 |
74 | Copyright [yyyy] [name of copyright owner]
75 |
76 | Licensed under the Apache License, Version 2.0 (the "License");
77 | you may not use this file except in compliance with the License.
78 | You may obtain a copy of the License at
79 |
80 | http://www.apache.org/licenses/LICENSE-2.0
81 |
82 | Unless required by applicable law or agreed to in writing, software
83 | distributed under the License is distributed on an "AS IS" BASIS,
84 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85 | See the License for the specific language governing permissions and
86 | limitations under the License.
--------------------------------------------------------------------------------
/UtilSet/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License, Version 2.0
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
13 |
14 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
15 |
16 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
17 |
18 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
19 |
20 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
21 |
22 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
23 |
24 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
25 |
26 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
27 |
28 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
29 |
30 | 2. Grant of Copyright License.
31 |
32 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
33 |
34 | 3. Grant of Patent License.
35 |
36 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
37 |
38 | 4. Redistribution.
39 |
40 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
41 |
42 | You must give any other recipients of the Work or Derivative Works a copy of this License; and
43 | You must cause any modified files to carry prominent notices stating that You changed the files; and
44 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
45 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
46 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
47 |
48 | 5. Submission of Contributions.
49 |
50 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
51 |
52 | 6. Trademarks.
53 |
54 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
55 |
56 | 7. Disclaimer of Warranty.
57 |
58 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
59 |
60 | 8. Limitation of Liability.
61 |
62 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
63 |
64 | 9. Accepting Warranty or Additional Liability.
65 |
66 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
67 |
68 | END OF TERMS AND CONDITIONS
69 |
70 | APPENDIX: How to apply the Apache License to your work
71 |
72 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
73 |
74 | Copyright [yyyy] [name of copyright owner]
75 |
76 | Licensed under the Apache License, Version 2.0 (the "License");
77 | you may not use this file except in compliance with the License.
78 | You may obtain a copy of the License at
79 |
80 | http://www.apache.org/licenses/LICENSE-2.0
81 |
82 | Unless required by applicable law or agreed to in writing, software
83 | distributed under the License is distributed on an "AS IS" BASIS,
84 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85 | See the License for the specific language governing permissions and
86 | limitations under the License.
--------------------------------------------------------------------------------