的
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
*.iml
|
||||
@@ -0,0 +1,46 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 27
|
||||
versionCode 13
|
||||
versionName "1.1.3"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
options.addStringOption('encoding', 'UTF-8')
|
||||
}
|
||||
|
||||
def libVersion = '1.2.0'
|
||||
task makeJar(type: Jar) {
|
||||
// 指定生成的jar名
|
||||
def rootDir = project.getRootDir();
|
||||
def parentDir = project.getRootDir().getParentFile().getAbsolutePath();
|
||||
|
||||
delete 'build/libs/*.*'
|
||||
archiveName 'android-common-' + libVersion + '.jar'
|
||||
destinationDir = file('build/libs')
|
||||
// 从哪里打包class文件
|
||||
from('build/intermediates/classes/release/')
|
||||
// 打包到jar后的目录结构
|
||||
// 去掉不需要打包的目录和文件
|
||||
exclude('test/', 'BuildConfig.class', 'R.class', 'R\$*.class', 'META-INF/')
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/luffy/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -0,0 +1,18 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.litesuits.common">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application>
|
||||
|
||||
<service
|
||||
android:name=".service.NotificationService"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.litesuits.android.async;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 异步执行
|
||||
*
|
||||
* @author MaTianyu
|
||||
*/
|
||||
public class AsyncExecutor {
|
||||
private static final String TAG = AsyncExecutor.class.getSimpleName();
|
||||
private static ExecutorService threadPool;
|
||||
public static Handler handler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public AsyncExecutor() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public AsyncExecutor(ExecutorService threadPool) {
|
||||
if (AsyncExecutor.threadPool != null) {
|
||||
shutdownNow();
|
||||
}
|
||||
if (threadPool == null) {
|
||||
AsyncExecutor.threadPool = Executors.newCachedThreadPool();
|
||||
} else {
|
||||
AsyncExecutor.threadPool = threadPool;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void shutdownNow() {
|
||||
if (threadPool != null && !threadPool.isShutdown()) threadPool.shutdownNow();
|
||||
threadPool = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将任务投入线程池执行
|
||||
*
|
||||
* @param worker
|
||||
* @return
|
||||
*/
|
||||
public <T> FutureTask<T> execute(final Worker<T> worker) {
|
||||
Callable<T> call = new Callable<T>() {
|
||||
@Override
|
||||
public T call() throws Exception {
|
||||
return postResult(worker, worker.doInBackground());
|
||||
}
|
||||
};
|
||||
FutureTask<T> task = new FutureTask<T>(call) {
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
get();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, e);
|
||||
worker.abort();
|
||||
postCancel(worker);
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("An error occured while executing doInBackground()", e.getCause());
|
||||
} catch (CancellationException e) {
|
||||
worker.abort();
|
||||
postCancel(worker);
|
||||
Log.e(TAG, e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
threadPool.execute(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将子线程结果传递到UI线程
|
||||
*
|
||||
* @param worker
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
private <T> T postResult(final Worker<T> worker, final T result) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
worker.onPostExecute(result);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将子线程结果传递到UI线程
|
||||
*
|
||||
* @param worker
|
||||
* @return
|
||||
*/
|
||||
private void postCancel(final Worker worker) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
worker.onCanceled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public <T> FutureTask<T> execute(Callable<T> call) {
|
||||
FutureTask<T> task = new FutureTask<T>(call);
|
||||
threadPool.execute(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public static abstract class Worker<T> {
|
||||
protected abstract T doInBackground();
|
||||
|
||||
protected void onPostExecute(T data) {}
|
||||
|
||||
protected void onCanceled() {}
|
||||
|
||||
protected void abort() {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2013 litesuits.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.android.log;
|
||||
|
||||
/**
|
||||
* the logger
|
||||
*
|
||||
* @author MaTianyu
|
||||
* 2014-1-1下午4:05:39
|
||||
*/
|
||||
public final class Log {
|
||||
|
||||
/**
|
||||
* isPrint: print switch, true will print. false not print
|
||||
*/
|
||||
public static boolean isPrint = true;
|
||||
private static String defaultTag = "Log";
|
||||
|
||||
private Log() {}
|
||||
|
||||
public static void setTag(String tag) {
|
||||
defaultTag = tag;
|
||||
}
|
||||
|
||||
public static int i(Object o) {
|
||||
return isPrint && o != null ? android.util.Log.i(defaultTag, o.toString()) : -1;
|
||||
}
|
||||
|
||||
public static int i(String m) {
|
||||
return isPrint && m != null ? android.util.Log.i(defaultTag, m) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ******************** Log **************************
|
||||
*/
|
||||
public static int v(String tag, String msg) {
|
||||
return isPrint && msg != null ? android.util.Log.v(tag, msg) : -1;
|
||||
}
|
||||
|
||||
public static int d(String tag, String msg) {
|
||||
return isPrint && msg != null ? android.util.Log.d(tag, msg) : -1;
|
||||
}
|
||||
|
||||
public static int i(String tag, String msg) {
|
||||
return isPrint && msg != null ? android.util.Log.i(tag, msg) : -1;
|
||||
}
|
||||
|
||||
public static int w(String tag, String msg) {
|
||||
return isPrint && msg != null ? android.util.Log.w(tag, msg) : -1;
|
||||
}
|
||||
|
||||
public static int e(String tag, String msg) {
|
||||
return isPrint && msg != null ? android.util.Log.e(tag, msg) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ******************** Log with object list **************************
|
||||
*/
|
||||
public static int v(String tag, Object... msg) {
|
||||
return isPrint ? android.util.Log.v(tag, getLogMessage(msg)) : -1;
|
||||
}
|
||||
|
||||
public static int d(String tag, Object... msg) {
|
||||
return isPrint ? android.util.Log.d(tag, getLogMessage(msg)) : -1;
|
||||
}
|
||||
|
||||
public static int i(String tag, Object... msg) {
|
||||
return isPrint ? android.util.Log.i(tag, getLogMessage(msg)) : -1;
|
||||
}
|
||||
|
||||
public static int w(String tag, Object... msg) {
|
||||
return isPrint ? android.util.Log.w(tag, getLogMessage(msg)) : -1;
|
||||
}
|
||||
|
||||
public static int e(String tag, Object... msg) {
|
||||
return isPrint ? android.util.Log.e(tag, getLogMessage(msg)) : -1;
|
||||
}
|
||||
|
||||
private static String getLogMessage(Object... msg) {
|
||||
if (msg != null && msg.length > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object s : msg) {
|
||||
if (s != null) {
|
||||
sb.append(s.toString());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* ******************** Log with Throwable **************************
|
||||
*/
|
||||
public static int v(String tag, String msg, Throwable tr) {
|
||||
return isPrint && msg != null ? android.util.Log.v(tag, msg, tr) : -1;
|
||||
}
|
||||
|
||||
public static int d(String tag, String msg, Throwable tr) {
|
||||
return isPrint && msg != null ? android.util.Log.d(tag, msg, tr) : -1;
|
||||
}
|
||||
|
||||
public static int i(String tag, String msg, Throwable tr) {
|
||||
return isPrint && msg != null ? android.util.Log.i(tag, msg, tr) : -1;
|
||||
}
|
||||
|
||||
public static int w(String tag, String msg, Throwable tr) {
|
||||
return isPrint && msg != null ? android.util.Log.w(tag, msg, tr) : -1;
|
||||
}
|
||||
|
||||
public static int e(String tag, String msg, Throwable tr) {
|
||||
return isPrint && msg != null ? android.util.Log.e(tag, msg, tr) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ******************** TAG use Object Tag **************************
|
||||
*/
|
||||
public static int v(Object tag, String msg) {
|
||||
return isPrint ? android.util.Log.v(tag.getClass().getSimpleName(), msg) : -1;
|
||||
}
|
||||
|
||||
public static int d(Object tag, String msg) {
|
||||
return isPrint ? android.util.Log.d(tag.getClass().getSimpleName(), msg) : -1;
|
||||
}
|
||||
|
||||
public static int i(Object tag, String msg) {
|
||||
return isPrint ? android.util.Log.i(tag.getClass().getSimpleName(), msg) : -1;
|
||||
}
|
||||
|
||||
public static int w(Object tag, String msg) {
|
||||
return isPrint ? android.util.Log.w(tag.getClass().getSimpleName(), msg) : -1;
|
||||
}
|
||||
|
||||
public static int e(Object tag, String msg) {
|
||||
return isPrint ? android.util.Log.e(tag.getClass().getSimpleName(), msg) : -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2013 litesuits.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.android.log;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 打印日志
|
||||
*
|
||||
* @author mty
|
||||
* @time 2011-11-2下午06:23:29
|
||||
*/
|
||||
public class LogReader extends Thread {
|
||||
public static final String TAG = "LogReader";
|
||||
public static final String LOG_FILE_PATH = "/bonglog.txt";
|
||||
public static final String LOG_ROOT_PATH = "/sdcard";
|
||||
|
||||
public static boolean open = true;
|
||||
private static LogReader instance = null;
|
||||
private static Process mLogcatProc = null;
|
||||
|
||||
private BufferedReader mReader = null;
|
||||
private String packageName = "*";
|
||||
|
||||
public static void startCatchLog(String packageName) {
|
||||
if (!open) return;
|
||||
if (instance == null) {
|
||||
instance = new LogReader();
|
||||
instance.packageName = packageName;
|
||||
instance.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopCatchLog() {
|
||||
if (!open) return;
|
||||
if (mLogcatProc != null) {
|
||||
mLogcatProc.destroy();
|
||||
mLogcatProc = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "log reader(catcher) is running..---------------------------");
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
mLogcatProc = Runtime.getRuntime().exec("logcat " + packageName + ":I");
|
||||
mReader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));
|
||||
|
||||
// 打印系统信息。
|
||||
logSystemInfo();
|
||||
|
||||
String line;
|
||||
File file = new File(LOG_ROOT_PATH + LOG_FILE_PATH);
|
||||
if (file.exists() && isFileSizeOutof10M(file)) {
|
||||
file.delete();
|
||||
}
|
||||
if (file.exists()) {
|
||||
System.out.println("log file size is :"
|
||||
+ FormatFileSize(file.length()));
|
||||
}
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
bw = new BufferedWriter(fw);
|
||||
while ((line = mReader.readLine()) != null) {
|
||||
bw.append(line);
|
||||
bw.newLine();
|
||||
bw.flush();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
Log.i(TAG, "Log reader(catcher) and bufferwriter has closed. ------------------");
|
||||
try {
|
||||
if (mReader != null) {
|
||||
mReader.close();
|
||||
mReader = null;
|
||||
}
|
||||
if (bw != null) {
|
||||
bw.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
instance = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String FormatFileSize(long fileS) {// 转换文件大小
|
||||
DecimalFormat df = new DecimalFormat("#.00");
|
||||
String fileSizeString = "";
|
||||
if (fileS < 1024) {
|
||||
fileSizeString = df.format((double) fileS) + "B";
|
||||
} else if (fileS < 1048576) {
|
||||
fileSizeString = df.format((double) fileS / 1024) + "K";
|
||||
} else if (fileS < 1073741824) {
|
||||
fileSizeString = df.format((double) fileS / 1048576) + "M";
|
||||
} else {
|
||||
fileSizeString = df.format((double) fileS / 1073741824) + "G";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否大于10M。
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isFileSizeOutof10M(File file) throws Exception {
|
||||
if (file == null) return false;
|
||||
return file.length() >= 10485760;
|
||||
}
|
||||
|
||||
public static void logSystemInfo() {
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String time = dateFormat.format(date);
|
||||
android.util.Log.w("system", "New Start $$$$$$$$$$$$$$########### " + time + "############$$$$$$$$$$$$$$$");
|
||||
android.util.Log.w("system", "android.os.Build.BOARD:" + android.os.Build.BOARD);
|
||||
android.util.Log.w("system", "android.os.Build.DEVICE:" + android.os.Build.DEVICE);
|
||||
android.util.Log.w("system", "android.os.Build.MANUFACTURER:"
|
||||
+ android.os.Build.MANUFACTURER);
|
||||
android.util.Log.w("system", "android.os.Build.MODEL:" + android.os.Build.MODEL);
|
||||
android.util.Log.w("system", "android.os.Build.PRODUCT:" + android.os.Build.PRODUCT);
|
||||
android.util.Log.w("system", "android.os.Build.VERSION.CODENAME:"
|
||||
+ android.os.Build.VERSION.CODENAME);
|
||||
android.util.Log.w("system", "android.os.Build.VERSION.RELEASE:"
|
||||
+ android.os.Build.VERSION.RELEASE);
|
||||
//android.util.Log.w("system", "android.os.Build.VERSION.SDK:"
|
||||
// + android.os.Build.VERSION.SDK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.litesuits.android.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-08-15
|
||||
*/
|
||||
public class TipsView extends LinearLayout {
|
||||
protected View realView;
|
||||
protected ViewGroup parentView;
|
||||
|
||||
protected Context context;
|
||||
protected boolean isThisInLayout = false;
|
||||
|
||||
public TipsView(Context context) {
|
||||
this(context, (AttributeSet) null);
|
||||
}
|
||||
|
||||
public TipsView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, null, null);
|
||||
}
|
||||
|
||||
public TipsView(Context context, View realView, View tipView) {
|
||||
this(context, null, realView, tipView);
|
||||
}
|
||||
|
||||
public TipsView(Context context, View realView) {
|
||||
this(context, null, realView, null);
|
||||
}
|
||||
|
||||
public TipsView(Context context, AttributeSet attrs, View realView, View tipView) {
|
||||
super(context, attrs);
|
||||
this.context = context;
|
||||
initSelf();
|
||||
setRealView(realView);
|
||||
setTipView(tipView);
|
||||
}
|
||||
|
||||
public void initSelf() {
|
||||
setOrientation(HORIZONTAL);
|
||||
setGravity(Gravity.CENTER);
|
||||
}
|
||||
|
||||
public TipsView setTipView(View tipView) {
|
||||
if (tipView != null) {
|
||||
removeAllViews();
|
||||
addView(tipView);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TipsView setTipView(int resID) {
|
||||
removeAllViews();
|
||||
LayoutInflater.from(context).inflate(resID, this, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public View getRealView() {
|
||||
return realView;
|
||||
}
|
||||
|
||||
|
||||
public TipsView setRealView(View realView) {
|
||||
if (realView != null) {
|
||||
showRealView();
|
||||
this.realView = realView;
|
||||
parentView = (ViewGroup) realView.getParent();
|
||||
setLayoutParams(realView.getLayoutParams());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void showRealView() {
|
||||
if (realView != null && parentView != null) {
|
||||
if (isThisInLayout) {
|
||||
for (int i = 0, size = parentView.getChildCount(); i < size; i++) {
|
||||
if (parentView.getChildAt(i) == this) {
|
||||
parentView.removeView(this);
|
||||
//realView.setId(getId());
|
||||
//setId(0);
|
||||
parentView.addView(realView, i);
|
||||
isThisInLayout = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showTipsView() {
|
||||
if (realView != null && parentView != null) {
|
||||
if (!isThisInLayout) {
|
||||
for (int i = 0, size = parentView.getChildCount(); i < size; i++) {
|
||||
if (parentView.getChildAt(i) == realView) {
|
||||
parentView.removeView(realView);
|
||||
//setId(realView.getId());
|
||||
//realView.setId(0);
|
||||
parentView.addView(this, i);
|
||||
isThisInLayout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void gone() {
|
||||
setVisibility(GONE);
|
||||
}
|
||||
|
||||
public void visible() {
|
||||
setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
public void inVisible() {
|
||||
setVisibility(INVISIBLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 用以统计平均数
|
||||
*
|
||||
* @author MaTianyu
|
||||
* 2013-12-11下午3:31:03
|
||||
*/
|
||||
public class Averager {
|
||||
private static final String TAG = "Averager";
|
||||
private ArrayList<Number> numList = new ArrayList<Number>();
|
||||
|
||||
/**
|
||||
* 添加一个数字
|
||||
*
|
||||
* @param num
|
||||
*/
|
||||
public synchronized void add(Number num) {
|
||||
numList.add(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除全部
|
||||
*/
|
||||
public void clear() {
|
||||
numList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回参与均值计算的数字个数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Number size() {
|
||||
return numList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平均数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Number getAverage() {
|
||||
if (numList.size() == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
Float sum = 0f;
|
||||
for (int i = 0, size = numList.size(); i < size; i++) {
|
||||
sum = sum.floatValue() + numList.get(i).floatValue();
|
||||
}
|
||||
return sum / numList.size();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印数字列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String print() {
|
||||
String str = "PrintList(" + size() + "): " + numList;
|
||||
Log.i(TAG, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Utilities for encoding and decoding the Base64 representation of
|
||||
* binary data. See RFCs <a
|
||||
* href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a
|
||||
* href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>.
|
||||
*/
|
||||
public class Base64 {
|
||||
/**
|
||||
* Default values for encoder/decoder flags.
|
||||
*/
|
||||
public static final int DEFAULT = 0;
|
||||
|
||||
/**
|
||||
* Encoder flag bit to omit the padding '=' characters at the end
|
||||
* of the output (if any).
|
||||
*/
|
||||
public static final int NO_PADDING = 1;
|
||||
|
||||
/**
|
||||
* Encoder flag bit to omit all line terminators (i.e., the output
|
||||
* will be on one long line).
|
||||
*/
|
||||
public static final int NO_WRAP = 2;
|
||||
|
||||
/**
|
||||
* Encoder flag bit to indicate lines should be terminated with a
|
||||
* CRLF pair instead of just an LF. Has no effect if {@code
|
||||
* NO_WRAP} is specified as well.
|
||||
*/
|
||||
public static final int CRLF = 4;
|
||||
|
||||
/**
|
||||
* Encoder/decoder flag bit to indicate using the "URL and
|
||||
* filename safe" variant of Base64 (see RFC 3548 section 4) where
|
||||
* {@code -} and {@code _} are used in place of {@code +} and
|
||||
* {@code /}.
|
||||
*/
|
||||
public static final int URL_SAFE = 8;
|
||||
|
||||
/**
|
||||
* Flag to pass to {@link android.util.Base64OutputStream} to indicate that it
|
||||
* should not close the output stream it is wrapping when it
|
||||
* itself is closed.
|
||||
*/
|
||||
public static final int NO_CLOSE = 16;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// shared code
|
||||
// --------------------------------------------------------
|
||||
|
||||
/* package */ static abstract class Coder {
|
||||
public byte[] output;
|
||||
public int op;
|
||||
|
||||
/**
|
||||
* Encode/decode another block of input data. this.output is
|
||||
* provided by the caller, and must be big enough to hold all
|
||||
* the coded data. On exit, this.opwill be set to the length
|
||||
* of the coded data.
|
||||
*
|
||||
* @param finish true if this is the final call to process for
|
||||
* this object. Will finalize the coder state and
|
||||
* include any final bytes in the output.
|
||||
*
|
||||
* @return true if the input so far is good; false if some
|
||||
* error has been detected in the input stream..
|
||||
*/
|
||||
public abstract boolean process(byte[] input, int offset, int len, boolean finish);
|
||||
|
||||
/**
|
||||
* @return the maximum number of bytes a call to process()
|
||||
* could produce for the given number of input bytes. This may
|
||||
* be an overestimate.
|
||||
*/
|
||||
public abstract int maxOutputSize(int len);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// decoding
|
||||
// --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Decode the Base64-encoded data in input and return the data in
|
||||
* a new byte array.
|
||||
*
|
||||
* <p>The padding '=' characters at the end are considered optional, but
|
||||
* if any are present, there must be the correct number of them.
|
||||
*
|
||||
* @param str the input String to decode, which is converted to
|
||||
* bytes using the default charset
|
||||
* @param flags controls certain features of the decoded output.
|
||||
* Pass {@code DEFAULT} to decode standard Base64.
|
||||
*
|
||||
* @throws IllegalArgumentException if the input contains
|
||||
* incorrect padding
|
||||
*/
|
||||
public static byte[] decode(String str, int flags) {
|
||||
return decode(str.getBytes(), flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the Base64-encoded data in input and return the data in
|
||||
* a new byte array.
|
||||
*
|
||||
* <p>The padding '=' characters at the end are considered optional, but
|
||||
* if any are present, there must be the correct number of them.
|
||||
*
|
||||
* @param input the input array to decode
|
||||
* @param flags controls certain features of the decoded output.
|
||||
* Pass {@code DEFAULT} to decode standard Base64.
|
||||
*
|
||||
* @throws IllegalArgumentException if the input contains
|
||||
* incorrect padding
|
||||
*/
|
||||
public static byte[] decode(byte[] input, int flags) {
|
||||
return decode(input, 0, input.length, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the Base64-encoded data in input and return the data in
|
||||
* a new byte array.
|
||||
*
|
||||
* <p>The padding '=' characters at the end are considered optional, but
|
||||
* if any are present, there must be the correct number of them.
|
||||
*
|
||||
* @param input the data to decode
|
||||
* @param offset the position within the input array at which to start
|
||||
* @param len the number of bytes of input to decode
|
||||
* @param flags controls certain features of the decoded output.
|
||||
* Pass {@code DEFAULT} to decode standard Base64.
|
||||
*
|
||||
* @throws IllegalArgumentException if the input contains
|
||||
* incorrect padding
|
||||
*/
|
||||
public static byte[] decode(byte[] input, int offset, int len, int flags) {
|
||||
// Allocate space for the most data the input could represent.
|
||||
// (It could contain less if it contains whitespace, etc.)
|
||||
Decoder decoder = new Decoder(flags, new byte[len*3/4]);
|
||||
|
||||
if (!decoder.process(input, offset, len, true)) {
|
||||
throw new IllegalArgumentException("bad base-64");
|
||||
}
|
||||
|
||||
// Maybe we got lucky and allocated exactly enough output space.
|
||||
if (decoder.op == decoder.output.length) {
|
||||
return decoder.output;
|
||||
}
|
||||
|
||||
// Need to shorten the array, so allocate a new one of the
|
||||
// right size and copy.
|
||||
byte[] temp = new byte[decoder.op];
|
||||
System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* package */ static class Decoder extends Coder {
|
||||
/**
|
||||
* Lookup table for turning bytes into their position in the
|
||||
* Base64 alphabet.
|
||||
*/
|
||||
private static final int DECODE[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode lookup table for the "web safe" variant (RFC 3548
|
||||
* sec. 4) where - and _ replace + and /.
|
||||
*/
|
||||
private static final int DECODE_WEBSAFE[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
/** Non-data values in the DECODE arrays. */
|
||||
private static final int SKIP = -1;
|
||||
private static final int EQUALS = -2;
|
||||
|
||||
/**
|
||||
* States 0-3 are reading through the next input tuple.
|
||||
* State 4 is having read one '=' and expecting exactly
|
||||
* one more.
|
||||
* State 5 is expecting no more data or padding characters
|
||||
* in the input.
|
||||
* State 6 is the error state; an error has been detected
|
||||
* in the input and no future input can "fix" it.
|
||||
*/
|
||||
private int state; // state number (0 to 6)
|
||||
private int value;
|
||||
|
||||
final private int[] alphabet;
|
||||
|
||||
public Decoder(int flags, byte[] output) {
|
||||
this.output = output;
|
||||
|
||||
alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
|
||||
state = 0;
|
||||
value = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an overestimate for the number of bytes {@code
|
||||
* len} bytes could decode to.
|
||||
*/
|
||||
public int maxOutputSize(int len) {
|
||||
return len * 3/4 + 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode another block of input data.
|
||||
*
|
||||
* @return true if the state machine is still healthy. false if
|
||||
* bad base-64 data has been detected in the input stream.
|
||||
*/
|
||||
public boolean process(byte[] input, int offset, int len, boolean finish) {
|
||||
if (this.state == 6) return false;
|
||||
|
||||
int p = offset;
|
||||
len += offset;
|
||||
|
||||
// Using local variables makes the decoder about 12%
|
||||
// faster than if we manipulate the member variables in
|
||||
// the loop. (Even alphabet makes a measurable
|
||||
// difference, which is somewhat surprising to me since
|
||||
// the member variable is final.)
|
||||
int state = this.state;
|
||||
int value = this.value;
|
||||
int op = 0;
|
||||
final byte[] output = this.output;
|
||||
final int[] alphabet = this.alphabet;
|
||||
|
||||
while (p < len) {
|
||||
// Try the fast path: we're starting a new tuple and the
|
||||
// next four bytes of the input stream are all data
|
||||
// bytes. This corresponds to going through states
|
||||
// 0-1-2-3-0. We expect to use this method for most of
|
||||
// the data.
|
||||
//
|
||||
// If any of the next four bytes of input are non-data
|
||||
// (whitespace, etc.), value will end up negative. (All
|
||||
// the non-data values in decode are small negative
|
||||
// numbers, so shifting any of them up and or'ing them
|
||||
// together will result in a value with its top bit set.)
|
||||
//
|
||||
// You can remove this whole block and the output should
|
||||
// be the same, just slower.
|
||||
if (state == 0) {
|
||||
while (p+4 <= len &&
|
||||
(value = ((alphabet[input[p] & 0xff] << 18) |
|
||||
(alphabet[input[p+1] & 0xff] << 12) |
|
||||
(alphabet[input[p+2] & 0xff] << 6) |
|
||||
(alphabet[input[p+3] & 0xff]))) >= 0) {
|
||||
output[op+2] = (byte) value;
|
||||
output[op+1] = (byte) (value >> 8);
|
||||
output[op] = (byte) (value >> 16);
|
||||
op += 3;
|
||||
p += 4;
|
||||
}
|
||||
if (p >= len) break;
|
||||
}
|
||||
|
||||
// The fast path isn't available -- either we've read a
|
||||
// partial tuple, or the next four input bytes aren't all
|
||||
// data, or whatever. Fall back to the slower state
|
||||
// machine implementation.
|
||||
|
||||
int d = alphabet[input[p++] & 0xff];
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (d >= 0) {
|
||||
value = d;
|
||||
++state;
|
||||
} else if (d != SKIP) {
|
||||
this.state = 6;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (d >= 0) {
|
||||
value = (value << 6) | d;
|
||||
++state;
|
||||
} else if (d != SKIP) {
|
||||
this.state = 6;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (d >= 0) {
|
||||
value = (value << 6) | d;
|
||||
++state;
|
||||
} else if (d == EQUALS) {
|
||||
// Emit the last (partial) output tuple;
|
||||
// expect exactly one more padding character.
|
||||
output[op++] = (byte) (value >> 4);
|
||||
state = 4;
|
||||
} else if (d != SKIP) {
|
||||
this.state = 6;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (d >= 0) {
|
||||
// Emit the output triple and return to state 0.
|
||||
value = (value << 6) | d;
|
||||
output[op+2] = (byte) value;
|
||||
output[op+1] = (byte) (value >> 8);
|
||||
output[op] = (byte) (value >> 16);
|
||||
op += 3;
|
||||
state = 0;
|
||||
} else if (d == EQUALS) {
|
||||
// Emit the last (partial) output tuple;
|
||||
// expect no further data or padding characters.
|
||||
output[op+1] = (byte) (value >> 2);
|
||||
output[op] = (byte) (value >> 10);
|
||||
op += 2;
|
||||
state = 5;
|
||||
} else if (d != SKIP) {
|
||||
this.state = 6;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (d == EQUALS) {
|
||||
++state;
|
||||
} else if (d != SKIP) {
|
||||
this.state = 6;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (d != SKIP) {
|
||||
this.state = 6;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!finish) {
|
||||
// We're out of input, but a future call could provide
|
||||
// more.
|
||||
this.state = state;
|
||||
this.value = value;
|
||||
this.op = op;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Done reading input. Now figure out where we are left in
|
||||
// the state machine and finish up.
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
// Output length is a multiple of three. Fine.
|
||||
break;
|
||||
case 1:
|
||||
// Read one extra input byte, which isn't enough to
|
||||
// make another output byte. Illegal.
|
||||
this.state = 6;
|
||||
return false;
|
||||
case 2:
|
||||
// Read two extra input bytes, enough to emit 1 more
|
||||
// output byte. Fine.
|
||||
output[op++] = (byte) (value >> 4);
|
||||
break;
|
||||
case 3:
|
||||
// Read three extra input bytes, enough to emit 2 more
|
||||
// output bytes. Fine.
|
||||
output[op++] = (byte) (value >> 10);
|
||||
output[op++] = (byte) (value >> 2);
|
||||
break;
|
||||
case 4:
|
||||
// Read one padding '=' when we expected 2. Illegal.
|
||||
this.state = 6;
|
||||
return false;
|
||||
case 5:
|
||||
// Read all the padding '='s we expected and no more.
|
||||
// Fine.
|
||||
break;
|
||||
}
|
||||
|
||||
this.state = state;
|
||||
this.op = op;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// encoding
|
||||
// --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Base64-encode the given data and return a newly allocated
|
||||
* String with the result.
|
||||
*
|
||||
* @param input the data to encode
|
||||
* @param flags controls certain features of the encoded output.
|
||||
* Passing {@code DEFAULT} results in output that
|
||||
* adheres to RFC 2045.
|
||||
*/
|
||||
public static String encodeToString(byte[] input, int flags) {
|
||||
try {
|
||||
return new String(encode(input, flags), "US-ASCII");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// US-ASCII is guaranteed to be available.
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64-encode the given data and return a newly allocated
|
||||
* String with the result.
|
||||
*
|
||||
* @param input the data to encode
|
||||
* @param offset the position within the input array at which to
|
||||
* start
|
||||
* @param len the number of bytes of input to encode
|
||||
* @param flags controls certain features of the encoded output.
|
||||
* Passing {@code DEFAULT} results in output that
|
||||
* adheres to RFC 2045.
|
||||
*/
|
||||
public static String encodeToString(byte[] input, int offset, int len, int flags) {
|
||||
try {
|
||||
return new String(encode(input, offset, len, flags), "US-ASCII");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// US-ASCII is guaranteed to be available.
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64-encode the given data and return a newly allocated
|
||||
* byte[] with the result.
|
||||
*
|
||||
* @param input the data to encode
|
||||
* @param flags controls certain features of the encoded output.
|
||||
* Passing {@code DEFAULT} results in output that
|
||||
* adheres to RFC 2045.
|
||||
*/
|
||||
public static byte[] encode(byte[] input, int flags) {
|
||||
return encode(input, 0, input.length, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64-encode the given data and return a newly allocated
|
||||
* byte[] with the result.
|
||||
*
|
||||
* @param input the data to encode
|
||||
* @param offset the position within the input array at which to
|
||||
* start
|
||||
* @param len the number of bytes of input to encode
|
||||
* @param flags controls certain features of the encoded output.
|
||||
* Passing {@code DEFAULT} results in output that
|
||||
* adheres to RFC 2045.
|
||||
*/
|
||||
public static byte[] encode(byte[] input, int offset, int len, int flags) {
|
||||
Encoder encoder = new Encoder(flags, null);
|
||||
|
||||
// Compute the exact length of the array we will produce.
|
||||
int output_len = len / 3 * 4;
|
||||
|
||||
// Account for the tail of the data and the padding bytes, if any.
|
||||
if (encoder.do_padding) {
|
||||
if (len % 3 > 0) {
|
||||
output_len += 4;
|
||||
}
|
||||
} else {
|
||||
switch (len % 3) {
|
||||
case 0: break;
|
||||
case 1: output_len += 2; break;
|
||||
case 2: output_len += 3; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Account for the newlines, if any.
|
||||
if (encoder.do_newline && len > 0) {
|
||||
output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
|
||||
(encoder.do_cr ? 2 : 1);
|
||||
}
|
||||
|
||||
encoder.output = new byte[output_len];
|
||||
encoder.process(input, offset, len, true);
|
||||
|
||||
assert encoder.op == output_len;
|
||||
|
||||
return encoder.output;
|
||||
}
|
||||
|
||||
/* package */ static class Encoder extends Coder {
|
||||
/**
|
||||
* Emit a new line every this many output tuples. Corresponds to
|
||||
* a 76-character line length (the maximum allowable according to
|
||||
* <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>).
|
||||
*/
|
||||
public static final int LINE_GROUPS = 19;
|
||||
|
||||
/**
|
||||
* Lookup table for turning Base64 alphabet positions (6 bits)
|
||||
* into output bytes.
|
||||
*/
|
||||
private static final byte ENCODE[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup table for turning Base64 alphabet positions (6 bits)
|
||||
* into output bytes.
|
||||
*/
|
||||
private static final byte ENCODE_WEBSAFE[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
|
||||
};
|
||||
|
||||
final private byte[] tail;
|
||||
/* package */ int tailLen;
|
||||
private int count;
|
||||
|
||||
final public boolean do_padding;
|
||||
final public boolean do_newline;
|
||||
final public boolean do_cr;
|
||||
final private byte[] alphabet;
|
||||
|
||||
public Encoder(int flags, byte[] output) {
|
||||
this.output = output;
|
||||
|
||||
do_padding = (flags & NO_PADDING) == 0;
|
||||
do_newline = (flags & NO_WRAP) == 0;
|
||||
do_cr = (flags & CRLF) != 0;
|
||||
alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
|
||||
|
||||
tail = new byte[2];
|
||||
tailLen = 0;
|
||||
|
||||
count = do_newline ? LINE_GROUPS : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an overestimate for the number of bytes {@code
|
||||
* len} bytes could encode to.
|
||||
*/
|
||||
public int maxOutputSize(int len) {
|
||||
return len * 8/5 + 10;
|
||||
}
|
||||
|
||||
public boolean process(byte[] input, int offset, int len, boolean finish) {
|
||||
// Using local variables makes the encoder about 9% faster.
|
||||
final byte[] alphabet = this.alphabet;
|
||||
final byte[] output = this.output;
|
||||
int op = 0;
|
||||
int count = this.count;
|
||||
|
||||
int p = offset;
|
||||
len += offset;
|
||||
int v = -1;
|
||||
|
||||
// First we need to concatenate the tail of the previous call
|
||||
// with any input bytes available now and see if we can empty
|
||||
// the tail.
|
||||
|
||||
switch (tailLen) {
|
||||
case 0:
|
||||
// There was no tail.
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (p+2 <= len) {
|
||||
// A 1-byte tail with at least 2 bytes of
|
||||
// input available now.
|
||||
v = ((tail[0] & 0xff) << 16) |
|
||||
((input[p++] & 0xff) << 8) |
|
||||
(input[p++] & 0xff);
|
||||
tailLen = 0;
|
||||
};
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (p+1 <= len) {
|
||||
// A 2-byte tail with at least 1 byte of input.
|
||||
v = ((tail[0] & 0xff) << 16) |
|
||||
((tail[1] & 0xff) << 8) |
|
||||
(input[p++] & 0xff);
|
||||
tailLen = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (v != -1) {
|
||||
output[op++] = alphabet[(v >> 18) & 0x3f];
|
||||
output[op++] = alphabet[(v >> 12) & 0x3f];
|
||||
output[op++] = alphabet[(v >> 6) & 0x3f];
|
||||
output[op++] = alphabet[v & 0x3f];
|
||||
if (--count == 0) {
|
||||
if (do_cr) output[op++] = '\r';
|
||||
output[op++] = '\n';
|
||||
count = LINE_GROUPS;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point either there is no tail, or there are fewer
|
||||
// than 3 bytes of input available.
|
||||
|
||||
// The main loop, turning 3 input bytes into 4 output bytes on
|
||||
// each iteration.
|
||||
while (p+3 <= len) {
|
||||
v = ((input[p] & 0xff) << 16) |
|
||||
((input[p+1] & 0xff) << 8) |
|
||||
(input[p+2] & 0xff);
|
||||
output[op] = alphabet[(v >> 18) & 0x3f];
|
||||
output[op+1] = alphabet[(v >> 12) & 0x3f];
|
||||
output[op+2] = alphabet[(v >> 6) & 0x3f];
|
||||
output[op+3] = alphabet[v & 0x3f];
|
||||
p += 3;
|
||||
op += 4;
|
||||
if (--count == 0) {
|
||||
if (do_cr) output[op++] = '\r';
|
||||
output[op++] = '\n';
|
||||
count = LINE_GROUPS;
|
||||
}
|
||||
}
|
||||
|
||||
if (finish) {
|
||||
// Finish up the tail of the input. Note that we need to
|
||||
// consume any bytes in tail before any bytes
|
||||
// remaining in input; there should be at most two bytes
|
||||
// total.
|
||||
|
||||
if (p-tailLen == len-1) {
|
||||
int t = 0;
|
||||
v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
|
||||
tailLen -= t;
|
||||
output[op++] = alphabet[(v >> 6) & 0x3f];
|
||||
output[op++] = alphabet[v & 0x3f];
|
||||
if (do_padding) {
|
||||
output[op++] = '=';
|
||||
output[op++] = '=';
|
||||
}
|
||||
if (do_newline) {
|
||||
if (do_cr) output[op++] = '\r';
|
||||
output[op++] = '\n';
|
||||
}
|
||||
} else if (p-tailLen == len-2) {
|
||||
int t = 0;
|
||||
v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
|
||||
(((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
|
||||
tailLen -= t;
|
||||
output[op++] = alphabet[(v >> 12) & 0x3f];
|
||||
output[op++] = alphabet[(v >> 6) & 0x3f];
|
||||
output[op++] = alphabet[v & 0x3f];
|
||||
if (do_padding) {
|
||||
output[op++] = '=';
|
||||
}
|
||||
if (do_newline) {
|
||||
if (do_cr) output[op++] = '\r';
|
||||
output[op++] = '\n';
|
||||
}
|
||||
} else if (do_newline && op > 0 && count != LINE_GROUPS) {
|
||||
if (do_cr) output[op++] = '\r';
|
||||
output[op++] = '\n';
|
||||
}
|
||||
|
||||
assert tailLen == 0;
|
||||
assert p == len;
|
||||
} else {
|
||||
// Save the leftovers in tail to be consumed on the next
|
||||
// call to encodeInternal.
|
||||
|
||||
if (p == len-1) {
|
||||
tail[tailLen++] = input[p];
|
||||
} else if (p == len-2) {
|
||||
tail[tailLen++] = input[p];
|
||||
tail[tailLen++] = input[p+1];
|
||||
}
|
||||
}
|
||||
|
||||
this.op = op;
|
||||
this.count = count;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private Base64() { } // don't instantiate
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 辅助判断
|
||||
*
|
||||
* @author mty
|
||||
* @date 2013-6-10下午5:50:57
|
||||
*/
|
||||
public class Check {
|
||||
|
||||
public static boolean isEmpty(CharSequence str) {
|
||||
return isNull(str) || str.length() == 0;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Object[] os) {
|
||||
return isNull(os) || os.length == 0;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Collection<?> l) {
|
||||
return isNull(l) || l.isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Map<?, ?> m) {
|
||||
return isNull(m) || m.isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isNull(Object o) {
|
||||
return o == null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
|
||||
/**
|
||||
* <!-- 手电筒 -->
|
||||
* Call requires API level 5
|
||||
* <uses-permission android:name="android.permission.FLASHLIGHT"/>
|
||||
* <uses-permission android:name="android.permission.CAMERA"/>
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2014-11-04
|
||||
*/
|
||||
public class FlashLight {
|
||||
|
||||
private Camera camera;
|
||||
private Handler handler = new Handler();
|
||||
|
||||
/**
|
||||
* 超过3分钟自动关闭,防止损伤硬件
|
||||
*/
|
||||
private static final int OFF_TIME = 3 * 60 * 1000;
|
||||
|
||||
public boolean turnOnFlashLight() {
|
||||
if (camera == null) {
|
||||
camera = Camera.open();
|
||||
camera.startPreview();
|
||||
Camera.Parameters parameter = camera.getParameters();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
|
||||
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
|
||||
} else {
|
||||
parameter.set("flash-mode", "torch");
|
||||
}
|
||||
camera.setParameters(parameter);
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
turnOffFlashLight();
|
||||
}
|
||||
}, OFF_TIME);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean turnOffFlashLight() {
|
||||
if (camera != null) {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
Camera.Parameters parameter = camera.getParameters();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
|
||||
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
|
||||
} else {
|
||||
parameter.set("flash-mode", "off");
|
||||
}
|
||||
camera.setParameters(parameter);
|
||||
camera.stopPreview();
|
||||
camera.release();
|
||||
camera = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* <!-- 解锁 -->
|
||||
* require <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2014-12-12
|
||||
*/
|
||||
public class KeyguardLock {
|
||||
KeyguardManager keyguardManager;
|
||||
KeyguardManager.KeyguardLock keyguardLock;
|
||||
|
||||
public KeyguardLock(Context context, String tag) {
|
||||
//获取系统服务
|
||||
keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
//初始化键盘锁,可以锁定或解开键盘锁
|
||||
keyguardLock = keyguardManager.newKeyguardLock(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call requires API level 16
|
||||
*/
|
||||
public boolean isKeyguardLocked() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
Log.e("Log : ", "can not call isKeyguardLocked if SDK_INT < 16 ");
|
||||
return false;
|
||||
} else {
|
||||
return keyguardManager.isKeyguardLocked();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Call requires API level 16
|
||||
*/
|
||||
public boolean isKeyguardSecure() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
Log.e("Log : ", "can not call isKeyguardSecure if SDK_INT < 16 ");
|
||||
return false;
|
||||
} else {
|
||||
return keyguardManager.isKeyguardSecure();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean inKeyguardRestrictedInputMode() {
|
||||
return keyguardManager.inKeyguardRestrictedInputMode();
|
||||
}
|
||||
|
||||
public void disableKeyguard() {
|
||||
keyguardLock.disableKeyguard();
|
||||
}
|
||||
|
||||
public void reenableKeyguard() {
|
||||
keyguardLock.reenableKeyguard();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if (keyguardLock != null) {
|
||||
//禁用显示键盘锁定
|
||||
keyguardLock.reenableKeyguard();
|
||||
}
|
||||
}
|
||||
|
||||
public KeyguardManager getKeyguardManager() {
|
||||
return keyguardManager;
|
||||
}
|
||||
|
||||
public void setKeyguardManager(KeyguardManager keyguardManager) {
|
||||
this.keyguardManager = keyguardManager;
|
||||
}
|
||||
|
||||
public KeyguardManager.KeyguardLock getKeyguardLock() {
|
||||
return keyguardLock;
|
||||
}
|
||||
|
||||
public void setKeyguardLock(KeyguardManager.KeyguardLock keyguardLock) {
|
||||
this.keyguardLock = keyguardLock;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* assist us in sensing state of the networks.
|
||||
*
|
||||
* need <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
*
|
||||
* 半夜了,研究了一下Android的Network方面,发现网上有些文章理解的是不对的。
|
||||
* 以下方法是我研究得出的结论和方法,如有误也感谢指出。
|
||||
*
|
||||
* @author MaTianyu
|
||||
* 2014-1-8上午 00:33:11
|
||||
*/
|
||||
public class Network {
|
||||
private static final String TAG = Network.class.getSimpleName();
|
||||
|
||||
public enum NetType {
|
||||
None(1),
|
||||
Mobile(2),
|
||||
Wifi(4),
|
||||
Other(8);
|
||||
|
||||
NetType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value;
|
||||
}
|
||||
|
||||
public enum NetWorkType {
|
||||
UnKnown(-1),
|
||||
Wifi(1),
|
||||
Net2G(2),
|
||||
Net3G(3),
|
||||
Net4G(4);
|
||||
|
||||
NetWorkType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value;
|
||||
}
|
||||
//
|
||||
//public enum NetSubType {
|
||||
// None(1),
|
||||
// Mobile(2),
|
||||
// Wifi(4),
|
||||
// Other(8);
|
||||
//
|
||||
// NetType(int value) {
|
||||
// this.value = value;
|
||||
// }
|
||||
//
|
||||
// public int value;
|
||||
//}
|
||||
|
||||
/**
|
||||
* 获取ConnectivityManager
|
||||
*/
|
||||
public static ConnectivityManager getConnectivityManager(Context context) {
|
||||
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ConnectivityManager
|
||||
*/
|
||||
public static TelephonyManager getTelephonyManager(Context context) {
|
||||
return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断网络连接是否有效(此时可传输数据)。
|
||||
*
|
||||
* @return boolean 不管wifi,还是mobile net,只有当前在连接状态(可有效传输数据)才返回true,反之false。
|
||||
*/
|
||||
public static boolean isConnected(Context context) {
|
||||
NetworkInfo net = getConnectivityManager(context).getActiveNetworkInfo();
|
||||
return net != null && net.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断有无网络正在连接中(查找网络、校验、获取IP等)。
|
||||
*
|
||||
* @return boolean 不管wifi,还是mobile net,只有当前在连接状态(可有效传输数据)才返回true,反之false。
|
||||
*/
|
||||
public static boolean isConnectedOrConnecting(Context context) {
|
||||
NetworkInfo[] nets = getConnectivityManager(context).getAllNetworkInfo();
|
||||
if (nets != null) {
|
||||
for (NetworkInfo net : nets) {
|
||||
if (net.isConnectedOrConnecting()) { return true; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static NetType getConnectedType(Context context) {
|
||||
NetworkInfo net = getConnectivityManager(context).getActiveNetworkInfo();
|
||||
if (net != null) {
|
||||
switch (net.getType()) {
|
||||
case ConnectivityManager.TYPE_WIFI:
|
||||
return NetType.Wifi;
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
return NetType.Mobile;
|
||||
default:
|
||||
return NetType.Other;
|
||||
}
|
||||
}
|
||||
return NetType.None;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在有效的WIFI连接
|
||||
*/
|
||||
public static boolean isWifiConnected(Context context) {
|
||||
NetworkInfo net = getConnectivityManager(context).getActiveNetworkInfo();
|
||||
return net != null && net.getType() == ConnectivityManager.TYPE_WIFI && net.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在有效的移动连接
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isMobileConnected(Context context) {
|
||||
NetworkInfo net = getConnectivityManager(context).getActiveNetworkInfo();
|
||||
return net != null && net.getType() == ConnectivityManager.TYPE_MOBILE && net.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测网络是否为可用状态
|
||||
*/
|
||||
public static boolean isAvailable(Context context) {
|
||||
return isWifiAvailable(context) || (isMobileAvailable(context) && isMobileEnabled(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有可用状态的Wifi,以下情况返回false:
|
||||
* 1. 设备wifi开关关掉;
|
||||
* 2. 已经打开飞行模式;
|
||||
* 3. 设备所在区域没有信号覆盖;
|
||||
* 4. 设备在漫游区域,且关闭了网络漫游。
|
||||
*
|
||||
* @return boolean wifi为可用状态(不一定成功连接,即Connected)即返回ture
|
||||
*/
|
||||
public static boolean isWifiAvailable(Context context) {
|
||||
NetworkInfo[] nets = getConnectivityManager(context).getAllNetworkInfo();
|
||||
if (nets != null) {
|
||||
for (NetworkInfo net : nets) {
|
||||
if (net.getType() == ConnectivityManager.TYPE_WIFI) { return net.isAvailable(); }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断有无可用状态的移动网络,注意关掉设备移动网络直接不影响此函数。
|
||||
* 也就是即使关掉移动网络,那么移动网络也可能是可用的(彩信等服务),即返回true。
|
||||
* 以下情况它是不可用的,将返回false:
|
||||
* 1. 设备打开飞行模式;
|
||||
* 2. 设备所在区域没有信号覆盖;
|
||||
* 3. 设备在漫游区域,且关闭了网络漫游。
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isMobileAvailable(Context context) {
|
||||
NetworkInfo[] nets = getConnectivityManager(context).getAllNetworkInfo();
|
||||
if (nets != null) {
|
||||
for (NetworkInfo net : nets) {
|
||||
if (net.getType() == ConnectivityManager.TYPE_MOBILE) { return net.isAvailable(); }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备是否打开移动网络开关
|
||||
*
|
||||
* @return boolean 打开移动网络返回true,反之false
|
||||
*/
|
||||
public static boolean isMobileEnabled(Context context) {
|
||||
try {
|
||||
Method getMobileDataEnabledMethod = ConnectivityManager.class.getDeclaredMethod("getMobileDataEnabled");
|
||||
getMobileDataEnabledMethod.setAccessible(true);
|
||||
return (Boolean) getMobileDataEnabledMethod.invoke(getConnectivityManager(context));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 反射失败,默认开启
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印当前各种网络状态
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean printNetworkInfo(Context context) {
|
||||
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
if (connectivity != null) {
|
||||
NetworkInfo in = connectivity.getActiveNetworkInfo();
|
||||
Log.i(TAG, "-------------$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$-------------");
|
||||
Log.i(TAG, "getActiveNetworkInfo: " + in);
|
||||
NetworkInfo[] info = connectivity.getAllNetworkInfo();
|
||||
if (info != null) {
|
||||
for (int i = 0; i < info.length; i++) {
|
||||
// if (info[i].getType() == ConnectivityManager.TYPE_WIFI) {
|
||||
Log.i(TAG, "NetworkInfo[" + i + "]isAvailable : " + info[i].isAvailable());
|
||||
Log.i(TAG, "NetworkInfo[" + i + "]isConnected : " + info[i].isConnected());
|
||||
Log.i(TAG, "NetworkInfo[" + i + "]isConnectedOrConnecting : " + info[i].isConnectedOrConnecting());
|
||||
Log.i(TAG, "NetworkInfo[" + i + "]: " + info[i]);
|
||||
// }
|
||||
}
|
||||
Log.i(TAG, "\n");
|
||||
} else {
|
||||
Log.i(TAG, "getAllNetworkInfo is null");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get connected network type by {@link ConnectivityManager}
|
||||
*
|
||||
* such as WIFI, MOBILE, ETHERNET, BLUETOOTH, etc.
|
||||
*
|
||||
* @return {@link ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_MOBILE},
|
||||
* {@link ConnectivityManager#TYPE_ETHERNET}...
|
||||
*/
|
||||
public static int getConnectedTypeINT(Context context) {
|
||||
NetworkInfo net = getConnectivityManager(context).getActiveNetworkInfo();
|
||||
if (net != null) {
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "NetworkInfo: " + net.toString());
|
||||
}
|
||||
return net.getType();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* get network type by {@link TelephonyManager}
|
||||
*
|
||||
* such as 2G, 3G, 4G, etc.
|
||||
*
|
||||
* @return {@link TelephonyManager#NETWORK_TYPE_CDMA}, {@link TelephonyManager#NETWORK_TYPE_GPRS},
|
||||
* {@link TelephonyManager#NETWORK_TYPE_LTE}...
|
||||
*/
|
||||
public static int getTelNetworkTypeINT(Context context) {
|
||||
return getTelephonyManager(context).getNetworkType();
|
||||
}
|
||||
|
||||
/**
|
||||
* GPRS 2G(2.5) General Packet Radia Service 114kbps
|
||||
* EDGE 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
|
||||
* UMTS 3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
|
||||
* CDMA 2G 电信 Code Division Multiple Access 码分多址
|
||||
* EVDO_0 3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
|
||||
* EVDO_A 3G 1.8mbps - 3.1mbps 属于3G过渡,3.5G
|
||||
* 1xRTT 2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
|
||||
* HSDPA 3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
|
||||
* HSUPA 3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
|
||||
* HSPA 3G (分HSDPA,HSUPA) High Speed Packet Access
|
||||
* IDEN 2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 (属于2G,来自维基百科)
|
||||
* EVDO_B 3G EV-DO Rev.B 14.7Mbps 下行 3.5G
|
||||
* LTE 4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡,升级版 LTE Advanced 才是4G
|
||||
* EHRPD 3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
|
||||
* HSPAP 3G HSPAP 比 HSDPA 快些
|
||||
*
|
||||
* @return {@link NetWorkType}
|
||||
*/
|
||||
public static NetWorkType getNetworkType(Context context) {
|
||||
int type = getConnectedTypeINT(context);
|
||||
switch (type) {
|
||||
case ConnectivityManager.TYPE_WIFI:
|
||||
return NetWorkType.Wifi;
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
case ConnectivityManager.TYPE_MOBILE_DUN:
|
||||
case ConnectivityManager.TYPE_MOBILE_HIPRI:
|
||||
case ConnectivityManager.TYPE_MOBILE_MMS:
|
||||
case ConnectivityManager.TYPE_MOBILE_SUPL:
|
||||
int teleType = getTelephonyManager(context).getNetworkType();
|
||||
switch (teleType) {
|
||||
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||
case TelephonyManager.NETWORK_TYPE_EDGE:
|
||||
case TelephonyManager.NETWORK_TYPE_CDMA:
|
||||
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
||||
case TelephonyManager.NETWORK_TYPE_IDEN:
|
||||
return NetWorkType.Net2G;
|
||||
case TelephonyManager.NETWORK_TYPE_UMTS:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_0:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_A:
|
||||
case TelephonyManager.NETWORK_TYPE_HSDPA:
|
||||
case TelephonyManager.NETWORK_TYPE_HSUPA:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPA:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_B:
|
||||
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
||||
return NetWorkType.Net3G;
|
||||
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||
return NetWorkType.Net4G;
|
||||
default:
|
||||
return NetWorkType.UnKnown;
|
||||
}
|
||||
default:
|
||||
return NetWorkType.UnKnown;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
import com.litesuits.common.utils.ShellUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* modify form Trinea
|
||||
*
|
||||
* @author trinea
|
||||
* @date 2014-12-10
|
||||
*/
|
||||
public class SilentInstaller {
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* install success.
|
||||
*/
|
||||
public static final int INSTALL_SUCCEEDED = 1;
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the package is already installed.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the package archive file is invalid.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_INVALID_APK = -2;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the URI passed in is invalid.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_INVALID_URI = -3;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the package manager service found that the device didn't have enough storage space to install the app.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* a package is already installed with the same name.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the requested shared user does not exist.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* a previously installed package of the same name has a different signature than the new package (and the old
|
||||
* package's data was not removed).
|
||||
*/
|
||||
public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package is requested a shared user which is already installed on the device and does not have matching
|
||||
* signature.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package uses a shared library that is not available.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package uses a shared library that is not available.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package failed while optimizing and validating its dex files, either because there was not enough storage
|
||||
* or the validation failed.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_DEXOPT = -11;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package failed because the current SDK version is older than that required by the package.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_OLDER_SDK = -12;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package failed because it contains a content provider with the same authority as a provider already
|
||||
* installed in the system.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package failed because the current SDK version is newer than that required by the package.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_NEWER_SDK = -14;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package failed because it has specified that it is a test-only package and the caller has not supplied
|
||||
* the {@link #INSTALL_ALLOW_TEST} flag.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_TEST_ONLY = -15;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the package being installed contains native code, but none that is compatible with the the device's CPU_ABI.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package uses a feature that is not available.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_MISSING_FEATURE = -17;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* a secure container mount point couldn't be accessed on external media.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_CONTAINER_ERROR = -18;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package couldn't be installed in the specified install location.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package couldn't be installed in the specified install location because the media is not available.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package couldn't be installed because the verification timed out.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package couldn't be installed because the verification did not succeed.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the package changed from what the calling program expected.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* the new package is assigned a different UID than it previously held.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_UID_CHANGED = -24;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser was given a path that is not a file, or does not end with the expected '.apk' extension.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser was unable to retrieve the AndroidManifest.xml file.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser encountered an unexpected exception.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser did not find any certificates in the .apk.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser found inconsistent certificates on the files in the .apk.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser encountered a CertificateEncodingException in one of the files in the .apk.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser encountered a bad or missing package name in the manifest.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser encountered a bad shared user id name in the manifest.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser encountered some structural problem in the manifest.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the parser did not find any actionable tags (instrumentation or application) in the manifest.
|
||||
*/
|
||||
public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
|
||||
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* if the system failed to install the package because of system issues.
|
||||
*/
|
||||
public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
|
||||
/**
|
||||
* Installation return code<br/>
|
||||
* other reason
|
||||
*/
|
||||
public static final int INSTALL_FAILED_OTHER = -1000000;
|
||||
|
||||
/**
|
||||
* Uninstall return code<br/>
|
||||
* uninstall success.
|
||||
*/
|
||||
public static final int DELETE_SUCCEEDED = 1;
|
||||
|
||||
/**
|
||||
* Uninstall return code<br/>
|
||||
* uninstall fail if the system failed to delete the package for an unspecified reason.
|
||||
*/
|
||||
public static final int DELETE_FAILED_INTERNAL_ERROR = -1;
|
||||
|
||||
/**
|
||||
* Uninstall return code<br/>
|
||||
* uninstall fail if the system failed to delete the package because it is the active DevicePolicy manager.
|
||||
*/
|
||||
public static final int DELETE_FAILED_DEVICE_POLICY_MANAGER = -2;
|
||||
|
||||
/**
|
||||
* Uninstall return code<br/>
|
||||
* uninstall fail if pcakge name is invalid
|
||||
*/
|
||||
public static final int DELETE_FAILED_INVALID_PACKAGE = -3;
|
||||
|
||||
/**
|
||||
* Uninstall return code<br/>
|
||||
* uninstall fail if permission denied
|
||||
*/
|
||||
public static final int DELETE_FAILED_PERMISSION_DENIED = -4;
|
||||
|
||||
private static final String TAG = SilentInstaller.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* App installation location flags of android system
|
||||
*/
|
||||
public static final int APP_INSTALL_AUTO = 0;
|
||||
public static final int APP_INSTALL_INTERNAL = 1;
|
||||
public static final int APP_INSTALL_EXTERNAL = 2;
|
||||
|
||||
/**
|
||||
* uninstall package and clear data of app silent by root
|
||||
*
|
||||
* @param context
|
||||
* @param packageName package name of app
|
||||
* @return
|
||||
* @see #uninstallSilent(Context, String, boolean)
|
||||
*/
|
||||
public int uninstallSilent(Context context, String packageName) {
|
||||
return uninstallSilent(context, packageName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* uninstall package silent by root
|
||||
* <ul>
|
||||
* <strong>Attentions:</strong>
|
||||
* <li>Don't call this on the ui thread, it may costs some times.</li>
|
||||
* <li>You should add <strong>android.permission.DELETE_PACKAGES</strong> in manifest, so no need to request root
|
||||
* permission, if you are system app.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param context file path of package
|
||||
* @param packageName package name of app
|
||||
* @param isKeepData whether keep the data and cache directories around after package removal
|
||||
* @return <ul>
|
||||
* <li>{@link #DELETE_SUCCEEDED} means uninstall success</li>
|
||||
* <li>{@link #DELETE_FAILED_INTERNAL_ERROR} means internal error</li>
|
||||
* <li>{@link #DELETE_FAILED_INVALID_PACKAGE} means package name error</li>
|
||||
* <li>{@link #DELETE_FAILED_PERMISSION_DENIED} means permission denied</li>
|
||||
*/
|
||||
public int uninstallSilent(Context context, String packageName, boolean isKeepData) {
|
||||
if (packageName == null || packageName.length() == 0) {
|
||||
return DELETE_FAILED_INVALID_PACKAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* if context is system app, don't need root permission, but should add <uses-permission
|
||||
* android:name="android.permission.DELETE_PACKAGES" /> in mainfest
|
||||
**/
|
||||
StringBuilder command = new StringBuilder().append("LD_LIBRARY_PATH=/vendor/lib:/system/lib pm uninstall")
|
||||
.append(isKeepData ? " -k " : " ").append(packageName.replace(" ", "\\ "));
|
||||
ShellUtil.CommandResult commandResult = ShellUtil.execCommand(command.toString(), !isSystemApplication(context), true);
|
||||
if (commandResult.responseMsg != null
|
||||
&& (commandResult.responseMsg.contains("Success") || commandResult.responseMsg.contains("success"))) {
|
||||
return DELETE_SUCCEEDED;
|
||||
}
|
||||
Log.e(TAG,
|
||||
new StringBuilder().append("uninstallSilent successMsg:").append(commandResult.responseMsg)
|
||||
.append(", ErrorMsg:").append(commandResult.errorMsg).toString());
|
||||
if (commandResult.errorMsg == null) {
|
||||
return DELETE_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("Permission denied")) {
|
||||
return DELETE_FAILED_PERMISSION_DENIED;
|
||||
}
|
||||
return DELETE_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* install package silent by root
|
||||
* <ul>
|
||||
* <strong>Attentions:</strong>
|
||||
* <li>Don't call this on the ui thread, it may costs some times.</li>
|
||||
* <li>You should add <strong>android.permission.INSTALL_PACKAGES</strong> in manifest, so no need to request root
|
||||
* permission, if you are system app.</li>
|
||||
* <li>Default pm install params is "-r".</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param context
|
||||
* @param filePath file path of package
|
||||
* @see #installSilent(Context, String, String)
|
||||
*/
|
||||
public int installSilent(Context context, String filePath) {
|
||||
return installSilent(context, filePath, " -r " + getInstallLocationParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* * install package silent by root
|
||||
* <ul>
|
||||
* <strong>Attentions:</strong>
|
||||
* <li>Don't call this on the ui thread, it may costs some times.</li>
|
||||
* <li>You should add <strong>android.permission.INSTALL_PACKAGES</strong> in manifest, so no need to request root
|
||||
* permission, if you are system app.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public int installSilent(Context context, String filePath, String pmParams) {
|
||||
if (filePath == null || filePath.length() == 0) {
|
||||
return INSTALL_FAILED_INVALID_URI;
|
||||
}
|
||||
|
||||
File file = new File(filePath);
|
||||
if (file == null || file.length() <= 0 || !file.exists() || !file.isFile()) {
|
||||
return INSTALL_FAILED_INVALID_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* if context is system app, don't need root permission, but should add <uses-permission
|
||||
* android:name="android.permission.INSTALL_PACKAGES" /> in mainfest
|
||||
**/
|
||||
StringBuilder command = new StringBuilder().append("LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install ")
|
||||
.append(pmParams == null ? "" : pmParams).append(" ").append(filePath.replace(" ", "\\ "));
|
||||
ShellUtil.CommandResult commandResult = ShellUtil.execCommand(command.toString(),
|
||||
!isSystemApplication(context), true);
|
||||
if (commandResult.responseMsg != null
|
||||
&& (commandResult.responseMsg.contains("Success") || commandResult.responseMsg.contains("success"))) {
|
||||
return INSTALL_SUCCEEDED;
|
||||
}
|
||||
|
||||
Log.e(TAG,
|
||||
new StringBuilder().append("installSilent successMsg:").append(commandResult.responseMsg)
|
||||
.append(", ErrorMsg:").append(commandResult.errorMsg).toString());
|
||||
if (commandResult.errorMsg == null) {
|
||||
return INSTALL_FAILED_OTHER;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_ALREADY_EXISTS")) {
|
||||
return INSTALL_FAILED_ALREADY_EXISTS;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_INVALID_APK")) {
|
||||
return INSTALL_FAILED_INVALID_APK;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_INVALID_URI")) {
|
||||
return INSTALL_FAILED_INVALID_URI;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_INSUFFICIENT_STORAGE")) {
|
||||
return INSTALL_FAILED_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_DUPLICATE_PACKAGE")) {
|
||||
return INSTALL_FAILED_DUPLICATE_PACKAGE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_NO_SHARED_USER")) {
|
||||
return INSTALL_FAILED_NO_SHARED_USER;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_UPDATE_INCOMPATIBLE")) {
|
||||
return INSTALL_FAILED_UPDATE_INCOMPATIBLE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_SHARED_USER_INCOMPATIBLE")) {
|
||||
return INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_MISSING_SHARED_LIBRARY")) {
|
||||
return INSTALL_FAILED_MISSING_SHARED_LIBRARY;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_REPLACE_COULDNT_DELETE")) {
|
||||
return INSTALL_FAILED_REPLACE_COULDNT_DELETE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_DEXOPT")) {
|
||||
return INSTALL_FAILED_DEXOPT;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_OLDER_SDK")) {
|
||||
return INSTALL_FAILED_OLDER_SDK;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_CONFLICTING_PROVIDER")) {
|
||||
return INSTALL_FAILED_CONFLICTING_PROVIDER;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_NEWER_SDK")) {
|
||||
return INSTALL_FAILED_NEWER_SDK;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_TEST_ONLY")) {
|
||||
return INSTALL_FAILED_TEST_ONLY;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_CPU_ABI_INCOMPATIBLE")) {
|
||||
return INSTALL_FAILED_CPU_ABI_INCOMPATIBLE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_MISSING_FEATURE")) {
|
||||
return INSTALL_FAILED_MISSING_FEATURE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_CONTAINER_ERROR")) {
|
||||
return INSTALL_FAILED_CONTAINER_ERROR;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_INVALID_INSTALL_LOCATION")) {
|
||||
return INSTALL_FAILED_INVALID_INSTALL_LOCATION;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_MEDIA_UNAVAILABLE")) {
|
||||
return INSTALL_FAILED_MEDIA_UNAVAILABLE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_VERIFICATION_TIMEOUT")) {
|
||||
return INSTALL_FAILED_VERIFICATION_TIMEOUT;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_VERIFICATION_FAILURE")) {
|
||||
return INSTALL_FAILED_VERIFICATION_FAILURE;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_PACKAGE_CHANGED")) {
|
||||
return INSTALL_FAILED_PACKAGE_CHANGED;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_UID_CHANGED")) {
|
||||
return INSTALL_FAILED_UID_CHANGED;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_NOT_APK")) {
|
||||
return INSTALL_PARSE_FAILED_NOT_APK;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_BAD_MANIFEST")) {
|
||||
return INSTALL_PARSE_FAILED_BAD_MANIFEST;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION")) {
|
||||
return INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_NO_CERTIFICATES")) {
|
||||
return INSTALL_PARSE_FAILED_NO_CERTIFICATES;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES")) {
|
||||
return INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING")) {
|
||||
return INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME")) {
|
||||
return INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID")) {
|
||||
return INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_MANIFEST_MALFORMED")) {
|
||||
return INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_PARSE_FAILED_MANIFEST_EMPTY")) {
|
||||
return INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
|
||||
}
|
||||
if (commandResult.errorMsg.contains("INSTALL_FAILED_INTERNAL_ERROR")) {
|
||||
return INSTALL_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
return INSTALL_FAILED_OTHER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前系统安装应用的默认位置
|
||||
*
|
||||
* @return APP_INSTALL_AUTO or APP_INSTALL_INTERNAL or APP_INSTALL_EXTERNAL.
|
||||
*/
|
||||
public int getInstallLocation() {
|
||||
ShellUtil.CommandResult commandResult = ShellUtil.execCommand(
|
||||
"LD_LIBRARY_PATH=/vendor/lib:/system/lib pm get-install-location", false, true);
|
||||
if (commandResult.result == 0 && commandResult.responseMsg != null && commandResult.responseMsg.length() > 0) {
|
||||
try {
|
||||
return Integer.parseInt(commandResult.responseMsg.substring(0, 1));
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return APP_INSTALL_AUTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* get params for pm install location
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getInstallLocationParams() {
|
||||
int location = getInstallLocation();
|
||||
switch (location) {
|
||||
case APP_INSTALL_INTERNAL:
|
||||
return "-f";
|
||||
case APP_INSTALL_EXTERNAL:
|
||||
return "-s";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* /**
|
||||
* whether packageName is system application
|
||||
*/
|
||||
public boolean isSystemApplication(Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
String packageName = context.getPackageName();
|
||||
if (packageManager == null || packageName == null || packageName.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ApplicationInfo app = packageManager.getApplicationInfo(packageName, 0);
|
||||
return (app != null && (app.flags & ApplicationInfo.FLAG_SYSTEM) > 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
|
||||
/**
|
||||
* 时间均值计算器,只能用于单线程计时。
|
||||
*
|
||||
* @author MaTianyu
|
||||
* 2013-12-12上午1:23:19
|
||||
*/
|
||||
public class TimeAverager {
|
||||
/**
|
||||
* 计时器
|
||||
*/
|
||||
private TimeCounter tc = new TimeCounter();
|
||||
/**
|
||||
* 均值器
|
||||
*/
|
||||
private Averager av = new Averager();
|
||||
|
||||
/**
|
||||
* 一个计时开始
|
||||
*/
|
||||
public long start() {
|
||||
return tc.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个计时结束
|
||||
*/
|
||||
public long end() {
|
||||
long time = tc.duration();
|
||||
av.add(time);
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个计时结束,并且启动下次计时。
|
||||
*/
|
||||
public long endAndRestart() {
|
||||
long time = tc.durationRestart();
|
||||
av.add(time);
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* 求全部计时均值
|
||||
*/
|
||||
public Number average() {
|
||||
return av.getAverage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印全部时间值
|
||||
*/
|
||||
public void print() {
|
||||
av.print();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清楚数据
|
||||
*/
|
||||
public void clear() {
|
||||
av.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* Time Counter.
|
||||
*
|
||||
* @author MaTianyu
|
||||
* 2013-12-11下午3:42:28
|
||||
*/
|
||||
public class TimeCounter {
|
||||
|
||||
private static final String TAG = TimeCounter.class.getSimpleName();
|
||||
private long t;
|
||||
|
||||
public TimeCounter() {
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count start.
|
||||
*/
|
||||
public long start() {
|
||||
t = System.currentTimeMillis();
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get duration and restart.
|
||||
*/
|
||||
public long durationRestart() {
|
||||
long now = System.currentTimeMillis();
|
||||
long d = now - t;
|
||||
t = now;
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get duration.
|
||||
*/
|
||||
public long duration() {
|
||||
return System.currentTimeMillis() - t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print duration.
|
||||
*/
|
||||
public void printDuration(String tag) {
|
||||
Log.i(TAG, tag + " : " + duration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Print duration.
|
||||
*/
|
||||
public void printDurationRestart(String tag) {
|
||||
Log.i(TAG, tag + " : " + durationRestart());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* @author 氢一 @http://litesuits.com
|
||||
* @date 2017-05-27
|
||||
*/
|
||||
public class TimeKeeper {
|
||||
private static final String TAG = "TimeKeeper";
|
||||
private long keepTimeMillis;
|
||||
private long startMillis;
|
||||
|
||||
public TimeKeeper(long keepTimeMillis) {
|
||||
this.keepTimeMillis = keepTimeMillis;
|
||||
}
|
||||
|
||||
public long getKeepTimeMillis() {
|
||||
return keepTimeMillis;
|
||||
}
|
||||
|
||||
public TimeKeeper setKeepTimeMillis(long keepTimeMillis) {
|
||||
this.keepTimeMillis = keepTimeMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TimeKeeper printTimeCost(String event) {
|
||||
long costMillis = SystemClock.elapsedRealtime() - startMillis;
|
||||
Log.d(TAG, event + " cost time millis: " + costMillis);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TimeKeeper startNow() {
|
||||
startMillis = SystemClock.elapsedRealtime();
|
||||
return this;
|
||||
}
|
||||
|
||||
public TimeKeeper waitForEnd(OnEndCallback endCallback) {
|
||||
long costMillis = SystemClock.elapsedRealtime() - startMillis;
|
||||
long leftMillis = keepTimeMillis - costMillis;
|
||||
if (leftMillis > 0) {
|
||||
SystemClock.sleep(leftMillis);
|
||||
endCallback.onEnd(costMillis, leftMillis);
|
||||
} else {
|
||||
endCallback.onEnd(costMillis, leftMillis);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public interface OnEndCallback {
|
||||
void onEnd(long costTime, long leftTime);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-07-31
|
||||
*/
|
||||
public class Toastor {
|
||||
|
||||
private Toast mToast;
|
||||
private Context context;
|
||||
|
||||
public Toastor(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
public Toast getSingletonToast(int resId) {
|
||||
if (mToast == null) {
|
||||
mToast = Toast.makeText(context, resId, Toast.LENGTH_SHORT);
|
||||
}else{
|
||||
mToast.setText(resId);
|
||||
}
|
||||
return mToast;
|
||||
}
|
||||
|
||||
public Toast getSingletonToast(String text) {
|
||||
if (mToast == null) {
|
||||
mToast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
|
||||
}else{
|
||||
mToast.setText(text);
|
||||
}
|
||||
return mToast;
|
||||
}
|
||||
|
||||
public Toast getSingleLongToast(int resId) {
|
||||
if (mToast == null) {
|
||||
mToast = Toast.makeText(context, resId, Toast.LENGTH_LONG);
|
||||
}else{
|
||||
mToast.setText(resId);
|
||||
}
|
||||
return mToast;
|
||||
}
|
||||
|
||||
public Toast getSingleLongToast(String text) {
|
||||
if (mToast == null) {
|
||||
mToast = Toast.makeText(context, text, Toast.LENGTH_LONG);
|
||||
}else{
|
||||
mToast.setText(text);
|
||||
}
|
||||
return mToast;
|
||||
}
|
||||
|
||||
public Toast getToast(int resId) {
|
||||
return Toast.makeText(context, resId, Toast.LENGTH_SHORT);
|
||||
}
|
||||
|
||||
public Toast getToast(String text) {
|
||||
return Toast.makeText(context, text, Toast.LENGTH_SHORT);
|
||||
}
|
||||
|
||||
public Toast getLongToast(int resId) {
|
||||
return Toast.makeText(context, resId, Toast.LENGTH_LONG);
|
||||
}
|
||||
|
||||
public Toast getLongToast(String text) {
|
||||
return Toast.makeText(context, text, Toast.LENGTH_LONG);
|
||||
}
|
||||
|
||||
public void showSingletonToast(int resId) {
|
||||
getSingletonToast(resId).show();
|
||||
}
|
||||
|
||||
|
||||
public void showSingletonToast(String text) {
|
||||
getSingletonToast(text).show();
|
||||
}
|
||||
|
||||
public void showSingleLongToast(int resId) {
|
||||
getSingleLongToast(resId).show();
|
||||
}
|
||||
|
||||
|
||||
public void showSingleLongToast(String text) {
|
||||
getSingleLongToast(text).show();
|
||||
}
|
||||
|
||||
public void showToast(int resId) {
|
||||
getToast(resId).show();
|
||||
}
|
||||
|
||||
public void showToast(String text) {
|
||||
getToast(text).show();
|
||||
}
|
||||
|
||||
public void showLongToast(int resId) {
|
||||
getLongToast(resId).show();
|
||||
}
|
||||
|
||||
public void showLongToast(String text) {
|
||||
getLongToast(text).show();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.litesuits.common.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* <!-- 亮屏 -->
|
||||
* require <uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2014-11-04
|
||||
*/
|
||||
public class WakeLock {
|
||||
PowerManager powerManager;
|
||||
PowerManager.WakeLock wakeLock;
|
||||
|
||||
public WakeLock(Context context, String tag) {
|
||||
////获取电源的服务 声明电源管理器
|
||||
powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.FULL_WAKE_LOCK, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call requires API level 7
|
||||
*/
|
||||
public boolean isScreenOn() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ECLAIR_MR1) {
|
||||
Log.e("Log : ", "can not call isScreenOn if SDK_INT < 7 ");
|
||||
return false;
|
||||
} else {
|
||||
return powerManager.isScreenOn();
|
||||
}
|
||||
}
|
||||
|
||||
public void turnScreenOn() {
|
||||
//点亮亮屏
|
||||
Log.i("Log : ", "PowerManager.WakeLock : wakeLock.isHeld: " + wakeLock.isHeld());
|
||||
if (!wakeLock.isHeld()) {
|
||||
Log.i("Log : ", "PowerManager.WakeLock : 点亮屏幕");
|
||||
wakeLock.acquire();
|
||||
}
|
||||
}
|
||||
|
||||
public void turnScreenOff() {
|
||||
//释放亮屏
|
||||
Log.i("Log : ", "PowerManager.WakeLock : wakeLock.isHeld: " + wakeLock.isHeld());
|
||||
if (wakeLock.isHeld()) {
|
||||
Log.i("Log : ", "PowerManager.WakeLock : 灭掉屏幕");
|
||||
try {
|
||||
wakeLock.release();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
try {
|
||||
wakeLock.release();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PowerManager.WakeLock getWakeLock() {
|
||||
return wakeLock;
|
||||
}
|
||||
|
||||
public void setWakeLock(PowerManager.WakeLock wakeLock) {
|
||||
this.wakeLock = wakeLock;
|
||||
}
|
||||
|
||||
public PowerManager getPowerManager() {
|
||||
return powerManager;
|
||||
}
|
||||
|
||||
public void setPowerManager(PowerManager powerManager) {
|
||||
this.powerManager = powerManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2013 litesuits.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.common.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import com.litesuits.android.log.Log;
|
||||
import com.litesuits.common.data.cipher.Cipher;
|
||||
import com.litesuits.common.utils.ByteUtil;
|
||||
import com.litesuits.common.utils.HexUtil;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-7-10
|
||||
*/
|
||||
public class DataKeeper {
|
||||
private SharedPreferences sp;
|
||||
public static final String KEY_PK_HOME = "msg_pk_home";
|
||||
public static final String KEY_PK_NEW = "msg_pk_new";
|
||||
private static final String TAG = DataKeeper.class.getSimpleName();
|
||||
|
||||
public DataKeeper(Context context, String fileName) {
|
||||
sp = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* *************** get ******************
|
||||
*/
|
||||
|
||||
public String get(String key, String defValue) {
|
||||
return sp.getString(key, defValue);
|
||||
}
|
||||
|
||||
public boolean get(String key, boolean defValue) {
|
||||
return sp.getBoolean(key, defValue);
|
||||
}
|
||||
|
||||
public float get(String key, float defValue) {
|
||||
return sp.getFloat(key, defValue);
|
||||
}
|
||||
|
||||
public int getInt(String key, int defValue) {
|
||||
return sp.getInt(key, defValue);
|
||||
}
|
||||
|
||||
public long get(String key, long defValue) {
|
||||
return sp.getLong(key, defValue);
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
return get(key, (Cipher) null);
|
||||
}
|
||||
|
||||
public Object get(String key, Cipher cipher) {
|
||||
try {
|
||||
String hex = get(key, (String) null);
|
||||
if (hex == null) return null;
|
||||
byte[] bytes = HexUtil.decodeHex(hex.toCharArray());
|
||||
if (cipher != null) bytes = cipher.decrypt(bytes);
|
||||
Object obj = ByteUtil.byteToObject(bytes);
|
||||
Log.i(TAG, key + " get: " + obj);
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* *************** put ******************
|
||||
*/
|
||||
public void put(String key, Object ser) {
|
||||
put(key, ser, null);
|
||||
}
|
||||
|
||||
public void put(String key, Object ser, Cipher cipher) {
|
||||
try {
|
||||
Log.i(TAG, key + " put: " + ser);
|
||||
if (ser == null) {
|
||||
sp.edit().remove(key).commit();
|
||||
} else {
|
||||
byte[] bytes = ByteUtil.objectToByte(ser);
|
||||
if (cipher != null) bytes = cipher.encrypt(bytes);
|
||||
put(key, HexUtil.encodeHexStr(bytes));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String key, String value) {
|
||||
if (value == null) {
|
||||
sp.edit().remove(key).commit();
|
||||
} else {
|
||||
sp.edit().putString(key, value).commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String key, boolean value) {
|
||||
sp.edit().putBoolean(key, value).commit();
|
||||
}
|
||||
|
||||
public void put(String key, float value) {
|
||||
sp.edit().putFloat(key, value).commit();
|
||||
}
|
||||
|
||||
public void put(String key, long value) {
|
||||
sp.edit().putLong(key, value).commit();
|
||||
}
|
||||
|
||||
public void putInt(String key, int value) {
|
||||
sp.edit().putInt(key, value).commit();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.litesuits.common.data.cipher;
|
||||
|
||||
|
||||
import com.litesuits.common.assist.Base64;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-7-31
|
||||
*/
|
||||
public class Base64Cipher extends Cipher {
|
||||
private Cipher cipher;
|
||||
|
||||
public Base64Cipher() {
|
||||
}
|
||||
|
||||
public Base64Cipher(Cipher cipher) {
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decrypt(byte[] res) {
|
||||
res = Base64.decode(res, Base64.DEFAULT);
|
||||
if (cipher != null) {
|
||||
res = cipher.decrypt(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encrypt(byte[] res) {
|
||||
if (cipher != null) {
|
||||
res = cipher.encrypt(res);
|
||||
}
|
||||
return Base64.encode(res, Base64.DEFAULT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.litesuits.common.data.cipher;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-7-31
|
||||
*/
|
||||
public abstract class Cipher implements Encrypt,Decrypt{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.litesuits.common.data.cipher;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-7-31
|
||||
*/
|
||||
public interface Decrypt {
|
||||
public byte[] decrypt(byte[] res);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.litesuits.common.data.cipher;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-7-31
|
||||
*/
|
||||
public interface Encrypt {
|
||||
public byte[] encrypt(byte[] res);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.common.io;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Charsets
|
||||
*/
|
||||
public class Charsets {
|
||||
public static Charset toCharset(Charset charset) {
|
||||
return charset == null ? Charset.defaultCharset() : charset;
|
||||
}
|
||||
public static Charset toCharset(String charset) {
|
||||
return charset == null ? Charset.defaultCharset() : Charset.forName(charset);
|
||||
}
|
||||
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
public static final Charset US_ASCII = Charset.forName("US-ASCII");
|
||||
public static final Charset UTF_16 = Charset.forName("UTF-16");
|
||||
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
|
||||
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
|
||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
package com.litesuits.common.io;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-12-05
|
||||
*/
|
||||
public class StringCodingUtils {
|
||||
|
||||
public static byte[] getBytes(String src, Charset charSet) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
|
||||
try {
|
||||
return src.getBytes(charSet.name());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return src.getBytes(charSet);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+357
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.common.io.stream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class implements an output stream in which the data is
|
||||
* written into a byte array. The buffer automatically grows as data
|
||||
* is written to it.
|
||||
* <p>
|
||||
* The data can be retrieved using <code>toByteArray()</code> and
|
||||
* <code>toString()</code>.
|
||||
* <p>
|
||||
* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an <tt>IOException</tt>.
|
||||
* <p>
|
||||
* This is an alternative implementation of the {@link java.io.ByteArrayOutputStream}
|
||||
* class. The original implementation only allocates 32 bytes at the beginning.
|
||||
* As this class is designed for heavy duty it starts at 1024 bytes. In contrast
|
||||
* to the original it doesn't reallocate the whole memory block but allocates
|
||||
* additional buffers. This way no buffers need to be garbage collected and
|
||||
* the contents don't have to be copied to the new buffer. This class is
|
||||
* designed to behave exactly like the original. The only exception is the
|
||||
* deprecated toString(int) method that has been ignored.
|
||||
*
|
||||
* @version $Id: ByteArrayOutputStream.java 1304052 2012-03-22 20:55:29Z ggregory $
|
||||
*/
|
||||
public class ByteArrayOutputStream extends OutputStream {
|
||||
|
||||
/** A singleton empty byte array. */
|
||||
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
|
||||
/** The list of buffers, which grows and never reduces. */
|
||||
private final List<byte[]> buffers = new ArrayList<byte[]>();
|
||||
/** The index of the current buffer. */
|
||||
private int currentBufferIndex;
|
||||
/** The total count of bytes in all the filled buffers. */
|
||||
private int filledBufferSum;
|
||||
/** The current buffer. */
|
||||
private byte[] currentBuffer;
|
||||
/** The total count of bytes written. */
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* Creates a new byte array output stream. The buffer capacity is
|
||||
* initially 1024 bytes, though its size increases if necessary.
|
||||
*/
|
||||
public ByteArrayOutputStream() {
|
||||
this(1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new byte array output stream, with a buffer capacity of
|
||||
* the specified size, in bytes.
|
||||
*
|
||||
* @param size the initial size
|
||||
* @throws IllegalArgumentException if size is negative
|
||||
*/
|
||||
public ByteArrayOutputStream(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Negative initial size: " + size);
|
||||
}
|
||||
synchronized (this) {
|
||||
needNewBuffer(size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a new buffer available either by allocating
|
||||
* a new one or re-cycling an existing one.
|
||||
*
|
||||
* @param newcount the size of the buffer if one is created
|
||||
*/
|
||||
private void needNewBuffer(int newcount) {
|
||||
if (currentBufferIndex < buffers.size() - 1) {
|
||||
//Recycling old buffer
|
||||
filledBufferSum += currentBuffer.length;
|
||||
|
||||
currentBufferIndex++;
|
||||
currentBuffer = buffers.get(currentBufferIndex);
|
||||
} else {
|
||||
//Creating new buffer
|
||||
int newBufferSize;
|
||||
if (currentBuffer == null) {
|
||||
newBufferSize = newcount;
|
||||
filledBufferSum = 0;
|
||||
} else {
|
||||
newBufferSize = Math.max(
|
||||
currentBuffer.length << 1,
|
||||
newcount - filledBufferSum);
|
||||
filledBufferSum += currentBuffer.length;
|
||||
}
|
||||
|
||||
currentBufferIndex++;
|
||||
currentBuffer = new byte[newBufferSize];
|
||||
buffers.add(currentBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the bytes to byte array.
|
||||
* @param b the bytes to write
|
||||
* @param off The start offset
|
||||
* @param len The number of bytes to write
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
if ((off < 0)
|
||||
|| (off > b.length)
|
||||
|| (len < 0)
|
||||
|| ((off + len) > b.length)
|
||||
|| ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return;
|
||||
}
|
||||
synchronized (this) {
|
||||
int newcount = count + len;
|
||||
int remaining = len;
|
||||
int inBufferPos = count - filledBufferSum;
|
||||
while (remaining > 0) {
|
||||
int part = Math.min(remaining, currentBuffer.length - inBufferPos);
|
||||
System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
|
||||
remaining -= part;
|
||||
if (remaining > 0) {
|
||||
needNewBuffer(newcount);
|
||||
inBufferPos = 0;
|
||||
}
|
||||
}
|
||||
count = newcount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a byte to byte array.
|
||||
* @param b the byte to write
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(int b) {
|
||||
int inBufferPos = count - filledBufferSum;
|
||||
if (inBufferPos == currentBuffer.length) {
|
||||
needNewBuffer(count + 1);
|
||||
inBufferPos = 0;
|
||||
}
|
||||
currentBuffer[inBufferPos] = (byte) b;
|
||||
count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the entire contents of the specified input stream to this
|
||||
* byte stream. Bytes from the input stream are read directly into the
|
||||
* internal buffers of this streams.
|
||||
*
|
||||
* @param in the input stream to read from
|
||||
* @return total number of bytes read from the input stream
|
||||
* (and written to this stream)
|
||||
* @throws java.io.IOException if an I/O error occurs while reading the input stream
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized int write(InputStream in) throws IOException {
|
||||
int readCount = 0;
|
||||
int inBufferPos = count - filledBufferSum;
|
||||
int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
|
||||
while (n != -1) {
|
||||
readCount += n;
|
||||
inBufferPos += n;
|
||||
count += n;
|
||||
if (inBufferPos == currentBuffer.length) {
|
||||
needNewBuffer(currentBuffer.length);
|
||||
inBufferPos = 0;
|
||||
}
|
||||
n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
|
||||
}
|
||||
return readCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current size of the byte array.
|
||||
* @return the current size of the byte array
|
||||
*/
|
||||
public synchronized int size() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an <tt>IOException</tt>.
|
||||
*
|
||||
* @throws java.io.IOException never (this method should not declare this exception
|
||||
* but it has to now due to backwards compatability)
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
//nop
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.io.ByteArrayOutputStream#reset()
|
||||
*/
|
||||
public synchronized void reset() {
|
||||
count = 0;
|
||||
filledBufferSum = 0;
|
||||
currentBufferIndex = 0;
|
||||
currentBuffer = buffers.get(currentBufferIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the entire contents of this byte stream to the
|
||||
* specified output stream.
|
||||
*
|
||||
* @param out the output stream to write to
|
||||
* @throws java.io.IOException if an I/O error occurs, such as if the stream is closed
|
||||
* @see java.io.ByteArrayOutputStream#writeTo(java.io.OutputStream)
|
||||
*/
|
||||
public synchronized void writeTo(OutputStream out) throws IOException {
|
||||
int remaining = count;
|
||||
for (byte[] buf : buffers) {
|
||||
int c = Math.min(buf.length, remaining);
|
||||
out.write(buf, 0, c);
|
||||
remaining -= c;
|
||||
if (remaining == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches entire contents of an <code>InputStream</code> and represent
|
||||
* same data as result InputStream.
|
||||
* <p>
|
||||
* This method is useful where,
|
||||
* <ul>
|
||||
* <li>Source InputStream is slow.</li>
|
||||
* <li>It has network resources associated, so we cannot keep it open for
|
||||
* long time.</li>
|
||||
* <li>It has network timeout associated.</li>
|
||||
* </ul>
|
||||
* It can be used in favor of {@link #toByteArray()}, since it
|
||||
* avoids unnecessary allocation and copy of byte[].<br>
|
||||
* This method buffers the input internally, so there is no need to use a
|
||||
* <code>BufferedInputStream</code>.
|
||||
*
|
||||
* @param input Stream to be fully buffered.
|
||||
* @return A fully buffered stream.
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
* @since 2.0
|
||||
*/
|
||||
public static InputStream toBufferedInputStream(InputStream input)
|
||||
throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
output.write(input);
|
||||
return output.toBufferedInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current contents of this byte stream as a Input Stream. The
|
||||
* returned stream is backed by buffers of <code>this</code> stream,
|
||||
* avoiding memory allocation and copy, thus saving space and time.<br>
|
||||
*
|
||||
* @return the current contents of this output stream.
|
||||
* @see java.io.ByteArrayOutputStream#toByteArray()
|
||||
* @see #reset()
|
||||
* @since 2.0
|
||||
*/
|
||||
private InputStream toBufferedInputStream() {
|
||||
int remaining = count;
|
||||
if (remaining == 0) {
|
||||
return new ClosedInputStream();
|
||||
}
|
||||
List<ByteArrayInputStream> list = new ArrayList<ByteArrayInputStream>(buffers.size());
|
||||
for (byte[] buf : buffers) {
|
||||
int c = Math.min(buf.length, remaining);
|
||||
list.add(new ByteArrayInputStream(buf, 0, c));
|
||||
remaining -= c;
|
||||
if (remaining == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new SequenceInputStream(Collections.enumeration(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the curent contents of this byte stream as a byte array.
|
||||
* The result is independent of this stream.
|
||||
*
|
||||
* @return the current contents of this output stream, as a byte array
|
||||
* @see java.io.ByteArrayOutputStream#toByteArray()
|
||||
*/
|
||||
public synchronized byte[] toByteArray() {
|
||||
int remaining = count;
|
||||
if (remaining == 0) {
|
||||
return EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
byte newbuf[] = new byte[remaining];
|
||||
int pos = 0;
|
||||
for (byte[] buf : buffers) {
|
||||
int c = Math.min(buf.length, remaining);
|
||||
System.arraycopy(buf, 0, newbuf, pos, c);
|
||||
pos += c;
|
||||
remaining -= c;
|
||||
if (remaining == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the curent contents of this byte stream as a string.
|
||||
* @return the contents of the byte array as a String
|
||||
* @see java.io.ByteArrayOutputStream#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the curent contents of this byte stream as a string
|
||||
* using the specified encoding.
|
||||
*
|
||||
* @param enc the name of the character encoding
|
||||
* @return the string converted from the byte array
|
||||
* @throws java.io.UnsupportedEncodingException if the encoding is not supported
|
||||
* @see java.io.ByteArrayOutputStream#toString(String)
|
||||
*/
|
||||
public String toString(String enc) throws UnsupportedEncodingException {
|
||||
return new String(toByteArray(), enc);
|
||||
}
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.common.io.stream;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Closed input stream. This stream returns -1 to all attempts to read
|
||||
* something from the stream.
|
||||
* <p>
|
||||
* Typically uses of this class include testing for corner cases in methods
|
||||
* that accept input streams and acting as a sentinel value instead of a
|
||||
* {@code null} input stream.
|
||||
*
|
||||
* @version $Id: ClosedInputStream.java 1307459 2012-03-30 15:11:44Z ggregory $
|
||||
* @since 1.4
|
||||
*/
|
||||
public class ClosedInputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* A singleton.
|
||||
*/
|
||||
public static final ClosedInputStream CLOSED_INPUT_STREAM = new ClosedInputStream();
|
||||
|
||||
/**
|
||||
* Returns -1 to indicate that the stream is closed.
|
||||
*
|
||||
* @return always -1
|
||||
*/
|
||||
@Override
|
||||
public int read() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.litesuits.common.io.stream;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* {@link java.io.Writer} implementation that outputs to a {@link StringBuilder}.
|
||||
* <p>
|
||||
* <strong>NOTE:</strong> This implementation, as an alternative to
|
||||
* <code>java.io.StringWriter</code>, provides an <i>un-synchronized</i>
|
||||
* (i.e. for use in a single thread) implementation for better performance.
|
||||
* For safe usage with multiple {@link Thread}s then
|
||||
* <code>java.io.StringWriter</code> should be used.
|
||||
*
|
||||
* @version $Id: StringBuilderWriter.java 1304052 2012-03-22 20:55:29Z ggregory $
|
||||
* @since 2.0
|
||||
*/
|
||||
public class StringBuilderWriter extends Writer implements Serializable {
|
||||
|
||||
private final StringBuilder builder;
|
||||
|
||||
/**
|
||||
* Construct a new {@link StringBuilder} instance with default capacity.
|
||||
*/
|
||||
public StringBuilderWriter() {
|
||||
this.builder = new StringBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link StringBuilder} instance with the specified capacity.
|
||||
*
|
||||
* @param capacity The initial capacity of the underlying {@link StringBuilder}
|
||||
*/
|
||||
public StringBuilderWriter(int capacity) {
|
||||
this.builder = new StringBuilder(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance with the specified {@link StringBuilder}.
|
||||
*
|
||||
* @param builder The String builder
|
||||
*/
|
||||
public StringBuilderWriter(StringBuilder builder) {
|
||||
this.builder = builder != null ? builder : new StringBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a single character to this Writer.
|
||||
*
|
||||
* @param value The character to append
|
||||
* @return This writer instance
|
||||
*/
|
||||
@Override
|
||||
public Writer append(char value) {
|
||||
builder.append(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a character sequence to this Writer.
|
||||
*
|
||||
* @param value The character to append
|
||||
* @return This writer instance
|
||||
*/
|
||||
@Override
|
||||
public Writer append(CharSequence value) {
|
||||
builder.append(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a portion of a character sequence to the {@link StringBuilder}.
|
||||
*
|
||||
* @param value The character to append
|
||||
* @param start The index of the first character
|
||||
* @param end The index of the last character + 1
|
||||
* @return This writer instance
|
||||
*/
|
||||
@Override
|
||||
public Writer append(CharSequence value, int start, int end) {
|
||||
builder.append(value, start, end);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closing this writer has no effect.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushing this writer has no effect.
|
||||
*/
|
||||
@Override
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a String to the {@link StringBuilder}.
|
||||
*
|
||||
* @param value The value to write
|
||||
*/
|
||||
@Override
|
||||
public void write(String value) {
|
||||
if (value != null) {
|
||||
builder.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a portion of a character array to the {@link StringBuilder}.
|
||||
*
|
||||
* @param value The value to write
|
||||
* @param offset The index of the first character
|
||||
* @param length The number of characters to write
|
||||
*/
|
||||
@Override
|
||||
public void write(char[] value, int offset, int length) {
|
||||
if (value != null) {
|
||||
builder.append(value, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying builder.
|
||||
*
|
||||
* @return The underlying builder
|
||||
*/
|
||||
public StringBuilder getBuilder() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link StringBuilder#toString()}.
|
||||
*
|
||||
* @return The contents of the String builder.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.litesuits.common.receiver;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import com.litesuits.android.log.Log;
|
||||
import com.litesuits.common.assist.Check;
|
||||
|
||||
/**
|
||||
* <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
* <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
* <p/>
|
||||
* action: android.intent.action.PHONE_STATE; android.intent.action.NEW_OUTGOING_CALL;
|
||||
* <p/>
|
||||
* 去电时:
|
||||
* 未接:phone_state=OFFHOOK;
|
||||
* 挂断:phone_state=IDLE
|
||||
* 来电时:
|
||||
* 未接:phone_state=RINGING
|
||||
* 已接:phone_state=OFFHOOK;
|
||||
* 挂断:phone_state=IDLE
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2015-03-09
|
||||
*/
|
||||
public class PhoneReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = "PhoneReceiver";
|
||||
|
||||
private static final String RINGING = "RINGING";
|
||||
private static final String OFFHOOK = "OFFHOOK";
|
||||
private static final String IDLE = "IDLE";
|
||||
|
||||
private static final String PHONE_STATE = "android.intent.action.PHONE_STATE";
|
||||
private static final String NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
|
||||
private static final String INTENT_STATE = "state";
|
||||
private static final String INTENT_INCOMING_NUMBER = "incoming_number";
|
||||
private PhoneListener phoneListener;
|
||||
private boolean isDialOut;
|
||||
private String number;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "action: " + intent.getAction());
|
||||
Log.d(TAG, "intent : ");
|
||||
Bundle bundle = intent.getExtras();
|
||||
for (String key : bundle.keySet()) {
|
||||
Log.d(TAG, key + " : " + bundle.get(key));
|
||||
}
|
||||
}
|
||||
if (NEW_OUTGOING_CALL.equals(intent.getAction())) {
|
||||
isDialOut = true;
|
||||
String outNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
|
||||
if (!Check.isEmpty(outNumber)) {
|
||||
this.number = outNumber;
|
||||
}
|
||||
if (phoneListener != null) {
|
||||
phoneListener.onPhoneStateChanged(CallState.Outgoing, number);
|
||||
}
|
||||
} else if (PHONE_STATE.equals(intent.getAction())) {
|
||||
String state = intent.getStringExtra(INTENT_STATE);
|
||||
String inNumber = intent.getStringExtra(INTENT_INCOMING_NUMBER);
|
||||
if (!Check.isEmpty(inNumber)) {
|
||||
this.number = inNumber;
|
||||
}
|
||||
if (RINGING.equals(state)) {
|
||||
isDialOut = false;
|
||||
if (phoneListener != null) {
|
||||
phoneListener.onPhoneStateChanged(CallState.IncomingRing, number);
|
||||
}
|
||||
} else if (OFFHOOK.equals(state)) {
|
||||
if (!isDialOut && phoneListener != null) {
|
||||
phoneListener.onPhoneStateChanged(CallState.Incoming, number);
|
||||
}
|
||||
} else if (IDLE.equals(state)) {
|
||||
if (isDialOut) {
|
||||
if (phoneListener != null) {
|
||||
phoneListener.onPhoneStateChanged(CallState.OutgoingEnd, number);
|
||||
}
|
||||
} else {
|
||||
if (phoneListener != null) {
|
||||
phoneListener.onPhoneStateChanged(CallState.IncomingEnd, number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 去电时:
|
||||
* 未接:phone_state=OFFHOOK;
|
||||
* 挂断:phone_state=IDLE
|
||||
* 来电时:
|
||||
* 未接:phone_state=RINGING
|
||||
* 已接:phone_state=OFFHOOK;
|
||||
* 挂断:phone_state=IDLE
|
||||
*/
|
||||
//public void registerCallStateListener(Context context, PhoneStateListener listener) {
|
||||
// try {
|
||||
// //获取电话通讯服务
|
||||
// TelephonyManager tpm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
// tpm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//}
|
||||
public void registerReceiver(Context context, PhoneListener phoneListener) {
|
||||
try {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("android.intent.action.PHONE_STATE");
|
||||
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
|
||||
filter.setPriority(Integer.MAX_VALUE);
|
||||
context.registerReceiver(this, filter);
|
||||
this.phoneListener = phoneListener;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterReceiver(Context context) {
|
||||
try {
|
||||
context.unregisterReceiver(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public interface PhoneListener {
|
||||
void onPhoneStateChanged(CallState state, String number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分别是:
|
||||
* <p/>
|
||||
* 播出电话
|
||||
* 播出电话结束
|
||||
* 接入电话铃响
|
||||
* 接入通话中
|
||||
* 接入通话完毕
|
||||
*/
|
||||
public enum CallState {
|
||||
Outgoing,
|
||||
OutgoingEnd,
|
||||
IncomingRing,
|
||||
Incoming,
|
||||
IncomingEnd
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.litesuits.common.receiver;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
public class ScreenReceiver extends BroadcastReceiver {
|
||||
private String TAG = "ScreenActionReceiver";
|
||||
private ScreenListener screenListener;
|
||||
|
||||
public ScreenReceiver() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action.equals(Intent.ACTION_SCREEN_ON)) {
|
||||
Log.d(TAG, "屏幕解锁广播...");
|
||||
if (screenListener != null) {
|
||||
screenListener.screenOn();
|
||||
}
|
||||
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
Log.d(TAG, "屏幕加锁广播...");
|
||||
if (screenListener != null) {
|
||||
screenListener.screenOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerScreenReceiver(Context context, ScreenListener screenListener) {
|
||||
try {
|
||||
this.screenListener = screenListener;
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
filter.addAction(Intent.ACTION_SCREEN_ON);
|
||||
Log.d(TAG, "注册屏幕解锁、加锁广播接收者...");
|
||||
context.registerReceiver(this, filter);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterScreenReceiver(Context context) {
|
||||
try {
|
||||
context.unregisterReceiver(this);
|
||||
Log.d(TAG, "注销屏幕解锁、加锁广播接收者...");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static interface ScreenListener {
|
||||
public void screenOn();
|
||||
|
||||
public void screenOff();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.litesuits.common.receiver;
|
||||
|
||||
import android.content.*;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Call requires API level 4
|
||||
* <uses-permission android:name="android.permission.RECEIVE_SMS"/>
|
||||
* <p/>
|
||||
* action: android.provider.Telephony.SMS_RECEIVED
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 14-7-23
|
||||
*/
|
||||
public class SmsReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = SmsReceiver.class.getSimpleName();
|
||||
private SmsListener smsListener;
|
||||
|
||||
public SmsReceiver() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
try {
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "收到广播:" + intent.getAction());
|
||||
Bundle bundle = intent.getExtras();
|
||||
for (String key : bundle.keySet()) {
|
||||
Log.i(TAG, key + " : " + bundle.get(key));
|
||||
}
|
||||
}
|
||||
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
|
||||
String fromAddress = null;
|
||||
String serviceCenterAddress = null;
|
||||
if (pdus != null) {
|
||||
String msgBody = "";
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
|
||||
for (Object obj : pdus) {
|
||||
SmsMessage sms = SmsMessage.createFromPdu((byte[]) obj);
|
||||
msgBody += sms.getMessageBody();
|
||||
fromAddress = sms.getOriginatingAddress();
|
||||
serviceCenterAddress = sms.getServiceCenterAddress();
|
||||
|
||||
if (smsListener != null) {
|
||||
smsListener.onMessage(sms);
|
||||
}
|
||||
//Log.i(TAG, "getDisplayMessageBody:" + sms.getDisplayMessageBody());
|
||||
//Log.i(TAG, "getDisplayOriginatingAddress:" + sms.getDisplayOriginatingAddress());
|
||||
//Log.i(TAG, "getEmailBody:" + sms.getEmailBody());
|
||||
//Log.i(TAG, "getEmailFrom:" + sms.getEmailFrom());
|
||||
//Log.i(TAG, "getMessageBody:" + sms.getMessageBody());
|
||||
//Log.i(TAG, "getOriginatingAddress:" + sms.getOriginatingAddress());
|
||||
//Log.i(TAG, "getPseudoSubject:" + sms.getPseudoSubject());
|
||||
//Log.i(TAG, "getServiceCenterAddress:" + sms.getServiceCenterAddress());
|
||||
//Log.i(TAG, "getIndexOnIcc:" + sms.getIndexOnIcc());
|
||||
//Log.i(TAG, "getMessageClass:" + sms.getMessageClass());
|
||||
//Log.i(TAG, "getUserData:" + new String(sms.getUserData()));
|
||||
}
|
||||
}
|
||||
if (smsListener != null) {
|
||||
smsListener.onMessage(msgBody, fromAddress, serviceCenterAddress);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerSmsReceiver(Context context, SmsListener smsListener) {
|
||||
try {
|
||||
this.smsListener = smsListener;
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
|
||||
filter.setPriority(Integer.MAX_VALUE);
|
||||
context.registerReceiver(this, filter);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterSmsReceiver(Context context) {
|
||||
try {
|
||||
context.unregisterReceiver(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class SmsListener {
|
||||
public abstract void onMessage(String msg, String fromAddress, String serviceCenterAddress);
|
||||
|
||||
public void onMessage(SmsMessage msg) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call requires API level 4
|
||||
* <uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
*
|
||||
* @param phone
|
||||
* @param msg
|
||||
*/
|
||||
public static void sendMsgToPhone(String phone, String msg) {
|
||||
Log.i(TAG, "发送手机:" + phone + " ,内容: " + msg);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
|
||||
SmsManager manager = SmsManager.getDefault();
|
||||
List<String> texts = manager.divideMessage(msg);
|
||||
for (String txt : texts) {
|
||||
manager.sendTextMessage(phone, null, txt, null, null);
|
||||
}
|
||||
}else{
|
||||
Log.e(TAG, "发送失败,系统版本低于DONUT," + phone + " ,内容: " + msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Call requires API level 4
|
||||
* <uses-permission android:name="android.permission.WRITE_SMS"/>
|
||||
*
|
||||
* @param context
|
||||
* @param phone
|
||||
* @param msg
|
||||
*/
|
||||
public static void saveMsgToSystem(Context context, String phone, String msg) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("date", System.currentTimeMillis());
|
||||
//阅读状态
|
||||
values.put("read", 0);
|
||||
//1为收 2为发
|
||||
values.put("type", 2);
|
||||
values.put("address", phone);
|
||||
values.put("body", msg);
|
||||
context.getContentResolver().insert(Uri.parse("content://sms/inbox"), values);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.litesuits.common.receiver;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* 时间广播
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2015-03-09
|
||||
*/
|
||||
public class TimeReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = "TimeReceiver";
|
||||
|
||||
private TimeListener timeListener;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "action: " + intent.getAction());
|
||||
Log.d(TAG, "intent : ");
|
||||
Bundle bundle = intent.getExtras();
|
||||
for (String key : bundle.keySet()) {
|
||||
Log.d(TAG, key + " : " + bundle.get(key));
|
||||
}
|
||||
}
|
||||
if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
|
||||
if (timeListener != null) {
|
||||
timeListener.onTimeTick();
|
||||
}
|
||||
} else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
|
||||
if (timeListener != null) {
|
||||
timeListener.onTimeChanged();
|
||||
}
|
||||
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
|
||||
if (timeListener != null) {
|
||||
timeListener.onTimeZoneChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerReceiver(Context context, TimeListener timeListener) {
|
||||
try {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||
filter.addAction(Intent.ACTION_TIME_TICK);
|
||||
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
filter.setPriority(Integer.MAX_VALUE);
|
||||
context.registerReceiver(this, filter);
|
||||
this.timeListener = timeListener;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterReceiver(Context context) {
|
||||
try {
|
||||
context.unregisterReceiver(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static interface TimeListener {
|
||||
/**
|
||||
* 时区改变
|
||||
*/
|
||||
public void onTimeZoneChanged();
|
||||
|
||||
/**
|
||||
* 设置时间
|
||||
*/
|
||||
public void onTimeChanged();
|
||||
|
||||
/**
|
||||
* 每分钟调用
|
||||
*/
|
||||
public void onTimeTick();
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
package com.litesuits.common.service;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* note: VERSION_CODE >= API_18
|
||||
* <p/>
|
||||
* manifest:
|
||||
* <service android:name=".service.NotificationService"
|
||||
* android:label="@string/app_name"
|
||||
* android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
* <intent-filter>
|
||||
* <action android:name="android.service.notification.NotificationListenerService" />
|
||||
* </intent-filter>
|
||||
* </service>
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2015-03-09
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
public class NotificationService extends NotificationListenerService {
|
||||
private static final String TAG = "NotificationService";
|
||||
public static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
|
||||
private static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
|
||||
private static NotificationService self;
|
||||
private static NotificationListener notificationListener;
|
||||
|
||||
/*----------------- 静态方法 -----------------*/
|
||||
public synchronized static void startNotificationService(Context context, NotificationListener notificationListener) {
|
||||
NotificationService.notificationListener = notificationListener;
|
||||
context.startService(new Intent(context, NotificationService.class));
|
||||
}
|
||||
|
||||
public synchronized static void stopNotificationService(Context context) {
|
||||
context.stopService(new Intent(context, NotificationService.class));
|
||||
}
|
||||
|
||||
|
||||
public static void startNotificationListenSettings(Context context) {
|
||||
Intent intent = new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
||||
if(!(context instanceof Activity)) {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static boolean isNotificationListenEnable(Context context) {
|
||||
return isNotificationListenEnable(context, context.getPackageName());
|
||||
}
|
||||
|
||||
public static boolean isNotificationListenEnable(Context context, String pkgName) {
|
||||
final String flat = Settings.Secure.getString(context.getContentResolver(), ENABLED_NOTIFICATION_LISTENERS);
|
||||
if (!TextUtils.isEmpty(flat)) {
|
||||
final String[] names = flat.split(":");
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
final ComponentName cn = ComponentName.unflattenFromString(names[i]);
|
||||
if (cn != null) {
|
||||
if (TextUtils.equals(pkgName, cn.getPackageName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*----------------- 生命周期 -----------------*/
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.i(TAG, "onCreate..");
|
||||
|
||||
if (notificationListener != null) {
|
||||
notificationListener.onServiceCreated(this);
|
||||
}
|
||||
self = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.i(TAG, "onStartCommand..");
|
||||
|
||||
return notificationListener == null ? START_STICKY : notificationListener.onServiceStartCommand(this, intent, flags, startId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.i(TAG, "onDestroy..");
|
||||
|
||||
if (notificationListener != null) {
|
||||
notificationListener.onServiceDestroy();
|
||||
notificationListener = null;
|
||||
}
|
||||
self = null;
|
||||
}
|
||||
|
||||
/*----------------- 通知回调 -----------------*/
|
||||
@Override
|
||||
public void onNotificationPosted(StatusBarNotification sbn) {
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, sbn.toString());
|
||||
Notification notification = sbn.getNotification();
|
||||
Log.i(TAG, "tickerText : " + notification.tickerText);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
Bundle bundle = notification.extras;
|
||||
for (String key : bundle.keySet()) {
|
||||
Log.i(TAG, key + ": " + bundle.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self != null && notificationListener != null) {
|
||||
notificationListener.onNotificationPosted(sbn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onNotificationRemoved(StatusBarNotification sbn) {
|
||||
if (self != null && notificationListener != null) {
|
||||
notificationListener.onNotificationRemoved(sbn);
|
||||
}
|
||||
}
|
||||
|
||||
public void printCurrentNotifications() {
|
||||
StatusBarNotification[] ns = getActiveNotifications();
|
||||
for (StatusBarNotification n : ns) {
|
||||
Log.i(TAG, String.format("%20s",n.getPackageName()) + ": " + n.getNotification().tickerText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static abstract class NotificationListener {
|
||||
public void onServiceCreated(NotificationService service) {}
|
||||
|
||||
public abstract int onServiceStartCommand(NotificationService service, Intent intent, int flags, int startId);
|
||||
|
||||
public void onServiceDestroy() {}
|
||||
|
||||
/**
|
||||
* Implement this method to learn about new notifications as they are posted by apps.
|
||||
*
|
||||
* @param sbn A data structure encapsulating the original {@link android.app.Notification}
|
||||
* object as well as its identifying information (tag and id) and source
|
||||
* (package name).
|
||||
*/
|
||||
public abstract void onNotificationPosted(StatusBarNotification sbn);
|
||||
|
||||
/**
|
||||
* Implement this method to learn when notifications are removed.
|
||||
* <p/>
|
||||
* This might occur because the user has dismissed the notification using system UI (or another
|
||||
* notification listener) or because the app has withdrawn the notification.
|
||||
* <p/>
|
||||
* NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
|
||||
* result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
|
||||
* fields such as {@link android.app.Notification#contentView} and
|
||||
* {@link android.app.Notification#largeIcon}. However, all other fields on
|
||||
* {@link StatusBarNotification}, sufficient to match this call with a prior call to
|
||||
* {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
|
||||
*
|
||||
* @param sbn A data structure encapsulating at least the original information (tag and id)
|
||||
* and source (package name) used to post the {@link android.app.Notification} that
|
||||
* was just removed.
|
||||
*/
|
||||
public abstract void onNotificationRemoved(StatusBarNotification sbn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* @author MaTianyu @http://litesuits.com
|
||||
* @date 2015-08-22
|
||||
*/
|
||||
public class AlarmUtil {
|
||||
/**
|
||||
* 开启定时器
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void startAlarmIntent(Context context, int triggerAtMillis, PendingIntent pendingIntent) {
|
||||
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
manager.set(AlarmManager.RTC_WAKEUP,triggerAtMillis, pendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭定时器
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void stopAlarmIntent(Context context, PendingIntent pendingIntent) {
|
||||
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
manager.cancel(pendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启轮询服务
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void startAlarmService(Context context, int triggerAtMillis, Class<?> cls, String action) {
|
||||
Intent intent = new Intent(context, cls);
|
||||
intent.setAction(action);
|
||||
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
startAlarmIntent(context, triggerAtMillis,pendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止启轮询服务
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void stopAlarmService(Context context, Class<?> cls, String action) {
|
||||
Intent intent = new Intent(context, cls);
|
||||
intent.setAction(action);
|
||||
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
stopAlarmIntent(context, pendingIntent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.litesuits.android.log.Log;
|
||||
import com.litesuits.common.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 手机信息 & MAC地址 & 开机时间
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2014-09-25
|
||||
*/
|
||||
public class AndroidUtil {
|
||||
private static final String TAG = AndroidUtil.class.getSimpleName();
|
||||
//Ethernet Mac Address
|
||||
private static final String ETH0_MAC_ADDRESS = "/sys/class/net/eth0/address";
|
||||
|
||||
/**
|
||||
* 获取 Wifi MAC 地址
|
||||
* <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getMacAddress(Context context) {
|
||||
return getWifiMacAddress(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Wifi MAC 地址
|
||||
* <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
*/
|
||||
public static String getWifiMacAddress(Context context) {
|
||||
//wifi mac地址
|
||||
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
WifiInfo info = wifi.getConnectionInfo();
|
||||
String mac = info.getMacAddress();
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "WIFI MAC:" + mac);
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取 以太网 MAC 地址
|
||||
*/
|
||||
public static String getEthernetMacAddress() {
|
||||
try {
|
||||
String mac = FileUtils.readFileToString(new File(ETH0_MAC_ADDRESS));
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "Ethernet MAC:" + mac);
|
||||
}
|
||||
return mac;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "IO Exception when getting eth0 mac address", e);
|
||||
e.printStackTrace();
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ANDROID_ID
|
||||
*/
|
||||
public static String getAndroidId(Context context) {
|
||||
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "ANDROID_ID :" + androidId);
|
||||
}
|
||||
return androidId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 开机时间
|
||||
*/
|
||||
public static String getBootTimeString() {
|
||||
long ut = SystemClock.elapsedRealtime() / 1000;
|
||||
int h = (int) ((ut / 3600));
|
||||
int m = (int) ((ut / 60) % 60);
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, h + ":" + m);
|
||||
}
|
||||
return h + ":" + m;
|
||||
}
|
||||
|
||||
public static String printSystemInfo() {
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String time = dateFormat.format(date);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("_______ 系统信息 ").append(time).append(" ______________");
|
||||
sb.append("\nID :").append(Build.ID);
|
||||
sb.append("\nBRAND :").append(Build.BRAND);
|
||||
sb.append("\nMODEL :").append(Build.MODEL);
|
||||
sb.append("\nRELEASE :").append(Build.VERSION.RELEASE);
|
||||
sb.append("\nSDK :").append(Build.VERSION.SDK);
|
||||
|
||||
sb.append("\n_______ OTHER _______");
|
||||
sb.append("\nBOARD :").append(Build.BOARD);
|
||||
sb.append("\nPRODUCT :").append(Build.PRODUCT);
|
||||
sb.append("\nDEVICE :").append(Build.DEVICE);
|
||||
sb.append("\nFINGERPRINT :").append(Build.FINGERPRINT);
|
||||
sb.append("\nHOST :").append(Build.HOST);
|
||||
sb.append("\nTAGS :").append(Build.TAGS);
|
||||
sb.append("\nTYPE :").append(Build.TYPE);
|
||||
sb.append("\nTIME :").append(Build.TIME);
|
||||
sb.append("\nINCREMENTAL :").append(Build.VERSION.INCREMENTAL);
|
||||
|
||||
sb.append("\n_______ CUPCAKE-3 _______");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
|
||||
sb.append("\nDISPLAY :").append(Build.DISPLAY);
|
||||
}
|
||||
|
||||
sb.append("\n_______ DONUT-4 _______");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
|
||||
sb.append("\nSDK_INT :").append(Build.VERSION.SDK_INT);
|
||||
sb.append("\nMANUFACTURER :").append(Build.MANUFACTURER);
|
||||
sb.append("\nBOOTLOADER :").append(Build.BOOTLOADER);
|
||||
sb.append("\nCPU_ABI :").append(Build.CPU_ABI);
|
||||
sb.append("\nCPU_ABI2 :").append(Build.CPU_ABI2);
|
||||
sb.append("\nHARDWARE :").append(Build.HARDWARE);
|
||||
sb.append("\nUNKNOWN :").append(Build.UNKNOWN);
|
||||
sb.append("\nCODENAME :").append(Build.VERSION.CODENAME);
|
||||
}
|
||||
|
||||
sb.append("\n_______ GINGERBREAD-9 _______");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
sb.append("\nSERIAL :").append(Build.SERIAL);
|
||||
}
|
||||
Log.i(TAG, sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Process;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-12-10
|
||||
*/
|
||||
public class AppUtil {
|
||||
|
||||
/**
|
||||
* 是否是主进程
|
||||
*/
|
||||
public static boolean isMainProcess(Context context) {
|
||||
String procName = getCurrentProcessName(context);
|
||||
return procName == null || procName.equalsIgnoreCase(context.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前进程名字
|
||||
*/
|
||||
public static String getCurrentProcessName(Context context) {
|
||||
int pid = android.os.Process.myPid();
|
||||
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) {
|
||||
if (appProcess.pid == pid) {
|
||||
return appProcess.processName;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用系统分享
|
||||
*/
|
||||
public static void shareToOtherApp(Context context, String title, String content, String dialogTitle) {
|
||||
Intent intentItem = new Intent(Intent.ACTION_SEND);
|
||||
intentItem.setType("text/plain");
|
||||
intentItem.putExtra(Intent.EXTRA_SUBJECT, title);
|
||||
intentItem.putExtra(Intent.EXTRA_TEXT, content);
|
||||
intentItem.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(Intent.createChooser(intentItem, dialogTitle));
|
||||
}
|
||||
|
||||
/**
|
||||
* need < uses-permission android:name =“android.permission.GET_TASKS” />
|
||||
* 判断是否前台运行
|
||||
*/
|
||||
public static boolean isRunningForeground(Context context) {
|
||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningTaskInfo> taskList = am.getRunningTasks(1);
|
||||
if (taskList != null && !taskList.isEmpty()) {
|
||||
ComponentName componentName = taskList.get(0).topActivity;
|
||||
if (componentName != null && componentName.getPackageName().equals(context.getPackageName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取App包 信息版本号
|
||||
*/
|
||||
public PackageInfo getPackageInfo(Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PackageInfo packageInfo = null;
|
||||
try {
|
||||
packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return packageInfo;
|
||||
}
|
||||
|
||||
public static void killTheApp() {
|
||||
android.os.Process.killProcess(Process.myPid());
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.MediaStore;
|
||||
import com.litesuits.android.log.Log;
|
||||
import com.litesuits.common.assist.Base64;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class BitmapUtil {
|
||||
|
||||
private static final String TAG = BitmapUtil.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* convert Bitmap to byte array
|
||||
*/
|
||||
public static byte[] bitmapToByte(Bitmap b) {
|
||||
ByteArrayOutputStream o = new ByteArrayOutputStream();
|
||||
b.compress(Bitmap.CompressFormat.PNG, 100, o);
|
||||
return o.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* convert byte array to Bitmap
|
||||
*/
|
||||
public static Bitmap byteToBitmap(byte[] b) {
|
||||
return (b == null || b.length == 0) ? null : BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把bitmap转换成Base64编码String
|
||||
*/
|
||||
public static String bitmapToString(Bitmap bitmap) {
|
||||
return Base64.encodeToString(bitmapToByte(bitmap), Base64.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert Drawable to Bitmap
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable) {
|
||||
return drawable == null ? null : ((BitmapDrawable) drawable).getBitmap();
|
||||
}
|
||||
|
||||
/**
|
||||
* convert Bitmap to Drawable
|
||||
*/
|
||||
public static Drawable bitmapToDrawable(Bitmap bitmap) {
|
||||
return bitmap == null ? null : new BitmapDrawable(bitmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* scale image
|
||||
*/
|
||||
public static Bitmap scaleImageTo(Bitmap org, int newWidth, int newHeight) {
|
||||
return scaleImage(org, (float) newWidth / org.getWidth(), (float) newHeight / org.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* scale image
|
||||
*/
|
||||
public static Bitmap scaleImage(Bitmap org, float scaleWidth, float scaleHeight) {
|
||||
if (org == null) {
|
||||
return null;
|
||||
}
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(scaleWidth, scaleHeight);
|
||||
return Bitmap.createBitmap(org, 0, 0, org.getWidth(), org.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
public static Bitmap toRoundCorner(Bitmap bitmap) {
|
||||
int height = bitmap.getHeight();
|
||||
int width = bitmap.getHeight();
|
||||
Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Canvas canvas = new Canvas(output);
|
||||
|
||||
final Paint paint = new Paint();
|
||||
final Rect rect = new Rect(0, 0, width, height);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawARGB(0, 0, 0, 0);
|
||||
//paint.setColor(0xff424242);
|
||||
paint.setColor(Color.TRANSPARENT);
|
||||
canvas.drawCircle(width / 2, height / 2, width / 2, paint);
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas.drawBitmap(bitmap, rect, rect, paint);
|
||||
return output;
|
||||
}
|
||||
|
||||
public static Bitmap createBitmapThumbnail(Bitmap bitMap, boolean needRecycle, int newHeight, int newWidth) {
|
||||
int width = bitMap.getWidth();
|
||||
int height = bitMap.getHeight();
|
||||
// 计算缩放比例
|
||||
float scaleWidth = ((float) newWidth) / width;
|
||||
float scaleHeight = ((float) newHeight) / height;
|
||||
// 取得想要缩放的matrix参数
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(scaleWidth, scaleHeight);
|
||||
// 得到新的图片
|
||||
Bitmap newBitMap = Bitmap.createBitmap(bitMap, 0, 0, width, height, matrix, true);
|
||||
if (needRecycle)
|
||||
bitMap.recycle();
|
||||
return newBitMap;
|
||||
}
|
||||
|
||||
public static boolean saveBitmap(Bitmap bitmap, File file) {
|
||||
if (bitmap == null)
|
||||
return false;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
|
||||
fos.flush();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean saveBitmap(Bitmap bitmap, String absPath) {
|
||||
return saveBitmap(bitmap, new File(absPath));
|
||||
}
|
||||
|
||||
public static Intent buildImageGetIntent(Uri saveTo, int outputX, int outputY, boolean returnData) {
|
||||
return buildImageGetIntent(saveTo, 1, 1, outputX, outputY, returnData);
|
||||
}
|
||||
|
||||
public static Intent buildImageGetIntent(Uri saveTo, int aspectX, int aspectY,
|
||||
int outputX, int outputY, boolean returnData) {
|
||||
Log.i(TAG, "Build.VERSION.SDK_INT : " + Build.VERSION.SDK_INT);
|
||||
Intent intent = new Intent();
|
||||
if (Build.VERSION.SDK_INT < 19) {
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
} else {
|
||||
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
}
|
||||
intent.setType("image/*");
|
||||
intent.putExtra("output", saveTo);
|
||||
intent.putExtra("aspectX", aspectX);
|
||||
intent.putExtra("aspectY", aspectY);
|
||||
intent.putExtra("outputX", outputX);
|
||||
intent.putExtra("outputY", outputY);
|
||||
intent.putExtra("scale", true);
|
||||
intent.putExtra("return-data", returnData);
|
||||
intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildImageCropIntent(Uri uriFrom, Uri uriTo, int outputX, int outputY, boolean returnData) {
|
||||
return buildImageCropIntent(uriFrom, uriTo, 1, 1, outputX, outputY, returnData);
|
||||
}
|
||||
|
||||
public static Intent buildImageCropIntent(Uri uriFrom, Uri uriTo, int aspectX, int aspectY,
|
||||
int outputX, int outputY, boolean returnData) {
|
||||
Intent intent = new Intent("com.android.camera.action.CROP");
|
||||
intent.setDataAndType(uriFrom, "image/*");
|
||||
intent.putExtra("crop", "true");
|
||||
intent.putExtra("output", uriTo);
|
||||
intent.putExtra("aspectX", aspectX);
|
||||
intent.putExtra("aspectY", aspectY);
|
||||
intent.putExtra("outputX", outputX);
|
||||
intent.putExtra("outputY", outputY);
|
||||
intent.putExtra("scale", true);
|
||||
intent.putExtra("return-data", returnData);
|
||||
intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildImageCaptureIntent(Uri uri) {
|
||||
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
|
||||
int h = options.outHeight;
|
||||
int w = options.outWidth;
|
||||
int inSampleSize = 0;
|
||||
if (h > reqHeight || w > reqWidth) {
|
||||
float ratioW = (float) w / reqWidth;
|
||||
float ratioH = (float) h / reqHeight;
|
||||
inSampleSize = (int) Math.min(ratioH, ratioW);
|
||||
}
|
||||
inSampleSize = Math.max(1, inSampleSize);
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
public static Bitmap getSmallBitmap(String filePath, int reqWidth, int reqHeight) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(filePath, options);
|
||||
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
|
||||
options.inJustDecodeBounds = false;
|
||||
return BitmapFactory.decodeFile(filePath, options);
|
||||
}
|
||||
|
||||
public byte[] compressBitmapToBytes(String filePath, int reqWidth, int reqHeight, int quality) {
|
||||
Bitmap bitmap = getSmallBitmap(filePath, reqWidth, reqHeight);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
bitmap.recycle();
|
||||
Log.i(TAG, "Bitmap compressed success, size: " + bytes.length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public byte[] compressBitmapSmallTo(String filePath, int reqWidth, int reqHeight, int maxLenth) {
|
||||
int quality = 100;
|
||||
byte[] bytes = compressBitmapToBytes(filePath, reqWidth, reqHeight, quality);
|
||||
while (bytes.length > maxLenth && quality > 0) {
|
||||
quality = quality / 2;
|
||||
bytes = compressBitmapToBytes(filePath, reqWidth, reqHeight, quality);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public byte[] compressBitmapQuikly(String filePath) {
|
||||
return compressBitmapToBytes(filePath, 480, 800, 50);
|
||||
}
|
||||
|
||||
public byte[] compressBitmapQuiklySmallTo(String filePath, int maxLenth) {
|
||||
return compressBitmapSmallTo(filePath, 480, 800, maxLenth);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-7-31
|
||||
*/
|
||||
public class ByteUtil {
|
||||
/**
|
||||
* byte[] 转为 对象
|
||||
*
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static Object byteToObject(byte[] bytes) throws Exception {
|
||||
ObjectInputStream ois = null;
|
||||
try {
|
||||
ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
|
||||
return ois.readObject();
|
||||
} finally {
|
||||
if (ois != null) ois.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象 转为 byte[]
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public static byte[] objectToByte(Object obj) throws Exception {
|
||||
ObjectOutputStream oos = null;
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(obj);
|
||||
return bos.toByteArray();
|
||||
} finally {
|
||||
if (oos != null) oos.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void byteToBit(byte[] bytes, StringBuilder sb) {
|
||||
for (int i = 0; i < Byte.SIZE * bytes.length; i++)
|
||||
sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
|
||||
}
|
||||
|
||||
public static String byteToBit(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < Byte.SIZE * bytes.length; i++)
|
||||
sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 类工具
|
||||
*
|
||||
* @author mty
|
||||
* @date 2013-6-10下午8:00:46
|
||||
*/
|
||||
public class ClassUtil {
|
||||
|
||||
/**
|
||||
* 判断类是否是基础数据类型
|
||||
* 目前支持11种
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isBaseDataType(Class<?> clazz) {
|
||||
return clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Boolean.class)
|
||||
|| clazz.equals(Integer.class) || clazz.equals(Long.class) || clazz.equals(Float.class)
|
||||
|| clazz.equals(Double.class) || clazz.equals(Byte.class) || clazz.equals(Character.class)
|
||||
|| clazz.equals(Short.class) || clazz.equals(Date.class) || clazz.equals(byte[].class)
|
||||
|| clazz.equals(Byte[].class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类获取对象:不再必须一个无参构造
|
||||
*
|
||||
* @param claxx
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> T newInstance(Class<T> claxx) throws Exception {
|
||||
Constructor<?>[] cons = claxx.getDeclaredConstructors();
|
||||
for (Constructor<?> c : cons) {
|
||||
Class[] cls = c.getParameterTypes();
|
||||
if (cls.length == 0) {
|
||||
c.setAccessible(true);
|
||||
return (T) c.newInstance();
|
||||
} else {
|
||||
Object[] objs = new Object[cls.length];
|
||||
for (int i = 0; i < cls.length; i++) {
|
||||
objs[i] = getDefaultPrimiticeValue(cls[i]);
|
||||
}
|
||||
c.setAccessible(true);
|
||||
return (T) c.newInstance(objs);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getDefaultPrimiticeValue(Class clazz) {
|
||||
if (clazz.isPrimitive()) {
|
||||
return clazz == boolean.class ? false : 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isCollection(Class claxx) {
|
||||
return Collection.class.isAssignableFrom(claxx);
|
||||
}
|
||||
|
||||
public static boolean isArray(Class claxx) {
|
||||
return claxx.isArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* @author MaTianyu @http://litesuits.com
|
||||
* @date 2015-08-25
|
||||
*/
|
||||
public class ClipboardUtil {
|
||||
|
||||
public static void copyToClipboardSupport(Context context, String text) {
|
||||
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context
|
||||
.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text);
|
||||
}
|
||||
|
||||
public static void getLatestTextSupport(Context context) {
|
||||
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context
|
||||
.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
clipboard.getText();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static void copyToClipboard(Context context, String text) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
clipboard.setPrimaryClip(ClipData.newPlainText(null, text));
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static int getItemCount(Context context) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData data = clipboard.getPrimaryClip();
|
||||
return data.getItemCount();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static String getText(Context context, int index) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = clipboard.getPrimaryClip();
|
||||
if (clip != null && clip.getItemCount() > index) {
|
||||
return String.valueOf(clip.getItemAt(0).coerceToText(context));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static String getLatestText(Context context) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = clipboard.getPrimaryClip();
|
||||
if (clip != null && clip.getItemCount() > 0) {
|
||||
return String.valueOf(clip.getItemAt(0).coerceToText(context));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import com.litesuits.android.log.Log;
|
||||
import com.litesuits.common.assist.Check;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Get CPU info.
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2015-04-18
|
||||
*/
|
||||
public class CpuUtil {
|
||||
private static final String TAG = CpuUtil.class.getSimpleName();
|
||||
private static final String CPU_INFO_PATH = "/proc/cpuinfo";
|
||||
private static final String CPU_FREQ_NULL = "N/A";
|
||||
private static final String CMD_CAT = "/system/bin/cat";
|
||||
private static final String CPU_FREQ_CUR_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";
|
||||
private static final String CPU_FREQ_MAX_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
|
||||
private static final String CPU_FREQ_MIN_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq";
|
||||
|
||||
private static String CPU_NAME;
|
||||
private static int CPU_CORES = 0;
|
||||
private static long CPU_MAX_FREQENCY = 0;
|
||||
private static long CPU_MIN_FREQENCY = 0;
|
||||
|
||||
/**
|
||||
* Print cpu info.
|
||||
*/
|
||||
public static String printCpuInfo() {
|
||||
String info = FileUtil.getFileOutputString(CPU_INFO_PATH);
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "_______ CPU : \n" + info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available processors.
|
||||
*/
|
||||
public static int getProcessorsCount() {
|
||||
return Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of cores available in this device, across all processors.
|
||||
* Requires: Ability to peruse the filesystem at "/sys/devices/system/cpu"
|
||||
*
|
||||
* @return The number of cores, or available processors if failed to get result
|
||||
*/
|
||||
public static int getCoresNumbers() {
|
||||
if (CPU_CORES != 0) {
|
||||
return CPU_CORES;
|
||||
}
|
||||
//Private Class to display only CPU devices in the directory listing
|
||||
class CpuFilter implements FileFilter {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
//Check if filename is "cpu", followed by a single digit number
|
||||
if (Pattern.matches("cpu[0-9]+", pathname.getName())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
//Get directory containing CPU info
|
||||
File dir = new File("/sys/devices/system/cpu/");
|
||||
//Filter to only list the devices we care about
|
||||
File[] files = dir.listFiles(new CpuFilter());
|
||||
//Return the number of cores (virtual CPU devices)
|
||||
CPU_CORES = files.length;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (CPU_CORES < 1) {
|
||||
CPU_CORES = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
if (CPU_CORES < 1) {
|
||||
CPU_CORES = 1;
|
||||
}
|
||||
return CPU_CORES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CPU name.
|
||||
*/
|
||||
public static String getCpuName() {
|
||||
if (!Check.isEmpty(CPU_NAME)) {
|
||||
return CPU_NAME;
|
||||
}
|
||||
try {
|
||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(CPU_INFO_PATH), 8192);
|
||||
String line = bufferedReader.readLine();
|
||||
bufferedReader.close();
|
||||
String[] array = line.split(":\\s+", 2);
|
||||
if (array.length > 1) {
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, array[1]);
|
||||
}
|
||||
CPU_NAME = array[1];
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CPU_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current CPU freqency.
|
||||
*/
|
||||
public static long getCurrentFreqency() {
|
||||
try {
|
||||
return Long.parseLong(FileUtil.getFileOutputString(CPU_FREQ_CUR_PATH).trim());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get maximum CPU freqency
|
||||
*/
|
||||
public static long getMaxFreqency() {
|
||||
if (CPU_MAX_FREQENCY > 0) {
|
||||
return CPU_MAX_FREQENCY;
|
||||
}
|
||||
try {
|
||||
CPU_MAX_FREQENCY = Long.parseLong(getCMDOutputString(new String[]{CMD_CAT, CPU_FREQ_MAX_PATH}).trim());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CPU_MAX_FREQENCY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimum frenqency.
|
||||
*/
|
||||
public static long getMinFreqency() {
|
||||
if (CPU_MIN_FREQENCY > 0) {
|
||||
return CPU_MIN_FREQENCY;
|
||||
}
|
||||
try {
|
||||
CPU_MIN_FREQENCY = Long.parseLong(getCMDOutputString(new String[]{CMD_CAT, CPU_FREQ_MIN_PATH}).trim());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CPU_MIN_FREQENCY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get command output string.
|
||||
*/
|
||||
public static String getCMDOutputString(String[] args) {
|
||||
try {
|
||||
ProcessBuilder cmd = new ProcessBuilder(args);
|
||||
Process process = cmd.start();
|
||||
InputStream in = process.getInputStream();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] re = new byte[64];
|
||||
int len;
|
||||
while ((len = in.read(re)) != -1) {
|
||||
sb.append(new String(re, 0, len));
|
||||
}
|
||||
in.close();
|
||||
process.destroy();
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "CMD: " + sb.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
|
||||
public class DialogUtil {
|
||||
|
||||
public static AlertDialog.Builder dialogBuilder(Context context, String title, String msg) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
if (msg != null) {
|
||||
builder.setMessage(msg);
|
||||
}
|
||||
if (title != null) {
|
||||
builder.setTitle(title);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static AlertDialog.Builder dialogBuilder(Context context, String title, String msg, int i) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
if (msg != null) {
|
||||
builder.setMessage(Html.fromHtml(msg));
|
||||
}
|
||||
if (title != null) {
|
||||
builder.setTitle(title);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
public static AlertDialog.Builder dialogBuilder(Context context, int title, View view) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
if (view != null) {
|
||||
builder.setView(view);
|
||||
}
|
||||
if (title > 0) {
|
||||
builder.setTitle(title);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static AlertDialog.Builder dialogBuilder(Context context, int titleResId, int msgResId) {
|
||||
String title = titleResId > 0 ? context.getResources().getString(titleResId) : null;
|
||||
String msg = msgResId > 0 ? context.getResources().getString(msgResId) : null;
|
||||
return dialogBuilder(context, title, msg);
|
||||
}
|
||||
|
||||
public static Dialog showTips(Context context, String title, String des) {
|
||||
return showTips(context, title, des, null, null);
|
||||
}
|
||||
|
||||
public static Dialog showTips(Context context, int title, int des) {
|
||||
return showTips(context, context.getString(title), context.getString(des));
|
||||
}
|
||||
|
||||
public static Dialog showTips(Context context, int title, int des, int btn, DialogInterface.OnDismissListener dismissListener) {
|
||||
return showTips(context, context.getString(title), context.getString(des), context.getString(btn), dismissListener);
|
||||
}
|
||||
|
||||
public static Dialog showTips(Context context, String title, String des, String btn, DialogInterface.OnDismissListener dismissListener) {
|
||||
AlertDialog.Builder builder = dialogBuilder(context, title, des);
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(btn, null);
|
||||
Dialog dialog = builder.show();
|
||||
dialog.setCanceledOnTouchOutside(true);
|
||||
dialog.setOnDismissListener(dismissListener);
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.DisplayMetrics;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2015-04-19
|
||||
*/
|
||||
public class DisplayUtil {
|
||||
private static final String TAG = DisplayUtil.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* 获取 显示信息
|
||||
*/
|
||||
public static DisplayMetrics getDisplayMetrics(Context context) {
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
return dm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印 显示信息
|
||||
*/
|
||||
public static DisplayMetrics printDisplayInfo(Context context) {
|
||||
DisplayMetrics dm = getDisplayMetrics(context);
|
||||
if (Log.isPrint) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("_______ 显示信息: ");
|
||||
sb.append("\ndensity :").append(dm.density);
|
||||
sb.append("\ndensityDpi :").append(dm.densityDpi);
|
||||
sb.append("\nheightPixels :").append(dm.heightPixels);
|
||||
sb.append("\nwidthPixels :").append(dm.widthPixels);
|
||||
sb.append("\nscaledDensity :").append(dm.scaledDensity);
|
||||
sb.append("\nxdpi :").append(dm.xdpi);
|
||||
sb.append("\nydpi :").append(dm.ydpi);
|
||||
Log.i(TAG, sb.toString());
|
||||
}
|
||||
return dm;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 域工具
|
||||
*
|
||||
* @author mty
|
||||
* @date 2013-6-10下午6:36:29
|
||||
*/
|
||||
public class FieldUtil {
|
||||
|
||||
/**
|
||||
* 判断是否序列化
|
||||
*
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static boolean isSerializable(Field f) {
|
||||
Class<?>[] cls = f.getType().getInterfaces();
|
||||
for (Class<?> c : cls) {
|
||||
if (Serializable.class == c) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置域的值
|
||||
*
|
||||
* @param f
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws IllegalAccessException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static Object set(Field f, Object obj, Object value) throws IllegalArgumentException, IllegalAccessException {
|
||||
f.setAccessible(true);
|
||||
f.set(obj, value);
|
||||
return f.get(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取域的值
|
||||
*
|
||||
* @param f
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws IllegalAccessException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static Object get(Field f, Object obj) throws IllegalArgumentException, IllegalAccessException {
|
||||
f.setAccessible(true);
|
||||
return f.get(obj);
|
||||
}
|
||||
|
||||
public static boolean isLong(Field field) {
|
||||
return field.getType() == long.class || field.getType() == Long.class;
|
||||
}
|
||||
|
||||
public static boolean isInteger(Field field) {
|
||||
return field.getType() == int.class || field.getType() != Integer.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取域的泛型类型,如果不带泛型返回null
|
||||
*
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static Class<?> getGenericType(Field f) {
|
||||
Type type = f.getGenericType();
|
||||
if (type instanceof ParameterizedType) {
|
||||
type = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
if (type instanceof Class<?>) return (Class<?>) type;
|
||||
} else if (type instanceof Class<?>) return (Class<?>) type;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组的类型
|
||||
*
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static Class<?> getComponentType(Field f) {
|
||||
return f.getType().getComponentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部Field,包括父类
|
||||
*
|
||||
* @param claxx
|
||||
* @return
|
||||
*/
|
||||
public static List<Field> getAllDeclaredFields(Class<?> claxx) {
|
||||
// find all field.
|
||||
LinkedList<Field> fieldList = new LinkedList<Field>();
|
||||
while (claxx != null && claxx != Object.class) {
|
||||
Field[] fs = claxx.getDeclaredFields();
|
||||
for (int i = 0; i < fs.length; i++) {
|
||||
Field f = fs[i];
|
||||
if (!isInvalid(f)) {
|
||||
fieldList.addLast(f);
|
||||
}
|
||||
}
|
||||
claxx = claxx.getSuperclass();
|
||||
}
|
||||
return fieldList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是静态常量或者内部结构属性
|
||||
*
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInvalid(Field f) {
|
||||
return (Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers())) || f.isSynthetic();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-08-10
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
private static final String TAG = FileUtil.class.getSimpleName();
|
||||
|
||||
public static void fileChannelCopy(File s, File t) {
|
||||
FileInputStream fi = null;
|
||||
FileOutputStream fo = null;
|
||||
try {
|
||||
fi = new FileInputStream(s);
|
||||
fo = new FileOutputStream(t);
|
||||
FileChannel in = fi.getChannel();//得到对应的文件通道
|
||||
FileChannel out = fo.getChannel();//得到对应的文件通道
|
||||
in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (fo != null) fo.close();
|
||||
if (fi != null) fi.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatFileSizeToString(long fileLen) {// 转换文件大小
|
||||
DecimalFormat df = new DecimalFormat("#.00");
|
||||
String fileSizeString = "";
|
||||
if (fileLen < 1024) {
|
||||
fileSizeString = df.format((double) fileLen) + "B";
|
||||
} else if (fileLen < 1048576) {
|
||||
fileSizeString = df.format((double) fileLen / 1024) + "K";
|
||||
} else if (fileLen < 1073741824) {
|
||||
fileSizeString = df.format((double) fileLen / 1048576) + "M";
|
||||
} else {
|
||||
fileSizeString = df.format((double) fileLen / 1073741824) + "G";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
/***
|
||||
* 根据路径删除图片
|
||||
*/
|
||||
public static boolean deleteFile(File file)throws IOException{
|
||||
return file != null && file.delete();
|
||||
}
|
||||
|
||||
/***
|
||||
* 获取文件扩展名
|
||||
* @param filename
|
||||
* @return 返回文件扩展名
|
||||
*/
|
||||
public static String getExtensionName(String filename) {
|
||||
if ((filename != null) && (filename.length() > 0)) {
|
||||
int dot = filename.lastIndexOf('.');
|
||||
if ((dot >-1) && (dot < (filename.length() - 1))) {
|
||||
return filename.substring(dot + 1);
|
||||
}
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取指定文件的输出
|
||||
*/
|
||||
public static String getFileOutputString(String path) {
|
||||
try {
|
||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(path), 8192);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = null;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
sb.append("\n").append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
return sb.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2015-03-12
|
||||
*/
|
||||
public class HandlerUtil {
|
||||
public static final Handler HANDLER = new Handler(Looper.getMainLooper());
|
||||
|
||||
public static void runOnUiThread(Runnable runnable){
|
||||
HANDLER.post(runnable);
|
||||
}
|
||||
|
||||
public static void runOnUiThreadDelay(Runnable runnable, long delayMillis){
|
||||
HANDLER.postDelayed(runnable,delayMillis);
|
||||
}
|
||||
|
||||
public static void removeRunable(Runnable runnable){
|
||||
HANDLER.removeCallbacks(runnable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
/**
|
||||
* reference apache commons <a
|
||||
* href="http://commons.apache.org/codec/">http://commons.apache.org/codec/</a>
|
||||
*
|
||||
* @author Aub
|
||||
*
|
||||
*/
|
||||
public class HexUtil {
|
||||
|
||||
/**
|
||||
* 用于建立十六进制字符的输出的小写字符数组
|
||||
*/
|
||||
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
/**
|
||||
* 用于建立十六进制字符的输出的大写字符数组
|
||||
*/
|
||||
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符数组
|
||||
*
|
||||
* @param data
|
||||
* byte[]
|
||||
* @return 十六进制char[]
|
||||
*/
|
||||
public static char[] encodeHex(byte[] data) {
|
||||
return encodeHex(data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符数组
|
||||
*
|
||||
* @param data
|
||||
* byte[]
|
||||
* @param toLowerCase
|
||||
* <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
|
||||
* @return 十六进制char[]
|
||||
*/
|
||||
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
|
||||
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符数组
|
||||
*
|
||||
* @param data
|
||||
* byte[]
|
||||
* @param toDigits
|
||||
* 用于控制输出的char[]
|
||||
* @return 十六进制char[]
|
||||
*/
|
||||
protected static char[] encodeHex(byte[] data, char[] toDigits) {
|
||||
int l = data.length;
|
||||
char[] out = new char[l << 1];
|
||||
// two characters form the hex value.
|
||||
for (int i = 0, j = 0; i < l; i++) {
|
||||
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
|
||||
out[j++] = toDigits[0x0F & data[i]];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param data
|
||||
* byte[]
|
||||
* @return 十六进制String
|
||||
*/
|
||||
public static String encodeHexStr(byte[] data) {
|
||||
return encodeHexStr(data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param data
|
||||
* byte[]
|
||||
* @param toLowerCase
|
||||
* <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
|
||||
* @return 十六进制String
|
||||
*/
|
||||
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
|
||||
return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串
|
||||
*
|
||||
* @param data
|
||||
* byte[]
|
||||
* @param toDigits
|
||||
* 用于控制输出的char[]
|
||||
* @return 十六进制String
|
||||
*/
|
||||
protected static String encodeHexStr(byte[] data, char[] toDigits) {
|
||||
return new String(encodeHex(data, toDigits));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符数组转换为字节数组
|
||||
*
|
||||
* @param data
|
||||
* 十六进制char[]
|
||||
* @return byte[]
|
||||
* @throws RuntimeException
|
||||
* 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
|
||||
*/
|
||||
public static byte[] decodeHex(char[] data) {
|
||||
|
||||
int len = data.length;
|
||||
|
||||
if ((len & 0x01) != 0) {
|
||||
throw new RuntimeException("Odd number of characters.");
|
||||
}
|
||||
|
||||
byte[] out = new byte[len >> 1];
|
||||
|
||||
// two characters form the hex value.
|
||||
for (int i = 0, j = 0; j < len; i++) {
|
||||
int f = toDigit(data[j], j) << 4;
|
||||
j++;
|
||||
f = f | toDigit(data[j], j);
|
||||
j++;
|
||||
out[i] = (byte) (f & 0xFF);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十六进制字符转换成一个整数
|
||||
*
|
||||
* @param ch
|
||||
* 十六进制char
|
||||
* @param index
|
||||
* 十六进制字符在字符数组中的位置
|
||||
* @return 一个整数
|
||||
* @throws RuntimeException
|
||||
* 当ch不是一个合法的十六进制字符时,抛出运行时异常
|
||||
*/
|
||||
protected static int toDigit(char ch, int index) {
|
||||
int digit = Character.digit(ch, 16);
|
||||
if (digit == -1) {
|
||||
throw new RuntimeException("Illegal hexadecimal character " + ch
|
||||
+ " at index " + index);
|
||||
}
|
||||
return digit;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String srcStr = "待转换字符串";
|
||||
String encodeStr = encodeHexStr(srcStr.getBytes());
|
||||
String decodeStr = new String(decodeHex(encodeStr.toCharArray()));
|
||||
System.out.println("转换前:" + srcStr);
|
||||
System.out.println("转换后:" + encodeStr);
|
||||
System.out.println("还原后:" + decodeStr);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
/**
|
||||
* @author MaTianyu(http://litesuits.com) on 2015-06-01
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public class InputMethodUtils {
|
||||
|
||||
public static void toggleSoftInput(Context context) {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
|
||||
public static boolean showSoftInput(View view) {
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
|
||||
}
|
||||
|
||||
public static boolean showSoftInput(Activity activity) {
|
||||
View view = activity.getCurrentFocus();
|
||||
if (view != null) {
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
|
||||
Context.INPUT_METHOD_SERVICE);
|
||||
return imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hideSoftInput(View view) {
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
public static boolean hideSoftInput(Activity activity) {
|
||||
if (activity.getCurrentFocus() != null) {
|
||||
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isActive(Context context) {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return imm.isActive();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* MS5
|
||||
*/
|
||||
public class MD5Util {
|
||||
private static final String TAG = MD5Util.class.getSimpleName();
|
||||
private static final int STREAM_BUFFER_LENGTH = 1024;
|
||||
|
||||
public static MessageDigest getDigest(final String algorithm) throws NoSuchAlgorithmException {
|
||||
return MessageDigest.getInstance(algorithm);
|
||||
}
|
||||
|
||||
public static byte[] md5(String txt) {
|
||||
return md5(txt.getBytes());
|
||||
}
|
||||
|
||||
public static byte[] md5(byte[] bytes) {
|
||||
try {
|
||||
MessageDigest digest = getDigest("MD5");
|
||||
digest.update(bytes);
|
||||
return digest.digest();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] md5(InputStream is) throws NoSuchAlgorithmException, IOException {
|
||||
return updateDigest(getDigest("MD5"), is).digest();
|
||||
}
|
||||
|
||||
public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
|
||||
final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
|
||||
int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
|
||||
|
||||
while (read > -1) {
|
||||
digest.update(buffer, 0, read);
|
||||
read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
|
||||
}
|
||||
|
||||
return digest;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.format.Formatter;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
/**
|
||||
* Get memory info.
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2015-04-19
|
||||
*/
|
||||
public class MemoryUtil {
|
||||
private static final String TAG = MemoryUtil.class.getSimpleName();
|
||||
private static final String MEM_INFO_PATH = "/proc/meminfo";
|
||||
|
||||
/**
|
||||
* Print memory info. such as:
|
||||
*
|
||||
* MemTotal: 1864292 kB
|
||||
* MemFree: 779064 kB
|
||||
* Buffers: 4540 kB
|
||||
* Cached: 185656 kB
|
||||
* SwapCached: 13160 kB
|
||||
* Active: 435588 kB
|
||||
* Inactive: 269312 kB
|
||||
* Active(anon): 386188 kB
|
||||
* Inactive(anon): 132576 kB
|
||||
* Active(file): 49400 kB
|
||||
* Inactive(file): 136736 kB
|
||||
* Unevictable: 2420 kB
|
||||
* Mlocked: 0 kB
|
||||
* HighTotal: 1437692 kB
|
||||
* HighFree: 520212 kB
|
||||
* LowTotal: 426600 kB
|
||||
* LowFree: 258852 kB
|
||||
* SwapTotal: 511996 kB
|
||||
* SwapFree: 171876 kB
|
||||
* Dirty: 412 kB
|
||||
* Writeback: 0 kB
|
||||
* AnonPages: 511924 kB
|
||||
* Mapped: 152368 kB
|
||||
* Shmem: 1636 kB
|
||||
* Slab: 109224 kB
|
||||
* SReclaimable: 75932 kB
|
||||
* SUnreclaim: 33292 kB
|
||||
* KernelStack: 13056 kB
|
||||
* PageTables: 28032 kB
|
||||
* NFS_Unstable: 0 kB
|
||||
* Bounce: 0 kB
|
||||
* WritebackTmp: 0 kB
|
||||
* CommitLimit: 1444140 kB
|
||||
* Committed_AS: 25977748 kB
|
||||
* VmallocTotal: 458752 kB
|
||||
* VmallocUsed: 123448 kB
|
||||
* VmallocChunk: 205828 kB
|
||||
*/
|
||||
public static String printMemInfo() {
|
||||
String info = FileUtil.getFileOutputString(MEM_INFO_PATH);
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, "_______ 内存信息: \n" + info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get memory info of device.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static ActivityManager.MemoryInfo getMemoryInfo(Context context) {
|
||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
|
||||
am.getMemoryInfo(mi);
|
||||
return mi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print Memory info.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static ActivityManager.MemoryInfo printMemoryInfo(Context context) {
|
||||
ActivityManager.MemoryInfo mi = getMemoryInfo(context);
|
||||
if (Log.isPrint) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("_______ Memory : ");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
sb.append("\ntotalMem :").append(mi.totalMem);
|
||||
}
|
||||
sb.append("\navailMem :").append(mi.availMem);
|
||||
sb.append("\nlowMemory :").append(mi.lowMemory);
|
||||
sb.append("\nthreshold :").append(mi.threshold);
|
||||
Log.i(TAG, sb.toString());
|
||||
}
|
||||
return mi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available memory info.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static String getAvailMemory(Context context) {// 获取android当前可用内存大小
|
||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
|
||||
am.getMemoryInfo(mi);
|
||||
// mi.availMem; 当前系统的可用内存
|
||||
return Formatter.formatFileSize(context, mi.availMem);// 将获取的内存大小规格化
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-11-19
|
||||
*/
|
||||
public class NotificationUtil {
|
||||
private static int LedID = 0;
|
||||
private static final String TAG = NotificationUtil.class.getSimpleName();
|
||||
|
||||
public static void notification(Context context, Uri uri,
|
||||
int icon, String ticker, String title, String msg) {
|
||||
Log.i(TAG, "notiry uri :" + uri);
|
||||
// 设置通知的事件消息
|
||||
Intent intent = new Intent();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
|
||||
intent.setPackage(context.getPackageName());
|
||||
}
|
||||
intent.setData(uri);
|
||||
notification(context, intent, 0, icon, ticker, title, msg);
|
||||
}
|
||||
|
||||
public static void notification(Context context, String activityClass, Bundle bundle,
|
||||
int icon, String ticker, String title, String msg) {
|
||||
// 设置通知的事件消息
|
||||
Intent intent = new Intent();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
|
||||
intent.setPackage(context.getPackageName());
|
||||
}
|
||||
intent.putExtras(bundle);
|
||||
intent.setComponent(new ComponentName(context.getPackageName(), activityClass));
|
||||
notification(context, intent, 0, icon, ticker, title, msg);
|
||||
}
|
||||
|
||||
public static void notification(Context context, Intent intent, int id,
|
||||
int icon, String ticker, String title, String msg) {
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
notification(context, pendingIntent, id, icon, ticker, title, msg);
|
||||
}
|
||||
|
||||
public static void notification(Context context, PendingIntent pendingIntent, int id,
|
||||
int icon, String ticker, String title, String msg) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
Notification.Builder builder = new Notification.Builder(context);
|
||||
builder.setSmallIcon(icon);
|
||||
|
||||
builder.setContentTitle(title);
|
||||
builder.setTicker(ticker);
|
||||
builder.setContentText(msg);
|
||||
|
||||
builder.setDefaults(Notification.DEFAULT_SOUND);
|
||||
builder.setLights(0xFFFFFF00, 0, 2000);
|
||||
builder.setVibrate(new long[]{0, 100, 300});
|
||||
builder.setAutoCancel(true);
|
||||
builder.setContentIntent(pendingIntent);
|
||||
Notification baseNF;
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
baseNF = builder.getNotification();
|
||||
} else {
|
||||
baseNF = builder.build();
|
||||
}
|
||||
//发出状态栏通知
|
||||
NotificationManager nm = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
|
||||
nm.notify(id, baseNF);
|
||||
}
|
||||
}
|
||||
|
||||
public static void lightLed(Context context, int colorOx, int durationMS) {
|
||||
lightLed(context, colorOx, 0, durationMS);
|
||||
}
|
||||
|
||||
public static void lightLed(Context context, int colorOx, int startOffMS, int durationMS) {
|
||||
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
Notification notification = new Notification();
|
||||
notification.ledARGB = colorOx;
|
||||
notification.ledOffMS = startOffMS;
|
||||
notification.ledOnMS = durationMS;
|
||||
notification.flags = Notification.FLAG_SHOW_LIGHTS;
|
||||
LedID++;
|
||||
nm.notify(LedID, notification);
|
||||
nm.cancel(LedID);
|
||||
}
|
||||
|
||||
public static void lightLed(final Context context, final int colorOx, final int startOffMS, final int durationMS,
|
||||
int repeat) {
|
||||
if (repeat < 1) {
|
||||
repeat = 1;
|
||||
}
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
lightLed(context, colorOx, startOffMS, durationMS);
|
||||
}
|
||||
}, (startOffMS + durationMS) * i);
|
||||
}
|
||||
}
|
||||
|
||||
public static void lightLed(Context context, ArrayList<LightPattern> patterns) {
|
||||
if (patterns == null) {
|
||||
return;
|
||||
}
|
||||
for (LightPattern lp : patterns) {
|
||||
lightLed(context, lp.argb, lp.startOffMS, lp.durationMS);
|
||||
}
|
||||
}
|
||||
|
||||
public static class LightPattern {
|
||||
public int argb = 0;
|
||||
public int startOffMS = 0;
|
||||
public int durationMS = 0;
|
||||
|
||||
public LightPattern(int argb, int startOffMS, int durationMS) {
|
||||
this.argb = argb;
|
||||
this.startOffMS = startOffMS;
|
||||
this.durationMS = durationMS;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2014-11-21
|
||||
*/
|
||||
public class NumberUtil {
|
||||
|
||||
public static int convertToint(String intStr, int defValue) {
|
||||
try {
|
||||
return Integer.parseInt(intStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static long convertTolong(String longStr, long defValue) {
|
||||
try {
|
||||
return Long.parseLong(longStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static float convertTofloat(String fStr, float defValue) {
|
||||
try {
|
||||
return Float.parseFloat(fStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static double convertTodouble(String dStr, double defValue) {
|
||||
try {
|
||||
return Double.parseDouble(dStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
|
||||
public static Integer convertToInteger(String intStr) {
|
||||
try {
|
||||
return Integer.parseInt(intStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Long convertToLong(String longStr) {
|
||||
try {
|
||||
return Long.parseLong(longStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Float convertToFloat(String fStr) {
|
||||
try {
|
||||
return Float.parseFloat(fStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Double convertToDouble(String dStr) {
|
||||
try {
|
||||
return Double.parseDouble(dStr);
|
||||
} catch (NumberFormatException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.widget.Toast;
|
||||
import com.litesuits.common.assist.Check;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 14-11-7
|
||||
*/
|
||||
public class PackageUtil {
|
||||
/**
|
||||
* App installation location flags of android system
|
||||
*/
|
||||
public static final int APP_INSTALL_AUTO = 0;
|
||||
public static final int APP_INSTALL_INTERNAL = 1;
|
||||
public static final int APP_INSTALL_EXTERNAL = 2;
|
||||
|
||||
/**
|
||||
* 调用系统安装应用
|
||||
*/
|
||||
public static boolean install(Context context, File file) {
|
||||
if (file == null || !file.exists() || !file.isFile()) {
|
||||
return false;
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用系统卸载应用
|
||||
*/
|
||||
public static void uninstallApk(Context context, String packageName) {
|
||||
Intent intent = new Intent(Intent.ACTION_DELETE);
|
||||
Uri packageURI = Uri.parse("package:" + packageName);
|
||||
intent.setData(packageURI);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开已安装应用的详情
|
||||
*/
|
||||
public static void goToInstalledAppDetails(Context context, String packageName) {
|
||||
Intent intent = new Intent();
|
||||
int sdkVersion = Build.VERSION.SDK_INT;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.fromParts("package", packageName, null));
|
||||
} else {
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
|
||||
intent.putExtra((sdkVersion == Build.VERSION_CODES.FROYO ? "pkg"
|
||||
: "com.android.settings.ApplicationPkgName"), packageName);
|
||||
}
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定程序信息
|
||||
*/
|
||||
public static ActivityManager.RunningTaskInfo getTopRunningTask(Context context) {
|
||||
try {
|
||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
// 得到当前正在运行的任务栈
|
||||
List<ActivityManager.RunningTaskInfo> runningTasks = am.getRunningTasks(1);
|
||||
// 得到前台显示的任务栈
|
||||
ActivityManager.RunningTaskInfo runningTaskInfo = runningTasks.get(0);
|
||||
return runningTaskInfo;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getAppVersionName(Context context) {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
|
||||
return pi.versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int getAppVersionCode(Context context) {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
|
||||
return pi.versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前系统安装应用的默认位置
|
||||
*
|
||||
* @return APP_INSTALL_AUTO or APP_INSTALL_INTERNAL or APP_INSTALL_EXTERNAL.
|
||||
*/
|
||||
public static int getInstallLocation() {
|
||||
ShellUtil.CommandResult commandResult = ShellUtil.execCommand(
|
||||
"LD_LIBRARY_PATH=/vendor/lib:/system/lib pm get-install-location", false, true);
|
||||
if (commandResult.result == 0 && commandResult.responseMsg != null && commandResult.responseMsg.length() > 0) {
|
||||
try {
|
||||
return Integer.parseInt(commandResult.responseMsg.substring(0, 1));
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return APP_INSTALL_AUTO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get app package info
|
||||
*/
|
||||
public static PackageInfo getAppPackageInfo(Context context) {
|
||||
if (context != null) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
if (pm != null) {
|
||||
PackageInfo pi;
|
||||
try {
|
||||
return pm.getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* whether context is system application
|
||||
*/
|
||||
public static boolean isSystemApplication(Context context) {
|
||||
if (context == null) {
|
||||
return false;
|
||||
}
|
||||
return isSystemApplication(context, context.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* whether packageName is system application
|
||||
*/
|
||||
public static boolean isSystemApplication(Context context, String packageName) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
if (packageManager == null || packageName == null || packageName.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ApplicationInfo app = packageManager.getApplicationInfo(packageName, 0);
|
||||
return (app != null && (app.flags & ApplicationInfo.FLAG_SYSTEM) > 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已安装的全部应用信息
|
||||
*/
|
||||
public static List<PackageInfo> getInsatalledPackages(Context context) {
|
||||
return context.getPackageManager().getInstalledPackages(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已安装的全部应用信息
|
||||
*/
|
||||
public static boolean isInsatalled(Context context, String pkg) {
|
||||
if (!Check.isEmpty(pkg)) {
|
||||
List<PackageInfo> list = getInsatalledPackages(context);
|
||||
if (!Check.isEmpty(list)) {
|
||||
for (PackageInfo pi : list) {
|
||||
if (pkg.equalsIgnoreCase(pi.packageName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定程序信息
|
||||
*/
|
||||
public static ApplicationInfo getApplicationInfo(Context context, String pkg) {
|
||||
try {
|
||||
return context.getPackageManager().getApplicationInfo(pkg, 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定程序信息
|
||||
*/
|
||||
public static android.content.pm.PackageInfo getPackageInfo(Context context, String pkg) {
|
||||
try {
|
||||
return context.getPackageManager().getPackageInfo(pkg, 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动应用
|
||||
*/
|
||||
public static boolean startAppByPackageName(Context context, String packageName) {
|
||||
return startAppByPackageName(context, packageName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动应用
|
||||
*/
|
||||
public static boolean startAppByPackageName(Context context, String packageName, Map<String, String> param) {
|
||||
android.content.pm.PackageInfo pi = null;
|
||||
try {
|
||||
pi = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
|
||||
resolveIntent.setPackage(pi.packageName);
|
||||
}
|
||||
|
||||
List<ResolveInfo> apps = context.getPackageManager().queryIntentActivities(resolveIntent, 0);
|
||||
|
||||
ResolveInfo ri = apps.iterator().next();
|
||||
if (ri != null) {
|
||||
String packageName1 = ri.activityInfo.packageName;
|
||||
String className = ri.activityInfo.name;
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
ComponentName cn = new ComponentName(packageName1, className);
|
||||
|
||||
intent.setComponent(cn);
|
||||
if (param != null) {
|
||||
for (Map.Entry<String, String> en : param.entrySet()) {
|
||||
intent.putExtra(en.getKey(), en.getValue());
|
||||
}
|
||||
}
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context.getApplicationContext(), "启动失败",
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
|
||||
/**
|
||||
* @author MaTianyu
|
||||
* @date 2015-03-26
|
||||
*/
|
||||
public class PollingUtil {
|
||||
|
||||
/**
|
||||
* 开启轮询
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void startPolling(Context context, int mills, PendingIntent pendingIntent) {
|
||||
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
manager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),
|
||||
mills, pendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止轮询
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void stopPolling(Context context, PendingIntent pendingIntent) {
|
||||
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
manager.cancel(pendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启轮询服务
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void startPollingService(Context context, int mills, Class<?> cls, String action) {
|
||||
Intent intent = new Intent(context, cls);
|
||||
intent.setAction(action);
|
||||
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
startPolling(context, mills, pendingIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止启轮询服务
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.CUPCAKE)
|
||||
public static void stopPollingService(Context context, Class<?> cls, String action) {
|
||||
Intent intent = new Intent(context, cls);
|
||||
intent.setAction(action);
|
||||
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
stopPolling(context, pendingIntent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 随机工具类
|
||||
* modified form Trinea
|
||||
* @author trinea
|
||||
* @date 2014-12-10
|
||||
*/
|
||||
public class RandomUtil {
|
||||
public static final String NUMBERS_AND_LETTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
public static final String NUMBERS = "0123456789";
|
||||
public static final String LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
public static final String CAPITAL_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
public static final String LOWER_CASE_LETTERS = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
private RandomUtil() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of uppercase, lowercase letters and numbers
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
* @see RandomUtil#getRandom(String source, int length)
|
||||
*/
|
||||
public static String getRandomNumbersAndLetters(int length) {
|
||||
return getRandom(NUMBERS_AND_LETTERS, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of numbers
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
* @see RandomUtil#getRandom(String source, int length)
|
||||
*/
|
||||
public static String getRandomNumbers(int length) {
|
||||
return getRandom(NUMBERS, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of uppercase and lowercase letters
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
* @see RandomUtil#getRandom(String source, int length)
|
||||
*/
|
||||
public static String getRandomLetters(int length) {
|
||||
return getRandom(LETTERS, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of uppercase letters
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
* @see RandomUtil#getRandom(String source, int length)
|
||||
*/
|
||||
public static String getRandomCapitalLetters(int length) {
|
||||
return getRandom(CAPITAL_LETTERS, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of lowercase letters
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
* @see RandomUtil#getRandom(String source, int length)
|
||||
*/
|
||||
public static String getRandomLowerCaseLetters(int length) {
|
||||
return getRandom(LOWER_CASE_LETTERS, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of chars in source
|
||||
*
|
||||
* @param source
|
||||
* @param length
|
||||
* @return <ul>
|
||||
* <li>if source is null or empty, return null</li>
|
||||
* <li>else see {@link RandomUtil#getRandom(char[] sourceChar, int length)}</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static String getRandom(String source, int length) {
|
||||
return source == null ? null : getRandom(source.toCharArray(), length);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a fixed-length random string, its a mixture of chars in sourceChar
|
||||
*
|
||||
* @param sourceChar
|
||||
* @param length
|
||||
* @return <ul>
|
||||
* <li>if sourceChar is null or empty, return null</li>
|
||||
* <li>if length less than 0, return null</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static String getRandom(char[] sourceChar, int length) {
|
||||
if (sourceChar == null || sourceChar.length == 0 || length < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder str = new StringBuilder(length);
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < length; i++) {
|
||||
str.append(sourceChar[random.nextInt(sourceChar.length)]);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* get random int between 0 and max
|
||||
*
|
||||
* @param max
|
||||
* @return <ul>
|
||||
* <li>if max <= 0, return 0</li>
|
||||
* <li>else return random int between 0 and max</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static int getRandom(int max) {
|
||||
return getRandom(0, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* get random int between min and max
|
||||
*
|
||||
* @param min
|
||||
* @param max
|
||||
* @return <ul>
|
||||
* <li>if min > max, return 0</li>
|
||||
* <li>if min == max, return min</li>
|
||||
* <li>else return random int between min and max</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static int getRandom(int min, int max) {
|
||||
if (min > max) {
|
||||
return 0;
|
||||
}
|
||||
if (min == max) {
|
||||
return min;
|
||||
}
|
||||
return min + new Random().nextInt(max - min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffling algorithm, Randomly permutes the specified array using a default source of randomness
|
||||
*/
|
||||
public static boolean shuffle(Object[] objArray) {
|
||||
if (objArray == null) {
|
||||
return false;
|
||||
}
|
||||
return shuffle(objArray, getRandom(objArray.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffling algorithm, Randomly permutes the specified array
|
||||
*/
|
||||
public static boolean shuffle(Object[] objArray, int shuffleCount) {
|
||||
int length;
|
||||
if (objArray == null || shuffleCount < 0 || (length = objArray.length) < shuffleCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= shuffleCount; i++) {
|
||||
int random = getRandom(length - i);
|
||||
Object temp = objArray[length - i];
|
||||
objArray[length - i] = objArray[random];
|
||||
objArray[random] = temp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffling algorithm, Randomly permutes the specified int array using a default source of randomness
|
||||
*/
|
||||
public static int[] shuffle(int[] intArray) {
|
||||
if (intArray == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return shuffle(intArray, getRandom(intArray.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffling algorithm, Randomly permutes the specified int array
|
||||
*/
|
||||
public static int[] shuffle(int[] intArray, int shuffleCount) {
|
||||
int length;
|
||||
if (intArray == null || shuffleCount < 0 || (length = intArray.length) < shuffleCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int[] out = new int[shuffleCount];
|
||||
for (int i = 1; i <= shuffleCount; i++) {
|
||||
int random = getRandom(length - i);
|
||||
out[i - 1] = intArray[random];
|
||||
int temp = intArray[length - i];
|
||||
intArray[length - i] = intArray[random];
|
||||
intArray[random] = temp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Get SD card info.
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2015-04-19
|
||||
*/
|
||||
public class SdCardUtil {
|
||||
private static final String TAG = SdCardUtil.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* is sd card available.
|
||||
* @return true if available
|
||||
*/
|
||||
public boolean isSdCardAvailable() {
|
||||
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link android.os.StatFs}.
|
||||
*/
|
||||
public static StatFs getStatFs(String path) {
|
||||
return new StatFs(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get phone data path.
|
||||
*/
|
||||
public static String getDataPath() {
|
||||
return Environment.getDataDirectory().getPath();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SD card path.
|
||||
*/
|
||||
public static String getNormalSDCardPath() {
|
||||
return Environment.getExternalStorageDirectory().getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SD card path by CMD.
|
||||
*/
|
||||
public static String getSDCardPath() {
|
||||
String cmd = "cat /proc/mounts";
|
||||
String sdcard = null;
|
||||
Runtime run = Runtime.getRuntime();// 返回与当前 Java 应用程序相关的运行时对象
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process p = run.exec(cmd);// 启动另一个进程来执行命令
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(p.getInputStream())));
|
||||
String lineStr;
|
||||
while ((lineStr = bufferedReader.readLine()) != null) {
|
||||
Log.i(TAG, "proc/mounts: " + lineStr);
|
||||
if (lineStr.contains("sdcard")
|
||||
&& lineStr.contains(".android_secure")) {
|
||||
String[] strArray = lineStr.split(" ");
|
||||
if (strArray.length >= 5) {
|
||||
sdcard = strArray[1].replace("/.android_secure", "");
|
||||
Log.i(TAG, "find sd card path: " + sdcard);
|
||||
return sdcard;
|
||||
}
|
||||
}
|
||||
if (p.waitFor() != 0 && p.exitValue() == 1) {
|
||||
// p.exitValue()==0表示正常结束,1:非正常结束
|
||||
Log.e(TAG, cmd + " 命令执行失败");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (bufferedReader != null) {
|
||||
bufferedReader.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
sdcard = Environment.getExternalStorageDirectory().getPath();
|
||||
Log.i(TAG, "not find sd card path return default: " + sdcard);
|
||||
return sdcard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SD card path list.
|
||||
*/
|
||||
public static ArrayList<String> getSDCardPathEx() {
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
try {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Process proc = runtime.exec("mount");
|
||||
InputStream is = proc.getInputStream();
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
String line;
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
while ((line = br.readLine()) != null) {
|
||||
Log.i(TAG, "mount: " + line);
|
||||
if (line.contains("secure")) {
|
||||
continue;
|
||||
}
|
||||
if (line.contains("asec")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.contains("fat")) {
|
||||
String columns[] = line.split(" ");
|
||||
if (columns.length > 1) {
|
||||
list.add("*" + columns[1]);
|
||||
}
|
||||
} else if (line.contains("fuse")) {
|
||||
String columns[] = line.split(" ");
|
||||
if (columns.length > 1) {
|
||||
list.add(columns[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available size of SD card.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
public static long getAvailableSize(String path) {
|
||||
try {
|
||||
File base = new File(path);
|
||||
StatFs stat = new StatFs(base.getPath());
|
||||
return stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SD card info detail.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
public static SDCardInfo getSDCardInfo() {
|
||||
SDCardInfo sd = new SDCardInfo();
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (Environment.MEDIA_MOUNTED.equals(state)) {
|
||||
sd.isExist = true;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
File sdcardDir = Environment.getExternalStorageDirectory();
|
||||
StatFs sf = new StatFs(sdcardDir.getPath());
|
||||
|
||||
sd.totalBlocks = sf.getBlockCountLong();
|
||||
sd.blockByteSize = sf.getBlockSizeLong();
|
||||
|
||||
sd.availableBlocks = sf.getAvailableBlocksLong();
|
||||
sd.availableBytes = sf.getAvailableBytes();
|
||||
|
||||
sd.freeBlocks = sf.getFreeBlocksLong();
|
||||
sd.freeBytes = sf.getFreeBytes();
|
||||
|
||||
sd.totalBytes = sf.getTotalBytes();
|
||||
}
|
||||
}
|
||||
if (Log.isPrint) {
|
||||
Log.i(TAG, sd.toString());
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* see more {@link android.os.StatFs}
|
||||
*/
|
||||
public static class SDCardInfo {
|
||||
public boolean isExist;
|
||||
public long totalBlocks;
|
||||
public long freeBlocks;
|
||||
public long availableBlocks;
|
||||
|
||||
public long blockByteSize;
|
||||
|
||||
public long totalBytes;
|
||||
public long freeBytes;
|
||||
public long availableBytes;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SDCardInfo{" +
|
||||
"isExist=" + isExist +
|
||||
", totalBlocks=" + totalBlocks +
|
||||
", freeBlocks=" + freeBlocks +
|
||||
", availableBlocks=" + availableBlocks +
|
||||
", blockByteSize=" + blockByteSize +
|
||||
", totalBytes=" + totalBytes +
|
||||
", freeBytes=" + freeBytes +
|
||||
", availableBytes=" + availableBytes +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* modified form Trinea
|
||||
* @author trinea
|
||||
* @date 2014-12-10
|
||||
*/
|
||||
public class ShellUtil {
|
||||
|
||||
/**
|
||||
* check whether has root permission
|
||||
*/
|
||||
public static boolean hasRootPermission() {
|
||||
return execCommand("echo root", true, false).result == 0;
|
||||
}
|
||||
|
||||
public static CommandResult execCommand(String command, boolean isRoot) {
|
||||
return execCommand(new String[] {command}, isRoot, true);
|
||||
}
|
||||
|
||||
public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(new String[]{command}, isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands
|
||||
* {@link CommandResult#result} is -1, there maybe some excepiton.
|
||||
*
|
||||
* @param commands command array
|
||||
* @param isRoot whether need to run with root
|
||||
* @param needResponse whether need result msg
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot, boolean needResponse) {
|
||||
int result = -1;
|
||||
if (commands == null || commands.length == 0) {
|
||||
return new CommandResult(result, null, "空命令");
|
||||
}
|
||||
|
||||
Process process = null;
|
||||
BufferedReader successResult = null;
|
||||
BufferedReader errorResult = null;
|
||||
StringBuilder successMsg = null;
|
||||
StringBuilder errorMsg = null;
|
||||
|
||||
DataOutputStream os = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
for (String command : commands) {
|
||||
if (command == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// donnot use os.writeBytes(commmand), avoid chinese charset error
|
||||
os.write(command.getBytes());
|
||||
os.writeBytes(COMMAND_LINE_END);
|
||||
os.flush();
|
||||
}
|
||||
os.writeBytes(COMMAND_EXIT);
|
||||
os.flush();
|
||||
|
||||
result = process.waitFor();
|
||||
if (needResponse) {
|
||||
successMsg = new StringBuilder();
|
||||
errorMsg = new StringBuilder();
|
||||
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String s;
|
||||
while ((s = successResult.readLine()) != null) {
|
||||
successMsg.append(s);
|
||||
}
|
||||
while ((s = errorResult.readLine()) != null) {
|
||||
errorMsg.append(s);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (errorResult != null) {
|
||||
errorResult.close();
|
||||
}
|
||||
if (successResult != null) {
|
||||
successResult.close();
|
||||
}
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
|
||||
: errorMsg.toString());
|
||||
}
|
||||
|
||||
public static class CommandResult {
|
||||
|
||||
public int result;
|
||||
public String responseMsg;
|
||||
public String errorMsg;
|
||||
|
||||
public CommandResult(int result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public CommandResult(int result, String responseMsg, String errorMsg) {
|
||||
this.result = result;
|
||||
this.responseMsg = responseMsg;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String COMMAND_SU = "su";
|
||||
public static final String COMMAND_SH = "sh";
|
||||
public static final String COMMAND_EXIT = "exit\n";
|
||||
public static final String COMMAND_LINE_END = "\n";
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.TelephonyManager;
|
||||
import com.litesuits.android.log.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Get phone info, such as IMEI,IMSI,Number,Sim State, etc.
|
||||
*
|
||||
* <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2014-09-25
|
||||
*/
|
||||
public class TelephoneUtil {
|
||||
|
||||
private static final String TAG = TelephoneUtil.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* IMSI是国际移动用户识别码的简称(International Mobile Subscriber Identity)
|
||||
* IMSI共有15位,其结构如下:
|
||||
* MCC+MNC+MIN
|
||||
* MCC:Mobile Country Code,移动国家码,共3位,中国为460;
|
||||
* MNC:Mobile NetworkCode,移动网络码,共2位
|
||||
* 在中国,移动的代码为电00和02,联通的代码为01,电信的代码为03
|
||||
* 合起来就是(也是Android手机中APN配置文件中的代码):
|
||||
* 中国移动:46000 46002
|
||||
* 中国联通:46001
|
||||
* 中国电信:46003
|
||||
* 举例,一个典型的IMSI号码为460030912121001
|
||||
*/
|
||||
public static String getIMSI(Context context) {
|
||||
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String IMSI = telephonyManager.getSubscriberId();
|
||||
Log.i(TAG, " IMSI:" + IMSI);
|
||||
return IMSI;
|
||||
}
|
||||
|
||||
/**
|
||||
* IMEI是International Mobile Equipment Identity (国际移动设备标识)的简称
|
||||
* IMEI由15位数字组成的”电子串号”,它与每台手机一一对应,而且该码是全世界唯一的
|
||||
* 其组成为:
|
||||
* 1. 前6位数(TAC)是”型号核准号码”,一般代表机型
|
||||
* 2. 接着的2位数(FAC)是”最后装配号”,一般代表产地
|
||||
* 3. 之后的6位数(SNR)是”串号”,一般代表生产顺序号
|
||||
* 4. 最后1位数(SP)通常是”0″,为检验码,目前暂备用
|
||||
*/
|
||||
public static String getIMEI(Context context) {
|
||||
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String IMEI = telephonyManager.getDeviceId();
|
||||
Log.i(TAG, " IMEI:" + IMEI);
|
||||
return IMEI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print telephone info.
|
||||
*/
|
||||
public static String printTelephoneInfo(Context context) {
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String time = dateFormat.format(date);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("_______ 手机信息 ").append(time).append(" ______________");
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String IMSI = tm.getSubscriberId();
|
||||
//IMSI前面三位460是国家号码,其次的两位是运营商代号,00、02是中国移动,01是联通,03是电信。
|
||||
String providerName = null;
|
||||
if (IMSI != null) {
|
||||
if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) {
|
||||
providerName = "中国移动";
|
||||
} else if (IMSI.startsWith("46001")) {
|
||||
providerName = "中国联通";
|
||||
} else if (IMSI.startsWith("46003")) {
|
||||
providerName = "中国电信";
|
||||
}
|
||||
}
|
||||
sb.append(providerName).append(" 手机号:").append(tm.getLine1Number()).append(" IMSI是:").append(IMSI);
|
||||
sb.append("\nDeviceID(IMEI) :").append(tm.getDeviceId());
|
||||
sb.append("\nDeviceSoftwareVersion:").append(tm.getDeviceSoftwareVersion());
|
||||
sb.append("\ngetLine1Number :").append(tm.getLine1Number());
|
||||
sb.append("\nNetworkCountryIso :").append(tm.getNetworkCountryIso());
|
||||
sb.append("\nNetworkOperator :").append(tm.getNetworkOperator());
|
||||
sb.append("\nNetworkOperatorName :").append(tm.getNetworkOperatorName());
|
||||
sb.append("\nNetworkType :").append(tm.getNetworkType());
|
||||
sb.append("\nPhoneType :").append(tm.getPhoneType());
|
||||
sb.append("\nSimCountryIso :").append(tm.getSimCountryIso());
|
||||
sb.append("\nSimOperator :").append(tm.getSimOperator());
|
||||
sb.append("\nSimOperatorName :").append(tm.getSimOperatorName());
|
||||
sb.append("\nSimSerialNumber :").append(tm.getSimSerialNumber());
|
||||
sb.append("\ngetSimState :").append(tm.getSimState());
|
||||
sb.append("\nSubscriberId :").append(tm.getSubscriberId());
|
||||
sb.append("\nVoiceMailNumber :").append(tm.getVoiceMailNumber());
|
||||
|
||||
Log.i(TAG, sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/////_________________ 双卡双待系统IMEI和IMSI方案(see more on http://benson37.iteye.com/blog/1923946)
|
||||
|
||||
/**
|
||||
* 双卡双待神机IMSI、IMSI、PhoneType信息
|
||||
* <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
*/
|
||||
public static class TeleInfo {
|
||||
public String imsi_1;
|
||||
public String imsi_2;
|
||||
public String imei_1;
|
||||
public String imei_2;
|
||||
public int phoneType_1;
|
||||
public int phoneType_2;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TeleInfo{" +
|
||||
"imsi_1='" + imsi_1 + '\'' +
|
||||
", imsi_2='" + imsi_2 + '\'' +
|
||||
", imei_1='" + imei_1 + '\'' +
|
||||
", imei_2='" + imei_2 + '\'' +
|
||||
", phoneType_1=" + phoneType_1 +
|
||||
", phoneType_2=" + phoneType_2 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MTK Phone.
|
||||
*
|
||||
* 获取 MTK 神机的双卡 IMSI、IMSI 信息
|
||||
*/
|
||||
public static TeleInfo getMtkTeleInfo(Context context) {
|
||||
TeleInfo teleInfo = new TeleInfo();
|
||||
try {
|
||||
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
|
||||
|
||||
Field fields1 = phone.getField("GEMINI_SIM_1");
|
||||
fields1.setAccessible(true);
|
||||
int simId_1 = (Integer) fields1.get(null);
|
||||
|
||||
Field fields2 = phone.getField("GEMINI_SIM_2");
|
||||
fields2.setAccessible(true);
|
||||
int simId_2 = (Integer) fields2.get(null);
|
||||
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
Method getSubscriberIdGemini = TelephonyManager.class.getDeclaredMethod("getSubscriberIdGemini", int.class);
|
||||
String imsi_1 = (String) getSubscriberIdGemini.invoke(tm, simId_1);
|
||||
String imsi_2 = (String) getSubscriberIdGemini.invoke(tm, simId_2);
|
||||
teleInfo.imsi_1 = imsi_1;
|
||||
teleInfo.imsi_2 = imsi_2;
|
||||
|
||||
Method getDeviceIdGemini = TelephonyManager.class.getDeclaredMethod("getDeviceIdGemini", int.class);
|
||||
String imei_1 = (String) getDeviceIdGemini.invoke(tm, simId_1);
|
||||
String imei_2 = (String) getDeviceIdGemini.invoke(tm, simId_2);
|
||||
|
||||
teleInfo.imei_1 = imei_1;
|
||||
teleInfo.imei_2 = imei_2;
|
||||
|
||||
Method getPhoneTypeGemini = TelephonyManager.class.getDeclaredMethod("getPhoneTypeGemini", int.class);
|
||||
int phoneType_1 = (Integer) getPhoneTypeGemini.invoke(tm, simId_1);
|
||||
int phoneType_2 = (Integer) getPhoneTypeGemini.invoke(tm, simId_2);
|
||||
teleInfo.phoneType_1 = phoneType_1;
|
||||
teleInfo.phoneType_2 = phoneType_2;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i(TAG, "MTK: " + teleInfo);
|
||||
return teleInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* MTK Phone.
|
||||
*
|
||||
* 获取 MTK 神机的双卡 IMSI、IMSI 信息
|
||||
*/
|
||||
public static TeleInfo getMtkTeleInfo2(Context context) {
|
||||
TeleInfo teleInfo = new TeleInfo();
|
||||
try {
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
|
||||
Field fields1 = phone.getField("GEMINI_SIM_1");
|
||||
fields1.setAccessible(true);
|
||||
int simId_1 = (Integer) fields1.get(null);
|
||||
Field fields2 = phone.getField("GEMINI_SIM_2");
|
||||
fields2.setAccessible(true);
|
||||
int simId_2 = (Integer) fields2.get(null);
|
||||
|
||||
Method getDefault = TelephonyManager.class.getMethod("getDefault", int.class);
|
||||
TelephonyManager tm1 = (TelephonyManager) getDefault.invoke(tm, simId_1);
|
||||
TelephonyManager tm2 = (TelephonyManager) getDefault.invoke(tm, simId_2);
|
||||
|
||||
String imsi_1 = tm1.getSubscriberId();
|
||||
String imsi_2 = tm2.getSubscriberId();
|
||||
teleInfo.imsi_1 = imsi_1;
|
||||
teleInfo.imsi_2 = imsi_2;
|
||||
|
||||
String imei_1 = tm1.getDeviceId();
|
||||
String imei_2 = tm2.getDeviceId();
|
||||
teleInfo.imei_1 = imei_1;
|
||||
teleInfo.imei_2 = imei_2;
|
||||
|
||||
int phoneType_1 = tm1.getPhoneType();
|
||||
int phoneType_2 = tm2.getPhoneType();
|
||||
teleInfo.phoneType_1 = phoneType_1;
|
||||
teleInfo.phoneType_2 = phoneType_2;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i(TAG, "MTK2: " + teleInfo);
|
||||
return teleInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Qualcomm Phone.
|
||||
* 获取 高通 神机的双卡 IMSI、IMSI 信息
|
||||
*/
|
||||
public static TeleInfo getQualcommTeleInfo(Context context) {
|
||||
TeleInfo teleInfo = new TeleInfo();
|
||||
try {
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
Class<?> simTMclass = Class.forName("android.telephony.MSimTelephonyManager");
|
||||
Object sim = context.getSystemService("phone_msim");
|
||||
int simId_1 = 0;
|
||||
int simId_2 = 1;
|
||||
|
||||
Method getSubscriberId = simTMclass.getMethod("getSubscriberId", int.class);
|
||||
String imsi_1 = (String) getSubscriberId.invoke(sim, simId_1);
|
||||
String imsi_2 = (String) getSubscriberId.invoke(sim, simId_2);
|
||||
teleInfo.imsi_1 = imsi_1;
|
||||
teleInfo.imsi_2 = imsi_2;
|
||||
|
||||
Method getDeviceId = simTMclass.getMethod("getDeviceId", int.class);
|
||||
String imei_1 = (String) getDeviceId.invoke(sim, simId_1);
|
||||
String imei_2 = (String) getDeviceId.invoke(sim, simId_2);
|
||||
teleInfo.imei_1 = imei_1;
|
||||
teleInfo.imei_2 = imei_2;
|
||||
|
||||
Method getDataState = simTMclass.getMethod("getDataState");
|
||||
int phoneType_1 = tm.getDataState();
|
||||
int phoneType_2 = (Integer) getDataState.invoke(sim);
|
||||
teleInfo.phoneType_1 = phoneType_1;
|
||||
teleInfo.phoneType_2 = phoneType_2;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i(TAG, "Qualcomm: " + teleInfo);
|
||||
return teleInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spreadtrum Phone.
|
||||
*
|
||||
* 获取 展讯 神机的双卡 IMSI、IMSI 信息
|
||||
*/
|
||||
public static TeleInfo getSpreadtrumTeleInfo(Context context) {
|
||||
TeleInfo teleInfo = new TeleInfo();
|
||||
try {
|
||||
|
||||
TelephonyManager tm1 = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String imsi_1 = tm1.getSubscriberId();
|
||||
String imei_1 = tm1.getDeviceId();
|
||||
int phoneType_1 = tm1.getPhoneType();
|
||||
teleInfo.imsi_1 = imsi_1;
|
||||
teleInfo.imei_1 = imei_1;
|
||||
teleInfo.phoneType_1 = phoneType_1;
|
||||
|
||||
Class<?> phoneFactory = Class.forName("com.android.internal.telephony.PhoneFactory");
|
||||
Method getServiceName = phoneFactory.getMethod("getServiceName", String.class, int.class);
|
||||
getServiceName.setAccessible(true);
|
||||
String spreadTmService = (String) getServiceName.invoke(phoneFactory, Context.TELEPHONY_SERVICE, 1);
|
||||
|
||||
TelephonyManager tm2 = (TelephonyManager) context.getSystemService(spreadTmService);
|
||||
String imsi_2 = tm2.getSubscriberId();
|
||||
String imei_2 = tm2.getDeviceId();
|
||||
int phoneType_2 = tm2.getPhoneType();
|
||||
teleInfo.imsi_2 = imsi_2;
|
||||
teleInfo.imei_2 = imei_2;
|
||||
teleInfo.phoneType_2 = phoneType_2;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i(TAG, "Spreadtrum: " + teleInfo);
|
||||
return teleInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.litesuits.common.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Vibrator;
|
||||
|
||||
/**
|
||||
* <p>All methods requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#VIBRATE}.
|
||||
*
|
||||
* @author MaTianyu
|
||||
* @date 2014-11-21
|
||||
*/
|
||||
public class VibrateUtil {
|
||||
|
||||
/**
|
||||
* Vibrate constantly for the specified period of time.
|
||||
* <p>This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#VIBRATE}.
|
||||
*
|
||||
* @param milliseconds The number of milliseconds to vibrate.
|
||||
*/
|
||||
public static void vibrate(Context context, long milliseconds) {
|
||||
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
vibrator.vibrate(milliseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vibrate with a given pattern.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Pass in an array of ints that are the durations for which to turn on or off
|
||||
* the vibrator in milliseconds. The first value indicates the number of milliseconds
|
||||
* to wait before turning the vibrator on. The next value indicates the number of milliseconds
|
||||
* for which to keep the vibrator on before turning it off. Subsequent values alternate
|
||||
* between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
|
||||
* </p><p>
|
||||
* To cause the pattern to repeat, pass the index into the pattern array at which
|
||||
* to start the repeat, or -1 to disable repeating.
|
||||
* </p>
|
||||
* <p>This method requires the caller to hold the permission
|
||||
* {@link android.Manifest.permission#VIBRATE}.
|
||||
*
|
||||
* @param pattern an array of longs of times for which to turn the vibrator on or off.
|
||||
* @param repeat the index into pattern at which to repeat, or -1 if
|
||||
* you don't want to repeat.
|
||||
*/
|
||||
public static void vibrate(Context context, long[] pattern, int repeat) {
|
||||
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
vibrator.vibrate(pattern, repeat);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">android-common</string>
|
||||
</resources>
|
||||
@@ -0,0 +1 @@
|
||||
<resources></resources>
|
||||
Reference in New Issue
Block a user