Commit b7526533 authored by 张释方's avatar 张释方

代码合并

parents 39843456 53cf96d8
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/vcs.xml
/.idea/assetWizardSettings.xml
/.idea
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
/.idea/shelf/
/library_ad/build/
/shareSdkLib/build/
......@@ -15,11 +15,20 @@ android {
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
//flavorDimensions "default"
flavorDimensions "default"
//多个dex
multiDexEnabled true
//配置so文件
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
manifestPlaceholders = [CHANNEL_NAME_VALUE: "street",
UMENG_KEY : RELEASE_UMENG_KEY,
SHARE_KEY : RELEASE_SHARESDK_KEY,
SHARE_SECRET : RELEASE_SHARESDK_SECRET]
}
buildFeatures{
......@@ -33,40 +42,102 @@ android {
targetCompatibility rootProject.ext.java_version["targetJavaVersion"]
}
// buildTypes {
// debug {
//
//
// //混淆
// minifyEnabled false
// zipAlignEnabled false
// shrinkResources false//打开
//
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// }
// release {
//
// //混淆
// minifyEnabled true
// zipAlignEnabled true
// shrinkResources true
// //signingConfig signingConfigs.release
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// }
// }
signingConfigs {
debug {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
buildTypes {
debug {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "true"
buildConfigField "String", "AppKeyPre", "\"abcd\""
buildConfigField "String", "MainIp", DEBUG_URL
//混淆
minifyEnabled false
zipAlignEnabled false
shrinkResources false//打开
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
release {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
buildConfigField "String", "AppKeyPre", "\"abcd\""
buildConfigField "String", "MainIp", RELEASE_URL
//混淆
minifyEnabled true
zipAlignEnabled true
shrinkResources true//打开
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
lintOptions {
//lint 遇到 error 时继续 构建
//abortOnError false
//build release 版本 时 开启lint 检测
checkReleaseBuilds false
// 防止在发布的时候出现因MissingTranslation导致Build Failed!
disable 'MissingTranslation'
}
productFlavors {
streetpkg {}
toutiao {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [CHANNEL_NAME_VALUE: name]
}
// 自定义输出配置
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
outputFileName = "${variant.productFlavors[0].name}_${defaultConfig.versionName}.apk"
}
}
}
repositories {
flatDir {
dirs 'libs'
}
}
sourceSets {
main {
jniLibs.srcDir 'libs'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation fileTree(include: ['*.jar'], dir: 'libs')
testImplementation rootProject.ext.support["junit"]
// implementation 'androidx.appcompat:appcompat:1.1.0'
// implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
// testImplementation 'junit:junit:4.12'
// androidTestImplementation 'androidx.test.ext:junit:1.1.1'
// androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//下拉刷新
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-26'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-26'
......@@ -83,8 +154,6 @@ dependencies {
// 三方接入
// bugly
implementation 'com.tencent.bugly:crashreport:3.3.92'
// 移动安全联盟
implementation(name: 'oaid_sdk_1.0.23', ext: 'aar')
// shareSdk
......@@ -105,4 +174,5 @@ dependencies {
implementation(name: 'open_ad_sdk_3.7.0.1', ext: 'aar')
// 广点通广告 腾讯
implementation(name: 'GDTSDK.unionNormal.4.362.1232', ext: 'aar')
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# By default, the flags in this file are appended to flags specified
# in /Users/mengcuiguang/Documents/softwareDevelopment/android-sdk-macosx/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:
......@@ -12,10 +16,408 @@
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
#指定代码的压缩级别
-optimizationpasses 5
#包明不混合大小写
-dontusemixedcaseclassnames
#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
#优化 不优化输入的类文件
-dontoptimize
#预校验
-dontpreverify
#混淆时是否记录日志
-verbose
# 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护注解
-keepattributes *Annotation*
#保护内部类 保护反射
-keepattributes Exceptions, Signature, InnerClasses ,EnclosingMethod
# 保持哪些类不被混淆
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.data.BroadcastReceiver
-keep public class * extends android.data.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.app.Fragment
#忽略警告
-ignorewarnings
##记录生成的日志数据,gradle build时在本项目根目录输出##
#apk 包内所有 class 的内部结构
-dump class_files.txt
#未混淆的类和成员
-printseeds seeds.txt
#列出从 apk 中删除的代码
-printusage unused.txt
#混淆前后的映射
-printmapping mapping.txt
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######
# ===================== 混淆保护自己项目的部分代码以及引用的第三方jar包library ================
#okhttp
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *;}
-dontwarn okio.**
#butterknife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
#忽略警告
-dontwarn retrofit.**
#保留一个完整的包
-keep class retrofit.** {
*;
}
#忽略警告
-dontwarn rx.internal.util.unsafe.**
#保留一个完整的包
-keep class rx.internal.util.unsafe.** {
*;
}
#忽略警告
-dontwarn uk.co.senab.photoview.**
#保留一个完整的包
-keep class uk.co.senab.photoview.** {
*;
}
#忽略警告
-dontwarn rx.internal.util.unsafe.**
#保留一个完整的包
-keep class rx.internal.util.unsafe.** {
*;
}
#忽略警告
-dontwarn com.mints.street.bean.**
#保留实体类
-keep class com.mints.street.bean.** {
*;
}
#忽略警告
-dontwarn com.mints.street.widget.**
#保留实体类
-keep class com.mints.street.widget.** {
*;
}
#系统的design 忽略警告
-dontwarn android.support.design.widget.**
#保留实体类
-keep class android.support.design.widget.** {
*;
}
#系统的renderscript 忽略警告
-dontwarn android.support.v8.renderscript.**
#保留实体类
-keep class android.support.v8.renderscript.** {
*;
}
#忽略警告
-dontwarn cn.com.library.rxbus.**
#保留实体类
-keep class cn.com.library.rxbus.** {*;}
#忽略警告 /高德
-dontwarn com.amap.api.**
-dontwarn com.autonavi.aps.amapapi.model.**
-dontwarn com.loc.**
#保留一个完整的包
-keep class com.amap.api.** {*;}
-keep class com.autonavi.aps.amapapi.model.** {*;}
-keep class com.loc.** {*;}
#忽略警告
-dontwarn cn.fraudmetrix.sdk.**
#保留一个完整的包
-keep class cn.fraudmetrix.sdk.** {
*;
}
#忽略警告
-dontwarn com.nineoldandroids.**
#保留一个完整的包
-keep class com.nineoldandroids.** {
*;
}
#忽略警告
-dontwarn Decoder.**
#保留一个完整的包
-keep class Decoder.** {
*;
}
#忽略警告
-dontwarn com.nostra13.universalimageloader.**
#保留实体类
-keep class com.nostra13.universalimageloader.** {
*;
}
#忽略警告
-dontwarn com.megvii.**
#保留实体类
-keep class com.megvii.** { *; }
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
#如果引用了v4或者v7包
-dontwarn android.support.**
#如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。
#gson
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
# ===================== 混淆保护自己项目的部分代码以及引用的第三方jar包library-end ================
-keep public class * extends android.view.View {
public <init>(android.data.Context);
public <init>(android.data.Context, android.util.AttributeSet);
public <init>(android.data.Context, android.util.AttributeSet, int);
public void set*(...);
}
#保持 native 方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
#保持自定义控件类不被混淆
-keepclasseswithmembers class * {
public <init>(android.data.Context, android.util.AttributeSet);
}
#保持自定义控件类不被混淆
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
#保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
#保持 Serializable 不被混淆
-keepnames class * implements java.io.Serializable
#保持 Serializable 不被混淆并且enum 类也不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * {
public void *ButtonClicked(android.view.View);
}
#不混淆资源类
-keepclassmembers class **.R$* {
public static <fields>;
}
# 避免影响升级功能,需要keep住support包的类
-keep class android.support.**{*;}
# ===================== shareSDK START ================
-dontwarn com.mob.**
-dontwarn cn.sharesdk.**
-dontwarn **.R$*
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
-keep class **.R$* {*;}
-keep class **.R{*;}
-keep class com.mob.**{*;}
# ======================= shareSDK END ===============
# ===================== umeng START ================
-keep class com.umeng.** {*;}
-keepclassmembers class * {
public <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class com.mints.camera.R$*{
public static final int *;
}
-keep class com.uc.crashsdk.** { *; }
-keep interface com.uc.crashsdk.** { *; }
-keep class com.efs.** { *; }
-keep interface com.efs.** { *; }
# ======================= umeng END ================
# ===================== OAID START ================
-keep class XI.CA.XI.**{*;}
-keep class XI.K0.XI.**{*;}
-keep class XI.XI.K0.**{*;}
-keep class XI.vs.K0.**{*;}
-keep class XI.xo.XI.XI.**{*;}
-keep class com.asus.msa.SupplementaryDID.**{*;}
-keep class com.asus.msa.sdid.**{*;}
-keep class com.bun.lib.**{*;}
-keep class com.bun.miitmdid.**{*;}
-keep class com.huawei.hms.ads.identifier.**{*;}
-keep class com.samsung.android.deviceidservice.**{*;}
-keep class org.json.**{*;}
-keep public class com.netease.nis.sdkwrapper.Utils {public <methods>;}
# ======================= OAID END ================
# ===================== bugly START ================
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
# ======================= bugly END ================
# ======================= 穿山甲 GroMore START ================
#pangle
-keep class com.bytedance.sdk.openadsdk.** { *; }
-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
-keep class com.pgl.sys.ces.* {*;}
#聚合混淆
-keep class bykvm*.**
-keep class com.bytedance.msdk.adapter.**{ public *; }
-keep class com.bytedance.msdk.api.** {
public *;
}
-keep class com.bytedance.msdk.base.TTBaseAd{*;}
-keep class com.bytedance.msdk.adapter.TTAbsAdLoaderAdapter{
public *;
protected <fields>;
}
# baidu sdk 不接入baidu sdk可以不引入
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class com.baidu.mobads.** { *; }
-keep class com.baidu.mobad.** { *; }
-keep class com.bun.miitmdid.core.** {*;}
#ks 快手 不接入ks sdk可以不引入
-keep class org.chromium.** {*;}
-keep class org.chromium.** { *; }
-keep class aegon.chrome.** { *; }
-keep class com.kwai.**{ *; }
-dontwarn com.kwai.**
-dontwarn com.kwad.**
-dontwarn com.ksad.**
-dontwarn aegon.chrome.**
# Admob 不接入admob sdk可以不引入
-keep class com.google.android.gms.ads.MobileAds {
public *;
}
#sigmob 不接入sigmob sdk可以不引入
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep class sun.misc.Unsafe { *; }
-dontwarn com.sigmob.**
-keep class com.sigmob.**.**{*;}
# ======================= 穿山甲 GroMore END ================
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
......@@ -7,6 +7,13 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name="com.mints.street.AppApplication"
......@@ -19,7 +26,36 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name="com.mints.street.main.MainActivity">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" /> <!-- 适配小米(xiaomi)刘海屏 -->
<meta-data
android:name="android.max_aspect"
android:value="2.4"
tools:replace="android:value" />
<meta-data
android:name="android.notch_support"
android:value="true" />
<meta-data
android:name="notch.config"
android:value="portrait|landscape" /> <!-- 渠道名称 -->
<meta-data
android:name="CHANNEL_NAME"
android:value="${CHANNEL_NAME_VALUE}" /> <!-- 友盟 -->
<meta-data
android:name="UMENG_KEY"
android:value="${UMENG_KEY}" /> <!-- ShareSDK -->
<meta-data
android:name="Mob-AppKey"
android:value="${SHARE_KEY}" />
<meta-data
android:name="Mob-AppSecret"
android:value="${SHARE_SECRET}" />
<activity android:name="com.mints.street.splash.SplashActivity"
android:excludeFromRecents="true"
android:theme="@style/NormalSplash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......@@ -29,7 +65,11 @@
<activity android:name="com.mints.street.login.LoginActivity">
</activity>
<activity android:name="com.mints.street.splash.SplashActivity">
<activity android:name="com.mints.street.main.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:theme="@style/AppTheme.NoneTranslucent">
</activity>
......@@ -58,11 +98,11 @@
</provider> <!-- 穿山甲广告 -->
<provider
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:authorities="com.mints.street.TTMultiProvider"
android:exported="false" />
<provider
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:authorities="com.mints.street.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
......@@ -70,7 +110,8 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"
tools:replace="android:resource" />
</provider> <!-- 广点通广告 -->
</provider>
<!-- 广点通广告 -->
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
......
package com.mints.street
import android.content.Context
import android.os.StrictMode
import android.os.StrictMode.VmPolicy
import android.util.Log
import com.fry.base.base.BaseApp
import com.mints.street.manager.CsjGroMoreManager
import com.mints.street.manager.UmengManager
import java.util.concurrent.TimeoutException
/**
* Created by 冯瑞雨 on 2021/7/1.
*/
class AppApplication :BaseApp() {
class AppApplication : BaseApp() {
override fun onCreate() {
super.onCreate()
mContext = this
thirdConfig()
val builder = VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
builder.detectFileUriExposure()
......@@ -28,5 +35,23 @@ class AppApplication :BaseApp() {
}
}
/*
* 三方配置
*/
private fun thirdConfig() {
UmengManager.preInit()
// GroMore
CsjGroMoreManager.init(this)
}
companion object {
var mContext: AppApplication? = null
fun getContext(): AppApplication? {
return mContext
}
}
}
\ No newline at end of file
package com.mints.street.ad;
import android.app.Activity;
import android.content.Context;
import android.provider.Settings;
import com.bytedance.msdk.api.TTAdConfig;
import com.bytedance.msdk.api.TTAdConstant;
import com.bytedance.msdk.api.TTMediationAdSdk;
import com.bytedance.msdk.api.UserInfoForSegment;
import com.mints.street.common.Constant;
import com.mints.street.BuildConfig;
import com.mints.street.manager.CsjGroMoreManager;
import java.util.HashMap;
import java.util.Map;
/**
* 可以用一个单例来保存TTAdManager实例,在需要初始化sdk的时候调用
*/
public class TTGroMoreAdManagerHolder {
private static boolean sInit;
public static void init(Context context) {
doInit(context);
}
public static void initUnitySdkBanner(Activity activity) {
TTMediationAdSdk.initUnityForBanner(activity);
}
//step1:接入网盟广告sdk的初始化操作,详情见接入文档和穿山甲平台说明
private static void doInit(Context context) {
if (!sInit) {
TTMediationAdSdk.initialize(context, buildConfig(context));
sInit = true;
}
}
private static TTAdConfig buildConfig(Context context) {
UserInfoForSegment userInfo = new UserInfoForSegment();
Map<String, String> customInfos = new HashMap<>();
// customInfos.put("aaaa", "test111");
// customInfos.put("bbbb", "test222");
userInfo.setCustomInfos(customInfos);
return new TTAdConfig.Builder()
.appId(CsjGroMoreManager.TT_AD_APPID) //必填 ,不能为空
.appName(Constant.MINTS_APP_NAME) //必填,不能为空
.openAdnTest(false)//开启第三方ADN测试时需要设置为true,会每次重新拉去最新配置,release 包情况下必须关闭.默认false
.isPanglePaid(false)//是否为费用户
.setPublisherDid(getAndroidId(context)) //用户自定义device_id
.openDebugLog(BuildConfig.DEBUG) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
.usePangleTextureView(true) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
.setPangleTitleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
.allowPangleShowNotify(true) //是否允许sdk展示通知栏提示
.allowPangleShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
.setPangleDirectDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G) //允许直接下载的网络状态集合
.needPangleClearTaskReset()//特殊机型过滤,部分机型出现包解析失败问题(大部分是三星)。参数取android.os.Build.MODEL
.setUserInfoForSegment(userInfo) // 设置流量分组的信息
.build();
}
public static String getAndroidId(Context context) {
String androidId = null;
try {
androidId = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
} catch (Exception e) {
e.printStackTrace();
}
return androidId;
}
}
package com.mints.street.common
object Constant {
/**
* app名称
*/
const val MINTS_APP_NAME = "3D高清街景"
/**
* 应用包名
*/
const val MINTS_PKG_NAME = "com.mints.street"
}
package com.mints.street.common
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.net.Proxy
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.BatteryManager
import android.os.Build
import android.os.SystemClock
import android.provider.Settings
import android.telephony.TelephonyManager
import android.text.TextUtils
import com.mints.street.AppApplication
import com.mints.street.R
import com.mints.street.utils.SimUtils
import com.mints.street.utils.StorageQueryUtil
import com.mints.street.utils.SystemUtils
import com.mints.street.utils.json.JsonUtil
import java.io.*
import java.net.NetworkInterface
import java.util.*
/**
* 描述:设备信息
* 作者:孟崔广
* 时间:2020/9/17 17:51
*/
class DeviceInfo private constructor() {
private var mContext: Context? = null
private fun init() {
mContext = AppApplication.getContext()
}
val proxyUrl: String?
get() {
var proxyUrl: String? = null
if (!isWifi) {
proxyUrl = Proxy.getDefaultHost()
}
return proxyUrl
}
/**
* android4.2以上
* 系统从启动到现在的时间
* 单位:ms
*
*/
val elapsedRealtime = SystemClock.elapsedRealtime()
/**
* 运营商相关信息
*/
val newModel: String
get() {
return brand + " " + mobileModel +
" " + totalMemory + "+" + totalStorage +
" " + operator
}
/**
* 双卡信息只能在(android 5.1-9.0)获取
*
* 运营商名称
*
*/
val operator: String
get() {
val sb = StringBuilder("")
try {
// 判断是否使用单卡 (android10 获取不到双卡信息,只能获取单卡)
var needSingleSim = false
// 卡1
val simStateBySlotIdx1 =
SimUtils.getSimStateBySlotIdx(AppApplication.getContext(), 0)
// 卡2
val simStateBySlotIdx2 =
SimUtils.getSimStateBySlotIdx(AppApplication.getContext(), 1)
if (simStateBySlotIdx1) {
val providersName1 =
SimUtils.getSimOperatorName2(AppApplication.getContext(), 0)
if (TextUtils.equals(providersName1, "unknown")) {
needSingleSim = true
sb.append(SimUtils.getSimOperatorNameBySingle(AppApplication.getContext()) + " ")
} else {
sb.append("$providersName1 ")
}
} else {
sb.append("未插卡 ")
}
if (simStateBySlotIdx2) {
val providersName2 =
SimUtils.getSimOperatorName2(AppApplication.getContext(), 1)
if (TextUtils.equals(providersName2, "unknown") && !needSingleSim) {
sb.append(SimUtils.getSimOperatorNameBySingle(AppApplication.getContext()) + " ")
} else {
sb.append("$providersName2")
}
} else {
sb.append("未插卡")
}
} catch (e: Exception) {
e.printStackTrace()
}
return sb.toString()
}
/**
* 是否使用vpn 需使用网络权限
*/
val isVPN: Int
get() {
try {
val niList = NetworkInterface.getNetworkInterfaces()
if (niList != null) {
for (intf in Collections.list(niList)) {
if (!intf.isUp || intf.interfaceAddresses.size == 0) {
continue
}
if ("tun0" == intf.name || "ppp0" == intf.name) {
return 1 // The VPN is up
}
}
}
} catch (e: Throwable) {
e.printStackTrace()
}
return 0
}
/**
* 手机内存大小
*
*/
val totalMemory: String
get() {
return SystemUtils.getTotalMemory()
}
/**
* 手机存储大小
*
*/
val totalStorage: String
get() {
return StorageQueryUtil.getTotalStorageSize(AppApplication.getContext())
}
/**
* get device's IMSI
*
* @return IMSI number
*/
val iMSI: String
get() = (mContext
?.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).subscriberId
/**
* get device's IMEI
*
* @return IMEI number
*/
val iMEI: String
get() {
var imei = ""
try {
imei =
(mContext!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).deviceId
} catch (e: Exception) {
}
return imei
}
val userAgent: String?
get() {
var userAgent: String? = ""
try {
userAgent = System.getProperty("http.agent")
} catch (e: Exception) {
e.printStackTrace()
}
return userAgent
}
/**
* get device's MODEL
*
* @return model string
*/
val mobileModel: String
get() = Build.MODEL
/**
* Get application SDK version
*
* @return
*/
val sDKVersionNumber: Int
get() = Build.VERSION.SDK_INT
/**
* Get application OS version
*
* @return
*/
val oSVersion: String
get() = Build.VERSION.RELEASE
/**
* Test if wifi is activated
*
* @param
* @return
*/
val isWifi: Boolean
get() {
val connectivityManager = mContext
?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetInfo = connectivityManager.activeNetworkInfo
return (activeNetInfo != null
&& activeNetInfo.type == ConnectivityManager.TYPE_WIFI)
}
/**
* 获取versionName
*
* @return
*/
val versionName: String
get() {
var versionName = "1.0.0"
try {
versionName = mContext!!.packageManager.getPackageInfo(
mContext!!.packageName, 0
).versionName
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return versionName
}
/**
* 获取CPU核数
*
* @return
*/
val cupCount: Int
get() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
// Gingerbread doesn't support giving a single application access to both cores, but a
// handful of devices (Atrix 4G and Droid X2 for example) were released with a dual-core
// chipset and Gingerbread; that can let an app in the background run without impacting
// the foreground application. But for our purposes, it makes them single core.
return 1
}
val cores: Int
cores = try {
File("/sys/devices/system/cpu/").listFiles(CPU_FILTER).size
} catch (e: SecurityException) {
0
} catch (e: java.lang.NullPointerException) {
0
}
return cores
}
/**
* 获取CPU型号
*
* @return
*/
val cupInfo: String
get() {
val cpuInfo = arrayOf("", "") //0:型号 1:频率
try {
val str1 = "/proc/cpuinfo"
var str2 = ""
var arrayOfString: Array<String>
val fr = FileReader(str1)
if (fr != null) {
val localBufferedReader = BufferedReader(fr, 8192)
str2 = localBufferedReader.readLine()
arrayOfString = str2.split("\\s+".toRegex()).toTypedArray()
for (i in 2 until arrayOfString.size) {
cpuInfo[0] = cpuInfo[0] + arrayOfString[i] + " "
}
str2 = localBufferedReader.readLine()
arrayOfString = str2.split("\\s+".toRegex()).toTypedArray()
cpuInfo[1] += arrayOfString[2]
localBufferedReader.close()
}
} catch (e: IOException) {
cpuInfo[0] = "unknow"
}
return cpuInfo[0]
}
/**
* 获取versionCode
*
* @return
*/
val versionCode: String
get() {
var versionCode = "0"
try {
versionCode = mContext!!.packageManager.getPackageInfo(
mContext!!.packageName, 0
).versionCode.toString()
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return versionCode
}
/**
* 获取APP的名称
*
* @return
*/
val appName: String
get() {
var appName = ""
try {
appName = mContext!!.resources.getString(R.string.app_name)
} catch (e: Exception) {
e.printStackTrace()
}
return appName
}
/**
* 获取mac地址
*
* @return
*/
private val mac: String?
private get() {
if (mContext == null) {
return null
}
val wifi = mContext!!
.getSystemService(Context.WIFI_SERVICE) as WifiManager
val info = wifi.connectionInfo
return info.macAddress
}
/**
* 获取ssid地址
*
* @return
*/
val ssid: String?
get() {
if (mContext == null) {
return null
}
val wifi = mContext!!
.getSystemService(Context.WIFI_SERVICE) as WifiManager
val info = wifi.connectionInfo
return info.ssid
}
/**
* 设备品牌
*
* @return
*/
val brand: String
get() = Build.BRAND
/**
* 获取bssid地址
*
* @return
*/
val bssid: String?
get() {
if (mContext == null) {
return null
}
val wifi = mContext!!
.getSystemService(Context.WIFI_SERVICE) as WifiManager
val info = wifi.connectionInfo
return info.bssid
}
/**
* 获取apk签名
*
* @return
*/
val signInfo: Boolean
get() {
var sign_bool = false
try {
val packageInfo = mContext!!.packageManager
.getPackageInfo(mContext!!.packageName, PackageManager.GET_SIGNATURES)
val signs = packageInfo.signatures
if (signs != null && signs.size != 0) {
for (i in signs.indices) {
val str =
Integer.toHexString(signs[i].toCharsString().hashCode())
if (mContext!!.getString(R.string.app_sign)
.equals(str, ignoreCase = true)
) sign_bool = true
}
}
} catch (e: Exception) {
}
return sign_bool
}
/**
* 获取基带版本
*
* @return
*/
val bandInfo: String?
get() {
var result: Any? = null
result = try {
val cl = Class.forName("android.os.SystemProperties")
val invoker = cl.newInstance()
val m = cl.getMethod(
"get", *arrayOf<Class<*>>(
String::class.java, String::class.java
)
)
m.invoke(invoker, *arrayOf<Any>("gsm.version.baseband", "no message"))
} catch (e: Exception) {
"unknow"
}
return result as String?
}
/**
* 获取附近wifi列表
*
* @param context
* @return
*/
fun getApsInfo(context: Context): String {
val wifiManager =
context.getSystemService(Context.WIFI_SERVICE) as WifiManager
val apsInfo: MutableList<String> =
ArrayList()
val sbAps = StringBuffer()
// //有些手机getScanResults 需要定位权限
try {
val scanResults =
wifiManager.scanResults
for (i in scanResults.indices) {
apsInfo.add(scanResults[i].SSID.toString())
if (i == scanResults.size - 1) {
sbAps.append(apsInfo[i])
} else {
sbAps.append(apsInfo[i] + ",")
}
}
} catch (e: Exception) {
}
return sbAps.toString()
}
/**
* 获取基站信息
*
*
* MCC,Mobile Country Code,移动国家代码(中国的为460);
* MNC,Mobile Network Code,移动网络号码(中国移动为00,中国联通为01);
*/
fun getCellInfo(context: Context): Array<String> {
val mTelephonyManager =
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
// 返回值MCC + MNC
val cellInfo = arrayOf("", "")
val operator = mTelephonyManager.networkOperator
if (!TextUtils.isEmpty(operator)) {
cellInfo[0] = operator.substring(0, 3)
cellInfo[1] = operator.substring(3)
}
return cellInfo
}
/**
* 最近安装10个APP列表
*
* @param context
* @return
*/
fun getAPPInstalled(context: Context): String {
val listItems: MutableList<String?> =
ArrayList()
val installTime: MutableMap<Long, String> =
HashMap()
val time: MutableList<Long> = ArrayList()
// 获取系统内的所有程序信息
val mainintent = Intent(Intent.ACTION_MAIN, null)
mainintent.addCategory(Intent.CATEGORY_LAUNCHER)
val packageinfo =
context.packageManager.getInstalledPackages(0)
var pinfo: PackageInfo? = null
val count = packageinfo.size
for (i in 0 until count) {
pinfo = packageinfo[i]
val appInfo = pinfo.applicationInfo
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
} else {
//非系统程序
time.add(pinfo.firstInstallTime)
installTime[pinfo.firstInstallTime] =
pinfo.applicationInfo.loadLabel(context.packageManager) as String
}
}
Collections.sort(
time,
Collections.reverseOrder()
) //降序
val size = if (time.size >= 10) 10 else time.size
for (i in 0 until size) {
val s = installTime[time[i]]
listItems.add(s)
}
val sb = StringBuffer()
for (i in listItems.indices) {
if (i == listItems.size - 1) {
sb.append(listItems[i])
} else {
sb.append(listItems[i].toString() + ",")
}
}
return sb.toString()
}
/**
* 获取APP列表信息
*/
fun getAppInfoMap(): String {
try {
val appList: MutableList<MutableMap<String, String>> = ArrayList()
val mainintent = Intent(Intent.ACTION_MAIN, null)
mainintent.addCategory(Intent.CATEGORY_LAUNCHER)
val packageinfo =
mContext!!.packageManager.getInstalledPackages(0)
var pinfo: PackageInfo? = null
val count = packageinfo.size
for (i in 0 until count) {
pinfo = packageinfo[i]
val appInfo = pinfo.applicationInfo
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
} else {
//非系统程序
val appMap: MutableMap<String, String> = HashMap()
appMap["appName"] = appInfo.loadLabel(mContext!!.packageManager) as String
appMap["appPkg"] = pinfo.packageName
if (TextUtils.equals(
Constant.MINTS_APP_NAME,
appInfo.loadLabel(mContext!!.packageManager) as String
) &&
TextUtils.equals(pinfo.packageName, Constant.MINTS_PKG_NAME)
) {
continue
}
appList.add(appMap)
}
}
return JsonUtil.toJson(appList)
} catch (e: Exception) {
e.printStackTrace()
}
return ""
}
/**
* 获取APP名称列表信息
*/
fun getAppNameInfoList(): MutableList<String>? {
try {
val appList: MutableList<String> = ArrayList()
val mainintent = Intent(Intent.ACTION_MAIN, null)
mainintent.addCategory(Intent.CATEGORY_LAUNCHER)
val packageinfo =
mContext!!.packageManager.getInstalledPackages(0)
var pinfo: PackageInfo? = null
val count = packageinfo.size
for (i in 0 until count) {
pinfo = packageinfo[i]
val appInfo = pinfo.applicationInfo
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
} else {
//非系统程序
if (TextUtils.equals(
Constant.MINTS_APP_NAME,
appInfo.loadLabel(mContext!!.packageManager) as String
) &&
TextUtils.equals(pinfo.packageName, Constant.MINTS_PKG_NAME)
) {
continue
}
appList.add(appInfo.loadLabel(mContext!!.packageManager) as String)
}
}
return appList
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
/**
* 获取APP包名列表信息
*/
fun getAppPkgInfoList(): MutableList<String>? {
try {
val appList: MutableList<String> = ArrayList()
val mainintent = Intent(Intent.ACTION_MAIN, null)
mainintent.addCategory(Intent.CATEGORY_LAUNCHER)
val packageinfo =
mContext!!.packageManager.getInstalledPackages(0)
var pinfo: PackageInfo? = null
val count = packageinfo.size
for (i in 0 until count) {
pinfo = packageinfo[i]
val appInfo = pinfo.applicationInfo
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
} else {
//非系统程序
if (TextUtils.equals(
Constant.MINTS_APP_NAME,
appInfo.loadLabel(mContext!!.packageManager) as String
) &&
TextUtils.equals(pinfo.packageName, Constant.MINTS_PKG_NAME)
) {
continue
}
appList.add(pinfo.packageName)
}
}
return appList
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
/**
* 根据应用名称获取包名
*
* return:包名
*/
fun getAppPkg(name: String): String {
var pkg = ""
try {
val mainintent = Intent(Intent.ACTION_MAIN, null)
mainintent.addCategory(Intent.CATEGORY_LAUNCHER)
val packageinfo =
mContext!!.packageManager.getInstalledPackages(0)
var pinfo: PackageInfo? = null
val count = packageinfo.size
for (i in 0 until count) {
pinfo = packageinfo[i]
val appInfo = pinfo.applicationInfo
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
} else {
//非系统程序
if (TextUtils.equals(
name,
appInfo.loadLabel(mContext!!.packageManager) as String
)
) {
pkg = pinfo.packageName
break
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return pkg
}
/**
*
*
* return:包名
*/
fun isLoadingPkg(pkg: String): Boolean {
var flag = false
try {
val mainintent = Intent(Intent.ACTION_MAIN, null)
mainintent.addCategory(Intent.CATEGORY_LAUNCHER)
val packageinfo =
mContext!!.packageManager.getInstalledPackages(0)
var pinfo: PackageInfo? = null
val count = packageinfo.size
for (i in 0 until count) {
pinfo = packageinfo[i]
val appInfo = pinfo.applicationInfo
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
} else {
//非系统程序
if (TextUtils.equals(pkg, pinfo.packageName)) {
return true
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return flag
}
/**
* Android ID
*
* @return
*/
val androidId: String
get() {
val androidId = Settings.Secure.getString(
mContext!!.contentResolver, Settings.Secure.ANDROID_ID
)
return if (TextUtils.isEmpty(androidId)) "unknow" else androidId
}
/**
* Android ID
*
* @param context
* @return
*/
fun getAndroidId(context: Context?): String {
val androidId = Settings.Secure.getString(
mContext?.contentResolver, Settings.Secure.ANDROID_ID
)
return if (TextUtils.isEmpty(androidId)) "unknow" else androidId
}// Gingerbread doesn't support giving a single application access to both cores, but a
// handful of devices (Atrix 4G and Droid X2 for example) were released with a dual-core
// chipset and Gingerbread; that can let an app in the background run without impacting
// the foreground application. But for our purposes, it makes them single core.
/**
* 获取CPU核数
*
* @return
*/
val cpuCount: Int
get() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
// Gingerbread doesn't support giving a single application access to both cores, but a
// handful of devices (Atrix 4G and Droid X2 for example) were released with a dual-core
// chipset and Gingerbread; that can let an app in the background run without impacting
// the foreground application. But for our purposes, it makes them single core.
return 1
}
val cores: Int
cores = try {
File("/sys/devices/system/cpu/").listFiles(CPU_FILTER).size
} catch (e: SecurityException) {
0
} catch (e: NullPointerException) {
0
}
return cores
}
private val CPU_FILTER = FileFilter { pathname ->
val path = pathname.name
//regex is slow, so checking char by char.
if (path.startsWith("cpu")) {
for (i in 3 until path.length) {
if (path[i] < '0' || path[i] > '9') {
return@FileFilter false
}
}
return@FileFilter true
}
false
}//0:型号 1:频率
/**
* 获取手机CPU信息
*
* @return
*/
val cpuInfo: String
get() {
val str1 = "/proc/cpuinfo"
var str2 = ""
val cpuInfo = arrayOf("", "") //0:型号 1:频率
var arrayOfString: Array<String>
try {
val fr = FileReader(str1)
if (fr != null) {
val localBufferedReader = BufferedReader(fr, 8192)
str2 = localBufferedReader.readLine()
arrayOfString = str2.split("\\s+".toRegex()).toTypedArray()
for (i in 2 until arrayOfString.size) {
cpuInfo[0] = cpuInfo[0] + arrayOfString[i] + " "
}
str2 = localBufferedReader.readLine()
arrayOfString = str2.split("\\s+".toRegex()).toTypedArray()
cpuInfo[1] += arrayOfString[2]
localBufferedReader.close()
}
} catch (e: IOException) {
cpuInfo[0] = "unknow"
}
return cpuInfo[0]
}
/**
* 获取系统prop. 手机系统环境变量
*
* @return 如果不存在该key则返回空字符串
* @throws IllegalArgumentException 如果key超过32个字符则返回空字符串
*/
// @Throws(IllegalArgumentException::class)
// operator fun get(context: Context, key: String?): String? {
// var ret = ""
// try {
// val cl = context.classLoader
// val SystemProperties = cl.loadClass("android.os.SystemProperties")
//
// //参数类型
// val paramTypes: Array<Class<*>> = arrayOfNulls(1)
// paramTypes[0] = String::class.java
// val get = SystemProperties.getMethod("get", *paramTypes)
//
// //参数
// val params = arrayOfNulls<Any>(1)
// params[0] = String(key)
// ret = get.invoke(SystemProperties, *params) as String
// } catch (iAE: IllegalArgumentException) {
// ret = ""
// } catch (e: Exception) {
// ret = ""
// }
// return ret
// }
/**
* 获取MAC地址
*
* @param context
* @return
*/
fun getMacAddress(): String {
var mac: String = "02:00:00:00:00:00"
try {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
mac = getMacDefault()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
mac = macFromFile
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mac = macFromHardware
}
} catch (e: Exception) {
}
return mac
}
/**
* Android 6.0 之前(不包括6.0)
* 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
*
* @param context
* @return
*/
private fun getMacDefault(): String {
var mac = "02:00:00:00:00:00"
try {
if (mContext == null) {
return mac
}
val wifi = mContext!!.getSystemService(Context.WIFI_SERVICE) as WifiManager
?: return mac
var info: WifiInfo? = null
try {
info = wifi.connectionInfo
} catch (e: Exception) {
}
if (info == null) {
return mac
}
mac = info.macAddress
if (!TextUtils.isEmpty(mac)) {
mac = mac.toUpperCase(Locale.ENGLISH)
}
} catch (e: Exception) {
}
return mac
}
/**
* Android 6.0(包括) - Android 7.0(不包括)
*
* @return
*/
private val macFromFile: String
private get() {
var WifiAddress = "02:00:00:00:00:00"
try {
WifiAddress =
BufferedReader(FileReader(File("/sys/class/net/wlan0/address")))
.readLine()
} catch (e: IOException) {
e.printStackTrace()
}
return WifiAddress
}
/**
* 遍历循环所有的网络接口,找到接口是 wlan0
* 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
*
* @return
*/
private val macFromHardware: String
private get() {
try {
val all: List<NetworkInterface> =
Collections.list(NetworkInterface.getNetworkInterfaces())
for (nif in all) {
if (!nif.name.equals("wlan0", ignoreCase = true)) continue
val macBytes = nif.hardwareAddress ?: return ""
val res1 = StringBuilder()
for (b in macBytes) {
res1.append(String.format("%02X:", b))
}
if (res1.length > 0) {
res1.deleteCharAt(res1.length - 1)
}
return res1.toString()
}
} catch (e: Exception) {
e.printStackTrace()
}
return "02:00:00:00:00:00"
}
/**
* 否充电中
*/
val isCharging: Int
get() {
try {
val batteryBroadcast: Intent? = mContext!!.registerReceiver(
null,
IntentFilter(Intent.ACTION_BATTERY_CHANGED)
)
val isCharging =
batteryBroadcast?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0
if (isCharging) {
return 1
}
} catch (e: Exception) {
e.printStackTrace()
}
return 0
}
/**
* 否处于USB调试模式
*/
val getUsbStatus: Int
get() {
try {
val enableAdb = Settings.Secure.getInt(
mContext!!.contentResolver, Settings.Secure.ADB_ENABLED, 0
) > 0
if (enableAdb) {
return 1
}
} catch (e: Exception) {
e.printStackTrace()
}
return 0
}
/**
* 是否连接wifi
*/
val getWifiConnected: Int
get() {
try {
val connectivityManager =
mContext!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetInfo: NetworkInfo? = connectivityManager.activeNetworkInfo
if (activeNetInfo != null && activeNetInfo.getType() === ConnectivityManager.TYPE_WIFI) {
return 1
}
} catch (e: Exception) {
e.printStackTrace()
}
return 0
}
/**
* 是否root
*/
val isRoot: Int
get() {
var file: File? = null
val paths = arrayOf(
"/system/bin/",
"/system/xbin/",
"/system/sbin/",
"/sbin/",
"/vendor/bin/",
"/su/bin/"
)
try {
for (path in paths) {
file = File(path + "su")
if (file.exists() && file.canExecute()) {
return 1
}
}
} catch (x: java.lang.Exception) {
x.printStackTrace()
}
return 0
}
/**
* 获取后台运行APP
*/
fun getRunningApp(): String {
try {
val appList: MutableList<MutableMap<String, String>> = ArrayList()
val localPackageManager = mContext?.packageManager
localPackageManager?.let {
val localList = localPackageManager.getInstalledPackages(0)
for (i in 0 until localList.size) {
val pinfo = localList.get(i) as PackageInfo
if (pinfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0) {
//系统程序 忽略
continue
}
if (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP and pinfo.applicationInfo.flags == 0
&& ApplicationInfo.FLAG_STOPPED and pinfo.applicationInfo.flags == 0
) {
val appMap: MutableMap<String, String> = HashMap()
appMap["appName"] =
pinfo.applicationInfo.loadLabel(mContext!!.packageManager) as String
appMap["appPkg"] = pinfo.packageName
appList.add(appMap)
}
}
return JsonUtil.toJson(appList)
}
} catch (e: Exception) {
}
return ""
}
companion object {
private var _inst: DeviceInfo? = null
val instance: DeviceInfo
get() = if (_inst != null) {
_inst!!
} else {
_inst = DeviceInfo()
_inst!!
}
}
init {
init()
}
}
\ No newline at end of file
package com.mints.street.manager
import com.mints.street.AppApplication
import com.mints.street.ad.TTGroMoreAdManagerHolder
/**
* 穿山甲GroMore
*/
object CsjGroMoreManager {
const val TT_AD_APPID = "12345"
var AD_UNIT_SPLASH_ID = "" // 开屏
// 穿山甲id
var AD_CSJ_SPLASH_ID = "" // 开屏
fun init(application: AppApplication) {
TTGroMoreAdManagerHolder.init(application)
}
}
\ No newline at end of file
package com.mints.street.manager
import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.UMConfigure
import com.mints.street.BuildConfig
import com.mints.street.AppApplication
import com.mints.street.utils.CommonUtils
object UmengManager {
fun preInit(){
UMConfigure.preInit(AppApplication.getContext(), CommonUtils.getAppMetaData(AppApplication.getContext(), "UMENG_KEY"),
CommonUtils.getAppMetaData(AppApplication.getContext(), "CHANNEL_NAME"))
}
/**
* 友盟初始化
*/
fun initUm() {
try {
/*
* 参数4:设备类型,必须参数,传参数为UMConfigure.DEVICE_TYPE_PHONE则表示手机;传参数为UMConfigure.DEVICE_TYPE_BOX则表示盒子;默认为手机。
* 参数5:Push推送业务的secret,需要集成Push功能时必须传入Push的secret,否则传空。
*/
UMConfigure.init(
AppApplication.getContext(),
CommonUtils.getAppMetaData(AppApplication.getContext(), "UMENG_KEY"),
CommonUtils.getAppMetaData(AppApplication.getContext(), "CHANNEL_NAME"),
UMConfigure.DEVICE_TYPE_PHONE,
""
)
UMConfigure.setLogEnabled(BuildConfig.DEBUG)
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.LEGACY_MANUAL)
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
}
\ No newline at end of file
package com.mints.street.splash
import android.os.Bundle
import android.widget.FrameLayout
import com.bytedance.msdk.adapter.pangle.PangleNetworkRequestInfo
import com.bytedance.msdk.api.AdError
import com.bytedance.msdk.api.AdSlot
import com.bytedance.msdk.api.TTNetworkRequestInfo
import com.bytedance.msdk.api.splash.TTSplashAd
import com.bytedance.msdk.api.splash.TTSplashAdListener
import com.bytedance.msdk.api.splash.TTSplashAdLoadCallback
import com.fry.base.base.BaseActivity
import com.mints.street.BR
import com.mints.street.R
import com.mints.street.common.DeviceInfo
import com.mints.street.databinding.ActivitySplashBinding
import com.mints.street.main.MainActivity
import com.mints.street.manager.CsjGroMoreManager
/**
* Created by 冯瑞雨 on 2021/7/5.
* 优量汇开屏页
* 描述:gromore开屏页
* 作者:孟崔广
* 时间:2021/7/9 13:39
*/
class SplashActivity:BaseActivity<ActivitySplashBinding,SplashViewModel>() {
private var mSplashContainer: FrameLayout? = null
private var mTTSplashAd: TTSplashAd? = null
private val AD_TIME_OUT = 3000
private var onPaused = false
//是否强制跳转到主页面
private var mForceGoMain = false
override fun initContentView(savedInstanceState: Bundle?) = R.layout.activity_splash
override fun initVariableId() = BR.viewModel
......@@ -27,10 +47,123 @@ class SplashActivity:BaseActivity<ActivitySplashBinding,SplashViewModel>() {
checkAppSign()
}
override fun onResume() {
//判断是否该跳转到主页面
if (mForceGoMain) {
goToMainActivity()
}
if (onPaused ) {
// 这种情况下,百度开屏广告不能在onAdDismiss中跳转,需要自己在onResume中跳转主页。
goToMainActivity()
}
super.onResume()
}
override fun onPause() {
super.onPause()
onPaused = true
}
override fun onStop() {
super.onStop()
mForceGoMain = true
}
override fun onDestroy() {
super.onDestroy()
mTTSplashAd?.destroy()
mTTSplashAd=null
mSplashContainer?.removeAllViews()
mSplashContainer=null
}
/**
* 校验App签名
*/
private fun checkAppSign() {
val deviceInfo: DeviceInfo = DeviceInfo.instance
if (!deviceInfo.signInfo) {
finish()
} else {
try {
mSplashContainer = findViewById(R.id.splash_container)
//加载开屏广告
loadSplashAd()
} catch (e: Exception) {
goToMainActivity()
}
}
}
/**
* 加载开屏广告
*/
private fun loadSplashAd() {
/**
* 注:每次加载开屏广告的时候需要新建一个TTSplashAd,否则可能会出现广告填充问题
* ( 例如:mTTSplashAd = new TTSplashAd(this, mAdUnitId);)
*/
mTTSplashAd = TTSplashAd(this, CsjGroMoreManager.AD_UNIT_SPLASH_ID)
mTTSplashAd?.setTTAdSplashListener(mSplashAdListener)
//step3:创建开屏广告请求参数AdSlot,具体参数含义参考文档
val adSlot = AdSlot.Builder()
.setImageAdSize(1080, 1920) // 既适用于原生类型,也适用于模版类型。
.build()
//自定义兜底方案 选择使用
val ttNetworkRequestInfo: TTNetworkRequestInfo
//穿山甲兜底
ttNetworkRequestInfo = PangleNetworkRequestInfo(CsjGroMoreManager.TT_AD_APPID,CsjGroMoreManager.AD_CSJ_SPLASH_ID)
//step4:请求广告,调用开屏广告异步请求接口,对请求回调的广告作渲染处理
mTTSplashAd?.loadAd(adSlot, ttNetworkRequestInfo, object : TTSplashAdLoadCallback {
// mTTSplashAd.loadAd(adSlot, new TTSplashAdLoadCallback() {
override fun onSplashAdLoadFail(adError: AdError) {
goToMainActivity()
}
override fun onSplashAdLoadSuccess() {
if (mTTSplashAd != null) {
mTTSplashAd!!.showAd(mSplashContainer)
}
}
override fun onAdLoadTimeout() {
goToMainActivity()
}
}, AD_TIME_OUT)
}
var mSplashAdListener: TTSplashAdListener = object : TTSplashAdListener {
override fun onAdClicked() {
}
override fun onAdShow() {
}
override fun onAdSkip() {
goToMainActivity()
}
override fun onAdDismiss() {
if (onPaused) {
// 这种情况下,百度开屏广告不能在onAdDismiss中跳转,需要在onResume中跳转主页。
return
}
goToMainActivity()
}
}
/**
* 跳转到主页面
*/
private fun goToMainActivity() {
startActivityThenKill(MainActivity::class.java)
}
}
\ No newline at end of file
/*
* Copyright (c) 2015 [1076559197@qq.com | tchen0707@gmail.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.mints.street.utils;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextUtils;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 描述:CommonUtils
* 作者:孟崔广
* 时间:2018/1/10 17:51
* 邮箱:mengcga@163.com
*/
public class CommonUtils {
/**
* return if str is empty
*
* @param str
* @return
*/
public static boolean isEmpty(String str) {
if (str == null || str.length() == 0 || str.equalsIgnoreCase("null") || str.isEmpty() || str.equals("")) {
return true;
} else {
return false;
}
}
/**
* decode Unicode string
*
* @param s
* @return
*/
public static String decodeUnicodeStr(String s) {
StringBuilder sb = new StringBuilder(s.length());
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c == '\\' && chars[i + 1] == 'u') {
char cc = 0;
for (int j = 0; j < 4; j++) {
char ch = Character.toLowerCase(chars[i + 2 + j]);
if ('0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f') {
cc |= (Character.digit(ch, 16) << (3 - j) * 4);
} else {
cc = 0;
break;
}
}
if (cc > 0) {
i += 5;
sb.append(cc);
continue;
}
}
sb.append(c);
}
return sb.toString();
}
/**
* encode Unicode string
*
* @param s
* @return
*/
public static String encodeUnicodeStr(String s) {
StringBuilder sb = new StringBuilder(s.length() * 3);
for (char c : s.toCharArray()) {
if (c < 256) {
sb.append(c);
} else {
sb.append("\\u");
sb.append(Character.forDigit((c >>> 12) & 0xf, 16));
sb.append(Character.forDigit((c >>> 8) & 0xf, 16));
sb.append(Character.forDigit((c >>> 4) & 0xf, 16));
sb.append(Character.forDigit((c) & 0xf, 16));
}
}
return sb.toString();
}
/**
* convert time str
*
* @param time
* @return
*/
public static String convertTime(int time) {
time /= 1000;
int minute = time / 60;
int second = time % 60;
minute %= 60;
return String.format("%02d:%02d", minute, second);
}
/**
* url is usable
*
* @param url
* @return
*/
public static boolean isUrlUsable(String url) {
URL urlTemp = null;
HttpURLConnection connt = null;
try {
urlTemp = new URL(url);
connt = (HttpURLConnection) urlTemp.openConnection();
connt.setRequestMethod("HEAD");
int returnCode = connt.getResponseCode();
if (returnCode == HttpURLConnection.HTTP_OK) {
return true;
}
} catch (Exception e) {
return false;
} finally {
if (connt != null) {
connt.disconnect();
}
}
return false;
}
/**
* is url
*
* @param url
* @return
*/
public static boolean isUrl(String url) {
Pattern pattern = Pattern.compile("^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\/])+$");
return pattern.matcher(url).matches();
}
/**
* get toolbar height
*
* @param context
* @return
*/
public static int getToolbarHeight(Context context) {
final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
new int[]{android.R.attr.actionBarSize});
int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
return toolbarHeight;
}
/**
* Using regular expressions
*
* @param regular
* @param value
* @return
*/
public static boolean getConformToRegular(String regular, String value) {
boolean flag = false;
if (!TextUtils.isEmpty(regular) && !TextUtils.isEmpty(value)) {
Pattern p = Pattern.compile(regular);
Matcher m = p.matcher(value);
flag = m.matches();
}
return flag;
}
/**
* 禁止输入emoji
*/
public static InputFilter emojiFilter = new InputFilter() {
Pattern emoji = Pattern.compile(
"[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
int dstart,
int dend) {
Matcher emojiMatcher = emoji.matcher(source);
if (emojiMatcher.find()) {
return "";
}
return null;
}
};
/**
* 获取application中指定的meta-data
*
* @return 如果没有获取成功(没有对应值 , 或者异常),则返回值为空
*/
public static String getAppMetaData(Context ctx, String key) {
if (ctx == null || TextUtils.isEmpty(key)) {
return null;
}
String resultData = null;
try {
PackageManager packageManager = ctx.getPackageManager();
if (packageManager != null) {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo != null) {
if (applicationInfo.metaData != null) {
resultData = applicationInfo.metaData.getString(key);
}
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "";
}
return resultData;
}
public static String formatString(String str) {
if (str.contains(".")) {
String[] array = str.split("\\.");
String str0 = array[0];
String str1 = array[1];
if (str0.length() <= 3) {
return str0 + "." + str1;
} else {
return formatString(str0.substring(0, str0.length() - 3)) + ',' + str0.substring(str0.length() - 3) + "." + str1;
}
} else {
if (str.length() <= 3) {
return str;
} else {
return formatString(str.substring(0, str.length() - 3)) + ',' + str.substring(str.length() - 3);
}
}
}
}
package com.mints.street.utils;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Desction:授权工具类
* Author:孟崔广
*/
public class PermissionUtils {
public static final int CODE_PERMISSIONS = 123;
public interface PermissionGrant {
/**
* 处理结果
*
* @param requestCode 请求码
* @param permissions 本次授权权限列表
* @param grantResults 本次授权结果,0:授权成功 -1:拒绝授权
* @param requestPermissions 请求所有权限
*/
void onPermissionGranted(final int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults, String[] requestPermissions);
}
private static void showMessageOKCancel(final Activity context, String message, DialogInterface.OnClickListener okListener, DialogInterface.OnClickListener cancelListener) {
new AlertDialog.Builder(context)
.setMessage(message)
.setPositiveButton("是", okListener)
.setNegativeButton("否", cancelListener)
.create()
.show();
}
/**
* 跳转到系统设置界面去开启权限
*
* @param activity
* @param message
*/
private static void openSettingActivity(final Activity activity, String message) {
showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivity(intent);
}
}, null);
}
/////////////////////////////////执行授权/////////////////////////////////////
/**
* 一次申请多个权限
*
* @param activity
* @param grant
*/
public static void requestMultiPermissions(final Activity activity, final String[] requestPermissions, final PermissionGrant grant) {
//获取没有授权的权限
final List<String> permissionsList = getNoGrantedPermission(activity, requestPermissions, false);
//获取上次被拒权限列表
final List<String> shouldRationalePermissionsList = getNoGrantedPermission(activity, requestPermissions, true);
if (permissionsList == null || shouldRationalePermissionsList == null) {
return;
}
final int[] grantResults = new int[requestPermissions.length];
if (permissionsList.size() > 0) {//去授权
ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String[permissionsList.size()]), CODE_PERMISSIONS);
} else if (shouldRationalePermissionsList.size() > 0) {
showMessageOKCancel(activity, "应用缺少权限,是否重新去授权?",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(activity, shouldRationalePermissionsList.toArray(new String[shouldRationalePermissionsList.size()]),
CODE_PERMISSIONS);
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
grant.onPermissionGranted(CODE_PERMISSIONS, requestPermissions, grantResults, requestPermissions);
}
});
} else {
grant.onPermissionGranted(CODE_PERMISSIONS, requestPermissions, grantResults, requestPermissions);
}
}
private static ArrayList<String> getNoGrantedPermission(Activity activity, String[] requestPermissions, boolean isShouldRationale) {
ArrayList<String> permissions = new ArrayList<>();
for (int i = 0; i < requestPermissions.length; i++) {
String requestPermission = requestPermissions[i];
int checkSelfPermission = -1;
try {
checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission);
} catch (RuntimeException e) {
return null;
}
if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) {
if (isShouldRationale) {
permissions.add(requestPermission);
}
} else {
if (!isShouldRationale) {
permissions.add(requestPermission);
}
}
}
}
return permissions;
}
/////////////////////////////////处理授权结果/////////////////////////////////////
/**
* 处理授权
*
* @param requestCode Need consistent with requestPermission
* @param permissions
* @param grantResults
*/
public static void requestPermissionsResult(final int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults, String[] requestPermissions, PermissionGrant permissionGrant) {
if (requestCode == CODE_PERMISSIONS) {
permissionGrant.onPermissionGranted(requestCode, permissions, grantResults, requestPermissions);
return;
}
}
/////////////////////////////////处理授权结果/////////////////////////////////////
public static boolean checkPermission(Context paramContext, String paramString) {
boolean bool = false;
if (paramContext == null) {
return false;
} else {
if (Build.VERSION.SDK_INT >= 23) {
try {
Class localClass = Class.forName("android.content.Context");
Method localMethod = localClass.getMethod("checkSelfPermission", String.class);
int i = (Integer)localMethod.invoke(paramContext, paramString);
bool = i == 0;
} catch (Throwable var6) {
bool = false;
}
} else {
PackageManager localPackageManager = paramContext.getPackageManager();
if (localPackageManager.checkPermission(paramString, paramContext.getPackageName()) == 0) {
bool = true;
}
}
return bool;
}
}
}
package com.mints.street.utils;
import android.Manifest;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.RequiresApi;
import java.lang.reflect.Method;
/**
* The type Sim utils.
*/
public class SimUtils {
private static final String TAG = SimUtils.class.getSimpleName();
private static final String SIM_STATE = "getSimState";
private static final String SIM_OPERATOR_NAME = "getNetworkOperatorName";
private static final String SIM_NETWORK_TYPE = "getNetworkType";
private static final String SIM_IMEI = "getImei";
private static final String SIM_LINE_NUMBER = "getLine1Number";
private static final String SIM_SUBSCRIBER_ID = "getSubscriberId";
// private static final String SIM_SUBSCRIBER_ID = "getSubscriberId";
/**
* Gets sim network type.
*
* @param context the context
* @param slotIdx the slot idx
* @return the sim network type
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static int getSimNetworkType(Context context, int slotIdx) {
if (PermissionUtils.checkPermission(context, Manifest.permission.READ_PHONE_STATE)) {
Log.d(TAG, "READ_PHONE_STATE permission has BEEN granted to getSimNetworkType().");
if (getSimStateBySlotIdx(context, slotIdx)) {
return (int) getSimByMethod(context, SIM_NETWORK_TYPE, getSubidBySlotId(context, slotIdx));
}
} else {
Log.d(TAG, "READ_PHONE_STATE permission has NOT been granted to getSimNetworkType().");
}
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
/**
* Gets sim network name.
*
* @param context the context
* @param slotIdx the slot idx
* @return the sim network name
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static String getSimNetworkName(Context context, int slotIdx) {
return getNetworkName(getSimNetworkType(context, slotIdx));
}
/**
* Gets sim operator name.
*
* @param context the context
* @param slotIdx the slot idx
* @return the sim operator name
*/
public static String getSimOperatorName(Context context, int slotIdx) {
if (getSimStateBySlotIdx(context, slotIdx)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
return (String) getSimByMethod(context, SIM_OPERATOR_NAME, getSubidBySlotId(context, slotIdx));
}
}
return null;
}
/**
* Gets sim operator name.
*
* @param context the context
* @param slotIdx the slot idx
* @return the sim operator name
*/
public static String getSimOperatorName2(Context context, int slotIdx) {
if (getSimStateBySlotIdx(context, slotIdx)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
return getSimOperatorNameById((String) getSimByMethod(context, SIM_SUBSCRIBER_ID, getSubidBySlotId(context, slotIdx)));
}
}
return null;
}
/**
* Gets sim operator name by single.
*
* @param context the context
* @return the sim operator name
*/
public static String getSimOperatorNameBySingle(Context context) {
try {
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return getSimOperatorNameById(telephony.getSimOperator());
} catch (Exception e) {
}
return "unknown";
}
private static String getSimOperatorNameById(String IMSI) {
String operatorName = "unknown";
if (IMSI != null) {
if (IMSI.startsWith("46000") || IMSI.startsWith("46002") || IMSI.startsWith("46004") || IMSI.startsWith("46007")) {
operatorName = "中国移动";
} else if (IMSI.startsWith("46001") || IMSI.startsWith("46006") || IMSI.startsWith("46009")) {
operatorName = "中国联通";
} else if (IMSI.startsWith("46003") || IMSI.startsWith("46005") || IMSI.startsWith("46011")) {
operatorName = "中国电信";
}
}
return operatorName;
}
/**
* Gets sim state by slot idx.
*
* @param context the context
* @param slotIdx :0(sim1),1(sim2)
* @return the sim state by slot idx
*/
public static boolean getSimStateBySlotIdx(Context context, int slotIdx) {
boolean isReady = false;
Object getSimState = getSimByMethod(context, SIM_STATE, slotIdx);
if (getSimState != null) {
int simState = Integer.parseInt(getSimState.toString());
if ((simState != TelephonyManager.SIM_STATE_ABSENT) && (simState != TelephonyManager.SIM_STATE_UNKNOWN)) {
isReady = true;
}
}
return isReady;
}
/**
* Gets sim by method.
*
* @param context the context
* @param method the method
* @param param the param
* @return the sim by method
*/
public static Object getSimByMethod(Context context, String method, int param) {
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class<?> telephonyClass = Class.forName(telephony.getClass().getName());
Class<?>[] parameter = new Class[1];
parameter[0] = int.class;
Method getSimState = telephonyClass.getMethod(method, parameter);
Object[] obParameter = new Object[1];
obParameter[0] = param;
Object ob_phone = getSimState.invoke(telephony, obParameter);
if (ob_phone != null) {
return ob_phone;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* The type Current network.
*/
public static class CurrentNetwork {
/**
* The Which sim.
*/
public String whichSim;//那张卡
/**
* The Net work name.
*/
public String netWorkName;//几G网络
/**
* The Operate name.
*/
public String operateName;//卡生厂商
}
/**
* Gets current network.
*
* @param context the context
* @return the current network
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public static CurrentNetwork getCurrentNetwork(Context context) {
CurrentNetwork currentNetwork = new CurrentNetwork();
ConnectivityManager connectionManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
assert connectionManager != null;
NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
assert tm != null;
Log.d(TAG, "state:" + tm.getSimState());
if (networkInfo != null) {
if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
boolean status = networkInfo.isConnected();
int sim1NetWorkType = getSimNetworkType(context, 0);
int sim2NetWorkType = getSimNetworkType(context, 1);
if (networkInfo.getSubtype() == sim1NetWorkType) {
if (getSimStateBySlotIdx(context, 0)) {
currentNetwork.netWorkName = getNetworkName(sim1NetWorkType);
currentNetwork.operateName = getSimOperatorName(context, 0);
currentNetwork.whichSim = "卡1";
}
} else if (networkInfo.getSubtype() == sim2NetWorkType) {
if (getSimStateBySlotIdx(context, 1)) {
currentNetwork.netWorkName = getNetworkName(sim2NetWorkType);
currentNetwork.operateName = getSimOperatorName(context, 1);
currentNetwork.whichSim = "卡2";
}
}
}
} else {
// Logger.d(TAG, "network info is null: ");
}
return currentNetwork;
}
/**
* Gets network name.
*
* @param networkType the network type
* @return the network name
*/
public static String getNetworkName(int networkType) {
switch (networkType) {
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 "2G";
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 "3G";
case TelephonyManager.NETWORK_TYPE_LTE:
return "4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "5G";
default:
return "UNKNOWN";
}
}
/**
* to
*
* @param context the context
* @param slotId the slot id
* @return subid by slot id
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static int getSubidBySlotId(Context context, int slotId) {
SubscriptionManager subscriptionManager = (SubscriptionManager) context.getSystemService(
Context.TELEPHONY_SUBSCRIPTION_SERVICE);
try {
assert subscriptionManager != null;
Class<?> telephonyClass = Class.forName(subscriptionManager.getClass().getName());
Class<?>[] parameter = new Class[1];
parameter[0] = int.class;
Method getSimState = telephonyClass.getMethod("getSubId", parameter);
Object[] obParameter = new Object[1];
obParameter[0] = slotId;
Object ob_phone = getSimState.invoke(subscriptionManager, obParameter);
if (ob_phone != null) {
Log.d(TAG, "slotId:" + slotId + ";" + ((int[]) ob_phone)[0]);
return ((int[]) ob_phone)[0];
}
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
}
package com.mints.street.utils;
import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.util.Log;
import androidx.annotation.RequiresApi;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
public class StorageQueryUtil {
private final static String TAG = "storage";
public static String getTotalStorageSize(Context context) {
//5.0 查外置存储
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
float unit = 1000;
int version = Build.VERSION.SDK_INT;
String totalSizeReturn = "unknown";
if (version < Build.VERSION_CODES.M) {
try {
Method getVolumeList = StorageManager.class.getDeclaredMethod("getVolumeList");
StorageVolume[] volumeList = (StorageVolume[]) getVolumeList.invoke(storageManager);
long totalSize = 0;
if (volumeList != null) {
Method getPathFile = null;
for (StorageVolume volume : volumeList) {
if (getPathFile == null) {
getPathFile = volume.getClass().getDeclaredMethod("getPathFile");
}
File file = (File) getPathFile.invoke(volume);
totalSize += file.getTotalSpace();
}
}
totalSizeReturn = getUnit(totalSize, unit);
} catch (Exception e) {
e.printStackTrace();
totalSizeReturn = queryWithStatFs();
}
} else {
try {
Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");//6.0
List<Object> getVolumeInfo = (List<Object>) getVolumes.invoke(storageManager);
for (Object obj : getVolumeInfo) {
Field getType = obj.getClass().getField("type");
int type = getType.getInt(obj);
Log.d(TAG, "type: " + type);
if (type == 1) {//TYPE_PRIVATE
long totalSize = 0L;
//获取内置内存总大小
if (version >= Build.VERSION_CODES.O) {//8.0
Method getFsUuid = obj.getClass().getDeclaredMethod("getFsUuid");
String fsUuid = (String) getFsUuid.invoke(obj);
totalSize = getTotalSize(context, fsUuid);//8.0 以后使用
} else if (version >= Build.VERSION_CODES.N_MR1) {//7.1.1
Method getPrimaryStorageSize = StorageManager.class.getMethod("getPrimaryStorageSize");//5.0 6.0 7.0没有
totalSize = (long) getPrimaryStorageSize.invoke(storageManager);
}
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
if (totalSize == 0) {
totalSize = f.getTotalSpace();
}
}
totalSizeReturn = getUnit(totalSize, unit);
}
}
} catch (SecurityException e) {
Log.e(TAG, "缺少权限:permission.PACKAGE_USAGE_STATS");
totalSizeReturn = "unknownWithNoPermission";
} catch (Exception e) {
e.printStackTrace();
totalSizeReturn = queryWithStatFs();
}
}
return totalSizeReturn;
}
public static void queryWithStorageManager(Context context) {
//5.0 查外置存储
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
float unit = 1024, unit2 = 1000;
int version = Build.VERSION.SDK_INT;
if (version < Build.VERSION_CODES.M) {//小于6.0
try {
Method getVolumeList = StorageManager.class.getDeclaredMethod("getVolumeList");
StorageVolume[] volumeList = (StorageVolume[]) getVolumeList.invoke(storageManager);
long totalSize = 0, availableSize = 0;
if (volumeList != null) {
Method getPathFile = null;
for (StorageVolume volume : volumeList) {
if (getPathFile == null) {
getPathFile = volume.getClass().getDeclaredMethod("getPathFile");
}
File file = (File) getPathFile.invoke(volume);
totalSize += file.getTotalSpace();
availableSize += file.getUsableSpace();
}
}
Log.d(TAG, "totalSize = " + getUnit(totalSize, unit) + " ,availableSize = " + getUnit(availableSize, unit));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else {
try {
Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");//6.0
List<Object> getVolumeInfo = (List<Object>) getVolumes.invoke(storageManager);
long total = 0L, used = 0L, systemSize = 0L;
for (Object obj : getVolumeInfo) {
Field getType = obj.getClass().getField("type");
int type = getType.getInt(obj);
Log.d(TAG, "type: " + type);
if (type == 1) {//TYPE_PRIVATE
long totalSize = 0L;
//获取内置内存总大小
if (version >= Build.VERSION_CODES.O) {//8.0
Method getFsUuid = obj.getClass().getDeclaredMethod("getFsUuid");
String fsUuid = (String) getFsUuid.invoke(obj);
totalSize = getTotalSize(context, fsUuid);//8.0 以后使用
} else if (version >= Build.VERSION_CODES.N_MR1) {//7.1.1
Method getPrimaryStorageSize = StorageManager.class.getMethod("getPrimaryStorageSize");//5.0 6.0 7.0没有
totalSize = (long) getPrimaryStorageSize.invoke(storageManager);
}
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
if (totalSize == 0) {
totalSize = f.getTotalSpace();
}
systemSize = totalSize - f.getTotalSpace();
used += totalSize - f.getFreeSpace();
total += totalSize;
}
Log.d(TAG, "type = " + type + "totalSize = " + getUnit(totalSize, unit)
+ " ,used(with system) = " + getUnit(used, unit)
+ " ,free = " + getUnit(totalSize - used, unit));
} else if (type == 0) {//TYPE_PUBLIC
//外置存储
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
used += f.getTotalSpace() - f.getFreeSpace();
total += f.getTotalSpace();
}
} else if (type == 2) {//TYPE_EMULATED
}
}
Log.d(TAG, "总内存 total = " + getUnit(total, unit) + "\n已用 used(with system) = " + getUnit(used, unit)
+ "可用 available = " + getUnit(total - used, unit) + "系统大小:" + getUnit(systemSize, unit));
Log.d(TAG, "总内存 total = " + getUnit(total, unit2) + "\n已用 used(with system) = " + getUnit(used, 1000)
+ "可用 available = " + getUnit(total - used, unit2) + "系统大小:" + getUnit(systemSize, unit2));
} catch (SecurityException e) {
Log.e(TAG, "缺少权限:permission.PACKAGE_USAGE_STATS");
} catch (Exception e) {
e.printStackTrace();
queryWithStatFs();
}
}
}
public static String queryWithStatFs() {
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
//存储块
long blockCount = statFs.getBlockCount();
//块大小
long blockSize = statFs.getBlockSize();
//可用块数量
long availableCount = statFs.getAvailableBlocks();
//剩余块数量,注:这个包含保留块(including reserved blocks)即应用无法使用的空间
long freeBlocks = statFs.getFreeBlocks();
//level 18
// long totalSize = statFs.getTotalBytes();
// long availableSize = statFs.getAvailableBytes();
Log.d(TAG, "=========");
Log.d(TAG, "total = " + getUnit(blockSize * blockCount, 1024));
Log.d(TAG, "available = " + getUnit(blockSize * availableCount, 1024));
Log.d(TAG, "free = " + getUnit(blockSize * freeBlocks, 1024));
return getUnit(blockSize * blockCount, 1024);
}
private static String[] units = {"B", "KB", "MB", "GB", "TB"};
// /**
// * 进制转换
// */
// public static String getUnit(float size, float base) {
// int index = 0;
// while (size > base && index < 4) {
// size = size / base;
// index++;
// }
// return String.format(Locale.getDefault(), " %.2f %s ", size, units[index]);
// }
/**
* 进制转换 无空格无小数点
*/
public static String getUnit(float size, float base) {
int index = 0;
while (size > base && index < 4) {
size = size / base;
index++;
}
return String.format(Locale.getDefault(), "%.0f%s", size, units[index]);
}
/**
* API 26 android O
* 获取总共容量大小,包括系统大小
*/
@RequiresApi(Build.VERSION_CODES.O)
public static long getTotalSize(Context context, String fsUuid) {
try {
UUID id;
if (fsUuid == null) {
id = StorageManager.UUID_DEFAULT;
} else {
id = UUID.fromString(fsUuid);
}
StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
return stats.getTotalBytes(id);
} catch (NoSuchFieldError | NoClassDefFoundError | NullPointerException | IOException e) {
e.printStackTrace();
return -1;
}
}
}
\ No newline at end of file
package com.mints.street.utils
import android.app.ActivityManager
import android.content.Context
import android.os.Environment
import android.os.StatFs
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import java.io.IOException
import kotlin.math.ceil
object SystemUtils {
/**
* 该方法必须在Activity或Service类内调用,一般情况下,可以在Activity的onCreate()方法中调用。
* 由于应用每启动一个新的进程,就会调用一次Application的onCreate()方法,而个推SDK是一个独立的进程
* ,因此如果在Application的onCreate()中调用intialize接口,会导致SDK初始化在一个应用中多次调用,
* 所以不建议在Application继承类中调用个推SDK初始化接口。
* 解释一下,每个[Android](http://lib.csdn.net/base/android "Android知识库")应用都要运行在一个虚拟机上,
* ”个推“采用Service和后台服务器通信进行通信,于是和原本的Activity就形成了多进程。
* 一个前台的应用进程,一个service后台进程,每个进程对应一个application对象,所以当应用配置了多个进程的时候,
* application对象的onCreate方法就会执行多次,所以为了保证只初始化一次,
* 就必须做出区分的处理的(“个推”中提到的在Activity或Service中初始,这种做法个人认为也是存在多次初始化的风险的);
* 进程名是通过Manifest.xml中的"android:process"属性设置的,因此可以在application的onCreate方法中通过pid获取processName,
* 再做进一步的判断(跟android:process的值进行判断)使得相关初始化代码仅执行一次。
*/
fun getProcessName(cxt: Context, pid: Int): String? {
val am: ActivityManager = cxt.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningApps: List<ActivityManager.RunningAppProcessInfo> =
am.runningAppProcesses
?: return null
for (procInfo in runningApps) {
if (procInfo.pid == pid) {
return procInfo.processName
}
}
return null
}
/**
* ram
*/
fun getTotalMemory(): String {
// 系统内存信息文件
val file = "/proc/meminfo"
val memInfo: String
val strs: Array<String>
var memory: Long = 0
try {
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(
fileReader,
8192
)
// 读取meminfo第一行,系统内存大小
memInfo = bufferedReader.readLine()
strs = memInfo.split("\\s+".toRegex()).toTypedArray()
// 获得系统总内存,单位KB
memory = Integer.valueOf(strs[1]).toLong()
bufferedReader.close()
} catch (e: Exception) {
e.printStackTrace()
}
return "" + ceil((memory.toFloat() / (1024 * 1024).toDouble())).toInt() + "GB"
}
/**
* 获取手机内部空间总大小
*
* @return 大小,字节为单位
*/
fun getTotalInternalMemorySize(): String {
//获取内部存储根目录
val path: File = Environment.getExternalStorageDirectory()
//系统的空间描述类
val stat = StatFs(path.absolutePath)
//每个区块占字节数
val totalSize = stat.totalBytes
return "" + ceil((totalSize.toFloat() / (1024 * 1024 * 1024).toDouble())).toInt() + "GB"
}
/**
* 描述:获取内存占用率.
*/
fun getUsedPercentValue(context: Context?): Int {
val dir = "/proc/meminfo"
try {
val fr = FileReader(dir)
val br = BufferedReader(fr, 8192)
val memoryTotalLine = br.readLine()
val subMemoryLine = memoryTotalLine.substring(memoryTotalLine.indexOf("MemTotal:"))
/** KB 计量单位 */
br.close()
val totalMemorySize = subMemoryLine.replace("\\D+".toRegex(), "").toLong() * 1024
val availableSize: Long = getAvailMemory(context)
return (((totalMemorySize - availableSize) / totalMemorySize.toFloat()) * 100).toInt()
} catch (e: IOException) {
e.printStackTrace()
}
return -1
}
/**
* 描述:获取可用内存.
*/
fun getAvailMemory(context: Context?): Long {
// 获取android当前可用内存大小
val activityManager = context?.getSystemService(
Context.ACTIVITY_SERVICE
) as ActivityManager
val memoryInfo =
ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)
// 当前系统可用内存 ,将获得的内存大小规格化
return memoryInfo.availMem
}
}
\ No newline at end of file
package com.mints.street.utils.json;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 描述:FooAnnotation
* 作者:孟崔广
* 时间:2018/1/10 17:51
* 邮箱:mengcga@163.com
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface FooAnnotation {
}
package com.mints.street.utils.json;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
/**
* 描述:FooAnnotationExclusionStrategy
* 作者:孟崔广
*/
public class FooAnnotationExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(FooAnnotation.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
// return clazz.getAnnotation(FooAnnotation.class) != null;
}
}
package com.mints.street.utils.json;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.lang.reflect.Type;
public class JsonUtil {
private static Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new FooAnnotationExclusionStrategy())
.create();
@SuppressWarnings("hiding")
public static <T> T parseJson(String response, Class<T> clazz) {
try {
return gson.fromJson(response, clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static <T> T parseJson(JsonObject response, Class<T> clazz) {
try {
return gson.fromJson(response, clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 把json字符串转换为JavaBean。如果json的根节点就是一个集合,则使用此方法<p>
* type参数的获取方式为:Type type = new TypeToken<集合泛型>(){}.getType();
*
* @param json json字符串
* @return type 指定要解析成的数据类型
*/
public static <T> T json2Bean(String json, Type type) {
T bean = null;
try {
bean = gson.fromJson(json, type);
} catch (Exception e) {
Log.i("JsonUtil", "解析json数据时出现异常\njson = " + json, e);
}
return bean;
}
/**
* 把JsonElement转换为JavaBean。如果json的根节点就是一个集合,则使用此方法<p>
* type参数的获取方式为:Type type = new TypeToken<集合泛型>(){}.getType();
*
* @param json json字符串
* @return type 指定要解析成的数据类型
*/
public static <T> T json2Bean(JsonElement json, Type type) {
T bean = null;
try {
bean = gson.fromJson(json, type);
} catch (Exception e) {
Log.i("JsonUtil", "解析json数据时出现异常\njson = " + json, e);
}
return bean;
}
public static String toJson(Object object) {
try {
return gson.toJson(object);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white" />
</shape>
</item>
<item >
<bitmap
android:src="@drawable/bg_splash" />
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/splash_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:src="@drawable/bg_splash"
/>
<data>
<variable
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/splash_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:src="@drawable/bg_splash"
/>
<data>
<variable
name="ViewModel"
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/fl_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<!--这里模拟一张oneshot单的焦点图展示-->
<ImageView
android:id="@+id/oneshot_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="400px" />
<RelativeLayout
android:id="@+id/splash_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<!-- 广点通开屏广告支持“半屏/全屏”展示,开发者可以把Logo区域放在屏幕底部,然后在Logo上方提供一个容器来放置半开屏广告,请注意此容器高度不得小于400dp -->
<!-- 1.Logo区域:展示半开屏广告时使用,如果想展示全开屏广告,可以不需要这个Logo区域 -->
<!-- 注意:如需要这个Logo区域,建议开发者使用自己的Logo资源,而不是联盟的Logo资源@drawable/gdt_splash_logo,资源规格可参照@drawable/gdt_splash_logo -->
<FrameLayout
android:id="@+id/splash_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/app_logo" />
<!-- 2.预设开屏图片区域: -->
<!-- 开发者可以把自家App设计开屏图片摆放在这里,本示例中放置了一张静态图片。!-->
<!-- 注意1:直接将此图放在广告容器的下面即可,始终不要将广告容器splash_container的设为invisible,否则将不会展示广告无法计费,返回错误码600。-->
<!-- 注意2:建议开发者使用自己的开屏图片资源,而不是联盟的@drawable/splash_holder,资源规格可参照@drawable/splash_holder -->
<ImageView
android:id="@+id/splash_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/app_logo"
android:scaleType="fitXY" />
<!-- 3.开屏广告容器区域:-->
<!-- 注意:该区域高度不得小于400dp。在本示例中没有写死splash_container的高度值,是因为第1部分的app_logo区域是一个高度很小的图片。 -->
<ImageView
android:id="@+id/app_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@color/white"
android:src="@drawable/bg_splash"
/>
<!-- 4.自定义跳过按钮区域:开发者可以根据需要自己实现不同样式的跳过按钮 -->
<!-- 注意1:根据广告法规定,跳过按钮必须在屏幕当中出现。因此广告展示的时候,必须让将SkipView显示出来,即visible,否则将SDK将不展示广告,返回错误码608。。 -->
<!-- 注意2:SDK除了会检查跳过按钮的可见性,还将检测它的尺寸,其尺寸不得小于3dp*3dp,否则将SDK将不展示广告,返回错误码608。 -->
<TextView
android:id="@+id/skip_view"
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:background="@drawable/shape_bg_circle"
android:gravity="center"
android:text="点击跳过"
android:textColor="@android:color/white"
android:textSize="14sp"
android:visibility="gone" />
<!-- 本示例省略了自定义的倒计时,和跳过按钮放在一起实现了。开发者也可以实现自己的倒计时View,方法是在onADTick回调中获得广告剩余的展示时间,并自由决定倒计时View的样式,SDK对倒计时的View没有要求。 -->
<!-- 自定义wifi预加载按钮,需设置状态为不显示,当素材为视频且视频开始播放时,SDK内部会处理为显示状态-->
<TextView
android:id="@+id/preload_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="16dp"
android:background="@drawable/shape_bg_circle"
android:gravity="center"
android:text="已Wi-Fi预加载"
android:textColor="@android:color/white"
android:textSize="14sp"
android:visibility="gone" />
</RelativeLayout>
</FrameLayout>
<data>
<variable
......
......@@ -11,7 +11,7 @@
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp">
<com.mints.street.widget.CircleImageView
<ImageView
android:id="@+id/item_title_avatar"
android:layout_width="60dp"
android:layout_height="60dp"
......
......@@ -23,10 +23,10 @@ isBuildModule=false
DEBUG_URL="http://test.mints-id.com/camera-api/"
RELEASE_URL="https://api.mints-id.com/gc-api/"
RELEASE_KEY_PASSWORD=mints.goodnews
RELEASE_KEY_ALIAS=mints_goodnews
RELEASE_STORE_PASSWORD=mints.goodnews
RELEASE_STORE_FILE=mints_goodnews.jks
RELEASE_KEY_PASSWORD=mints.street
RELEASE_KEY_ALIAS=mints_street
RELEASE_STORE_PASSWORD=mints.street
RELEASE_STORE_FILE=mints_street.jks
#ShareSDK
RELEASE_SHARESDK_KEY=
......@@ -34,6 +34,3 @@ RELEASE_SHARESDK_SECRET=
#友盟
RELEASE_UMENG_KEY=
\ No newline at end of file
#JPush
RELEASE_JPUSH_KEY=
\ No newline at end of file
......@@ -10,7 +10,7 @@
<string name="bottom_name_task">任务中心</string>
<string name="bottom_name_my">个人中心</string>
<string name="app_sign">5932d26a</string>
<string name="app_sign">61117d7a</string>
<string name="dot">--</string>
......
......@@ -61,4 +61,24 @@
<style name="TabLayoutFavoriteTextStyle">
<item name="android:textSize">15sp</item>
</style>
<style name="NormalSplash" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash_bg</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="AppTheme.NoneTranslucent" parent="AppTheme.Base">
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowAnimationStyle">@null</item>
</style>
<style name="CustomerTransparentTheme" parent="AppTheme.Base">
<!-- 为窗体的Enter和Exit设置动画 -->
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@color/transparent</item>
</style>
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
\ No newline at end of file
#Fri Jul 09 14:31:29 CST 2021
VERSION_BUILD=2603
#Fri Jul 09 14:43:55 CST 2021
VERSION_BUILD=2655
......@@ -9,7 +9,7 @@
public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
#glide-transformations
-keep class jp.wasabeef.glide.transformations.** {*;}
......
......@@ -247,6 +247,17 @@ public abstract class HabitBaseActivity<V extends ViewDataBinding, VM extends Ba
startContainerActivity(canonicalName, null);
}
/**
* startActivity then finish
*
* @param clazz
*/
protected void startActivityThenKill(Class<?> clazz) {
Intent intent = new Intent(this, clazz);
startActivity(intent);
finish();
}
/**
* 跳转容器页面
*
......
......@@ -109,7 +109,7 @@ public class ViewAdapter {
});
}
@BindingAdapter(value = {"viewZ",/*"outline",*/"shadowColor"},requireAll = false)
@BindingAdapter(value = {"viewZ",/*"outline",*/"shadowColor2"},requireAll = false)
public static void setViewZ(View view,int z,int color){
ViewCompat.setElevation(view,AppUtils.dp2Px(view.getContext(),z));
......
......@@ -37,7 +37,7 @@
<attr name="isThrottleFirst" />
<attr name="currentView" />
<attr name="viewZ" format="integer" />
<attr name="shadowColor" format="integer" />
<attr name="shadowColor2" format="integer" />
<attr name="selected" format="boolean" />
</declare-styleable>
......
......@@ -7,6 +7,4 @@ public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String LIBRARY_PACKAGE_NAME = "cn.sharesdk.lib";
public static final String BUILD_TYPE = "debug";
public static final int VERSION_CODE = -1;
public static final String VERSION_NAME = "";
}
{
"version": 2,
"artifactType": {
"type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
"kind": "Directory"
},
"applicationId": "cn.sharesdk.lib",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"outputFile": "AndroidManifest.xml"
}
]
}
\ No newline at end of file
{
"version": 1,
"applicationId": "cn.sharesdk.lib",
"variantType": "LIBRARY",
"elements": [
{
"outputType": {
"type": "AAPT_FRIENDLY_MERGED_MANIFESTS"
},
"apkData": {
"type": "MAIN",
"splits": [],
"versionCode": -1,
"outputFile": "shareSdkLib-debug.aar",
"fullName": "debug",
"baseName": "debug",
"dirName": ""
},
"path": "AndroidManifest.xml",
"properties": {
"packageId": "cn.sharesdk.lib",
"split": ""
}
}
]
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/debug/jniLibs"/></dataSet></merger>
\ No newline at end of file
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Androidproject\android_street\shareSdkLib\src\main\jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Androidproject\android_street\shareSdkLib\src\debug\jniLibs"/></dataSet></merger>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/debug/shaders"/></dataSet></merger>
\ No newline at end of file
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Androidproject\android_street\shareSdkLib\src\main\shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Androidproject\android_street\shareSdkLib\src\debug\shaders"/></dataSet></merger>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/assets"><file name="ShareSDK.xml" path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/assets/ShareSDK.xml"/></source><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/build/intermediates/shader_assets/debug/out"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/debug/assets"/></dataSet></merger>
\ No newline at end of file
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Androidproject\android_street\shareSdkLib\src\main\assets"><file name="ShareSDK.xml" path="D:\Androidproject\android_street\shareSdkLib\src\main\assets\ShareSDK.xml"/></source><source path="D:\Androidproject\android_street\shareSdkLib\build\intermediates\shader_assets\debug\out"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="D:\Androidproject\android_street\shareSdkLib\src\debug\assets"/></dataSet></merger>
\ No newline at end of file
#Fri Jul 09 14:24:23 CST 2021
#Fri Jul 09 14:36:39 CST 2021
D\:\\Androidproject\\android_street\\shareSdkLib\\src\\main\\res\\drawable-xhdpi\\ssdk_country_search_icon.png=D\:\\Androidproject\\android_street\\shareSdkLib\\build\\intermediates\\packaged_res\\debug\\drawable-xhdpi-v4\\ssdk_country_search_icon.png
D\:\\Androidproject\\android_street\\shareSdkLib\\src\\main\\res\\drawable-xhdpi\\ssdk_oks_classic_sinaweibo.png=D\:\\Androidproject\\android_street\\shareSdkLib\\build\\intermediates\\packaged_res\\debug\\drawable-xhdpi-v4\\ssdk_oks_classic_sinaweibo.png
D\:\\Androidproject\\android_street\\shareSdkLib\\src\\main\\res\\drawable-xhdpi\\ssdk_weibo_empty_failed.png=D\:\\Androidproject\\android_street\\shareSdkLib\\build\\intermediates\\packaged_res\\debug\\drawable-xhdpi-v4\\ssdk_weibo_empty_failed.png
......
......@@ -5,8 +5,8 @@
5 <!-- android:targetSdkVersion="21" /> -->
6 <uses-sdk
7 android:minSdkVersion="21"
7-->/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
7-->D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
8 android:targetSdkVersion="30" />
8-->/Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
8-->D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
9
10</manifest>
{
"version": 1,
"applicationId": "cn.sharesdk.lib",
"variantType": "LIBRARY",
"elements": [
{
"outputType": {
"type": "MERGED_MANIFESTS"
},
"apkData": {
"type": "MAIN",
"splits": [],
"versionCode": -1,
"outputFile": "shareSdkLib-debug.aar",
"fullName": "debug",
"baseName": "debug",
"dirName": ""
},
"path": "../../library_manifest/debug/AndroidManifest.xml",
"properties": {
"packageId": "cn.sharesdk.lib",
"split": ""
}
}
]
}
\ No newline at end of file
{
"version": 2,
"artifactType": {
"type": "PACKAGED_MANIFESTS",
"kind": "Directory"
},
"applicationId": "cn.sharesdk.lib",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"outputFile": "../../library_manifest/debug/AndroidManifest.xml"
}
]
}
\ No newline at end of file
-- Merging decision tree log ---
manifest
ADDED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml:1:1-8:12
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml:1:1-8:12
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml:1:1-8:12
ADDED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml:1:1-8:12
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml:1:1-8:12
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml:1:1-8:12
package
ADDED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml:2:5-30
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
ADDED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml:2:5-30
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
xmlns:android
ADDED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml:1:11-69
ADDED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml:1:11-69
uses-sdk
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml reason: use-sdk injection requested
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml reason: use-sdk injection requested
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
android:targetSdkVersion
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
ADDED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
ADDED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
android:minSdkVersion
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
ADDED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from /Users/mcg/Documents/worker/androidspace/MyFlowbox/shareSdkLib/src/main/AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
ADDED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
INJECTED from D:\Androidproject\android_street\shareSdkLib\src\main\AndroidManifest.xml
com/mints/onekeyshare/themes/classic/port/FriendListPagePort.java
com.mints.onekeyshare.themes.classic.port.FriendListPagePort
com/mints/onekeyshare/themes/classic/PlatformPageAdapter.java
com.mints.onekeyshare.themes.classic.PlatformPageAdapter
com/mints/onekeyshare/themes/classic/FriendAdapter.java
com.mints.onekeyshare.themes.classic.FriendAdapter
com.mints.onekeyshare.themes.classic.FriendAdapter$1
com.mints.onekeyshare.themes.classic.FriendAdapter$2
com.mints.onekeyshare.themes.classic.FriendAdapter$3
com.mints.onekeyshare.themes.classic.FriendAdapter$FollowersResult
com.mints.onekeyshare.themes.classic.FriendAdapter$Following
com/mints/onekeyshare/themes/classic/RotateImageView.java
com.mints.onekeyshare.themes.classic.RotateImageView
com/mints/onekeyshare/OnekeyShareThemeImpl.java
com.mints.onekeyshare.OnekeyShareThemeImpl
com.mints.onekeyshare.OnekeyShareThemeImpl$1
com/mints/onekeyshare/themes/classic/ClassicTheme.java
com.mints.onekeyshare.themes.classic.ClassicTheme
com/mints/onekeyshare/themes/classic/IndicatorView.java
com.mints.onekeyshare.themes.classic.IndicatorView
com/mints/onekeyshare/themes/classic/PRTHeader.java
com.mints.onekeyshare.themes.classic.PRTHeader
com/mints/onekeyshare/themes/classic/land/PlatformPageAdapterLand.java
com.mints.onekeyshare.themes.classic.land.PlatformPageAdapterLand
com/mints/street/login/OnLoginListener.java
com.mints.street.login.OnLoginListener
com/mints/onekeyshare/themes/classic/port/PlatformPagePort.java
com.mints.onekeyshare.themes.classic.port.PlatformPagePort
com/mints/onekeyshare/themes/classic/port/PlatformPageAdapterPort.java
com.mints.onekeyshare.themes.classic.port.PlatformPageAdapterPort
com/mints/street/login/LoginApi.java
com.mints.street.login.LoginApi
com.mints.street.login.LoginApi$1
com/mints/street/wxapi/WXEntryActivity.java
com.mints.street.wxapi.WXEntryActivity
com/mints/onekeyshare/themes/classic/land/EditPageLand.java
com.mints.onekeyshare.themes.classic.land.EditPageLand
com.mints.onekeyshare.themes.classic.land.EditPageLand$1
com/mints/onekeyshare/themes/classic/land/FriendListPageLand.java
com.mints.onekeyshare.themes.classic.land.FriendListPageLand
com/mints/onekeyshare/OnekeySharePage.java
com.mints.onekeyshare.OnekeySharePage
com/mints/onekeyshare/themes/classic/port/EditPagePort.java
com.mints.onekeyshare.themes.classic.port.EditPagePort
com.mints.onekeyshare.themes.classic.port.EditPagePort$1
com/mints/onekeyshare/themes/classic/EditPage.java
com.mints.onekeyshare.themes.classic.EditPage
com/mints/onekeyshare/themes/classic/land/PlatformPageLand.java
com.mints.onekeyshare.themes.classic.land.PlatformPageLand
cn/sharesdk/lib/BuildConfig.java
cn.sharesdk.lib.BuildConfig
com/mints/onekeyshare/themes/classic/PlatformPage.java
com.mints.onekeyshare.themes.classic.PlatformPage
com.mints.onekeyshare.themes.classic.PlatformPage$1
com.mints.onekeyshare.themes.classic.PlatformPage$2
com.mints.onekeyshare.themes.classic.PlatformPage$3
com.mints.onekeyshare.themes.classic.PlatformPage$4
com/mints/onekeyshare/ShareContentCustomizeCallback.java
com.mints.onekeyshare.ShareContentCustomizeCallback
com/mints/onekeyshare/themes/classic/XView.java
com.mints.onekeyshare.themes.classic.XView
com/mints/onekeyshare/themes/classic/FriendListItem.java
com.mints.onekeyshare.themes.classic.FriendListItem
com/mints/onekeyshare/CustomerLogo.java
com.mints.onekeyshare.CustomerLogo
com/mints/onekeyshare/themes/classic/FriendListPage.java
com.mints.onekeyshare.themes.classic.FriendListPage
com/mints/onekeyshare/themes/classic/PicViewerPage.java
com.mints.onekeyshare.themes.classic.PicViewerPage
com.mints.onekeyshare.themes.classic.PicViewerPage$1
com/mints/onekeyshare/OnekeyShare.java
com.mints.onekeyshare.OnekeyShare
com/mints/onekeyshare/OnekeyShareTheme.java
com.mints.onekeyshare.OnekeyShareTheme
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment