GradleDiff/qkbtzf/mainTemplate.gradle
New file @@ -0,0 +1,59 @@ // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.0' } } allprojects { repositories { flatDir { dirs 'libs' } } } apply plugin: 'com.android.application' dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) **DEPS**} android { compileSdkVersion **APIVERSION** buildToolsVersion '**BUILDTOOLS**' defaultConfig { targetSdkVersion 26 applicationId '**APPLICATIONID**' ndk { abiFilters **ABIFILTERS** } } lintOptions { abortOnError false } aaptOptions { noCompress '.unity3d', '.ress', '.resource', '.obb' } **SIGN** buildTypes { debug { jniDebuggable true } release { // Set minifyEnabled to true if you want to run ProGuard on your project minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt' **SIGNCONFIG** } } } Project/qkbtzf/libs/android-support-v4.jarBinary files differ
Project/qkbtzf/libs/bugly.jarBinary files differ
Project/qkbtzf/libs/buglyagent.jarBinary files differ
Project/qkbtzf/libs/jcore-android-1.2.1.jarBinary files differ
Project/qkbtzf/libs/jpush-android-3.1.3.jarBinary files differ
Project/qkbtzf/libs/quicksdk_v2.7.1_20200309.jarBinary files differ
Project/qkbtzf/libs/tracking1.3.0.jarBinary files differ
Project/qkbtzf/libs/unity-classes.jarBinary files differ
Project/qkbtzf/src/game_qk/AndroidManifest.xml
New file @@ -0,0 +1,120 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.secondworld.univeralsdk" android:installLocation="auto" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="26" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <application android:name="com.secondworld.universalsdk.GameApplication" android:allowBackup="true" android:hardwareAccelerated="false" android:icon="@drawable/app_icon" android:isGame="true" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"> <meta-data android:name="android.max_aspect" android:value="1075838976.000000" /> <meta-data android:name="com.samsung.android.keepalive.density" android:value="true" /> <!--<meta-data--> <!--android:name="android.notch_support"--> <!--android:value="true" />--> <meta-data android:name="notch.config" android:value="none" /> <meta-data android:name="android.vendor.full_screen" android:value="true" /> <activity android:name="com.secondworld.universalsdk.SplashActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTop" android:screenOrientation="landscape" tools:replace="android:launchMode"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.secondworld.universalsdk.MainActivity" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection" android:label="@string/app_name" android:launchMode="singleTop" tools:replace="android:configChanges" android:screenOrientation="sensorLandscape"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> <meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" /> <meta-data android:name="android.vendor.home_indicator" android:value="hide" /> <meta-data android:name="android.max_aspect" android:value="1075419520.000000" /> <meta-data android:name="com.samsung.android.keepalive.density" android:value="true" /> </activity> <!-- 针对7.0以上的api开放的文件权限 --> <provider android:name="android.support.v4.content.FileProvider" android:authorities="quicksdk_packName.fileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest> Project/qkbtzf/src/game_qk/java/com/secondworld/universalsdk/GameApplication.java
New file @@ -0,0 +1,12 @@ package com.secondworld.universalsdk; import com.quicksdk.QuickSdkApplication; public class GameApplication extends QuickSdkApplication { @Override public void onCreate() { super.onCreate(); } } Project/qkbtzf/src/game_qk/java/com/secondworld/universalsdk/H2EngineSDK.java
New file @@ -0,0 +1,719 @@ package com.secondworld.universalsdk; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.content.FileProvider; import android.text.method.QwertyKeyListener; import android.util.Log; import android.widget.Toast; import com.quicksdk.QuickSDK; import com.quicksdk.Sdk; import com.quicksdk.User; import com.quicksdk.entity.GameRoleInfo; import com.quicksdk.entity.OrderInfo; import com.quicksdk.Payment; import com.secondworld.univeralsdk.R; import com.unity3d.player.UnityPlayer; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import cn.jpush.android.api.JPushInterface; import cn.jpush.android.data.JPushLocalNotification; public class H2EngineSDK { private static final String TAG = "H2EngineSDK"; private static String APP_ID = ""; private static boolean PushEnable = false; public static void HandleUnityMessage(String json) { LogUtil.i(TAG, "收到Unity发来的信息: " + json); Activity _activity = UnityPlayer.currentActivity; try { JSONObject _json = new JSONObject(json); int _code = _json.getInt("code"); switch (_code) { case CodeU2A.Init: APP_ID = _json.getString("appID"); init(_activity); break; case CodeU2A.CopyOneAsset: FileUtil.copy(_activity, _json.getString("fileName")); break; case CodeU2A.AssetCopy: FileUtil.copyAssets(_activity); break; case CodeU2A.BatteryListenStart: BatteryUtil.getInstance().start(_activity); break; case CodeU2A.BatteryListenStop: BatteryUtil.getInstance().stop(_activity); break; case CodeU2A.UniqueID: break; case CodeU2A.CopyContent: CopyContent(_activity, _json.getString("content")); break; case CodeU2A.OpenWebView: WebViewUtil.OpenWebView(_activity, _json.getString("url")); break; case CodeU2A.RestartApp: RestartApp(_activity); break; case CodeU2A.InstallAPK: InstallApp(_activity, _json.getString("path")); break; case CodeU2A.ExteneralStorage: GetExternalStorage(); break; case CodeU2A.RequestPermission: break; case CodeU2A.RequestManifestPermissions: break; case CodeU2A.FreePlatformInit: break; case CodeU2A.FreePlatformLogin: //QuickPlatformUtil.getInstance().login(_activity); LoginEx(_activity); break; case CodeU2A.FreePlatformSwitchAccount: break; case CodeU2A.FreePlatformLogout: //QuickPlatformUtil.getInstance().logout(_activity); LogoutEx(_activity); break; case CodeU2A.FreePlatformPay: JSONObject _extraData = new JSONObject(); String _appid = com.quicksdk.Extend.getInstance().getExtrasConfig("zfappid"); if (_appid == "") { //没有打包的自定义参数则取配置表 _appid = APP_ID; } _extraData.put("appid", _appid); _extraData.put("cpinfo", _json.getString("cpInfo")); _extraData.put("cporderid", _json.getString("orderId")); try { // YJPlatformUtil.getInstance().payExtend(_activity, // _json.getString("title"), // _json.getString("cpInfo"), // (float) _json.getDouble("mount"), // URLEncoder.encode(_extraData.toString(), // "utf-8")); // if (_yjAppID.contains("mzgame") // || _yjAppID.contains("ucgame") // || _yjAppID.contains("yybgame")) // { // QuickPlatformUtil.getInstance().pay(_activity, // _json.getString("title"), // _json.getString("cpInfo"), // (float) _json.getDouble("mount"), // URLEncoder.encode( // _extraData.toString(), // "utf-8")); // } // else // { // QuickPlatformUtil.getInstance().charge(_activity, // _json.getString("title"), // (float) _json.getDouble("mount"), // URLEncoder.encode( // _extraData.toString(), // "utf-8")); // } GameRoleInfo roleInfo3 = new GameRoleInfo(); roleInfo3.setServerID(_json.getString("sid")); roleInfo3.setServerName(_json.getString("serverName")); roleInfo3.setGameRoleName(_json.getString("roleName").trim().replace(" ", "")); roleInfo3.setGameRoleID(_json.getString("roleID")); roleInfo3.setGameBalance(_json.getString("money")); roleInfo3.setVipLevel(_json.getString("vipLevel")); //设置当前用户vip等级,必须为数字整型字符串,请勿传"vip1"等类似字符串 roleInfo3.setGameUserLevel(_json.getString("level"));//设置游戏角色等级 roleInfo3.setPartyName(_json.getString("familyName").trim().replace(" ", ""));//设置帮派名称 roleInfo3.setRoleCreateTime(_json.getString("createTime")); //UC,当乐与1881,TT渠道必传,值为10位数时间戳 roleInfo3.setPartyId("1100"); //360渠道参数,设置帮派id,必须为整型字符串 roleInfo3.setGameRolePower("38"); //360,TT语音渠道参数,设置角色战力,必须为整型字符串 roleInfo3.setPartyRoleId("11"); //360渠道参数,设置角色在帮派中的id roleInfo3.setPartyRoleName("帮主"); //360渠道参数,设置角色在帮派中的名称 roleInfo3.setProfessionId("38"); //360渠道参数,设置角色职业id,必须为整型字符串 roleInfo3.setProfession("法师"); //360渠道参数,设置角色职业名称 roleInfo3.setFriendlist( "无"); //360渠道参数,设置好友关系列表,格式请参考:http://open.quicksdk.net/help/detail/aid/190 OrderInfo orderInfo = new OrderInfo(); orderInfo.setCpOrderID(_json.getString("orderId")); orderInfo.setGoodsName(_json.getString("title"));//商品名称,不带数量 orderInfo.setCount(1);//游戏币数量 orderInfo.setAmount((float) _json.getDouble("mount")); orderInfo.setGoodsID(_json.getString("cpInfo")); orderInfo.setGoodsDesc(_json.getString("title")); //orderInfo.setPrice(0.1); orderInfo.setExtrasParams( URLEncoder.encode(_extraData.toString(), "utf-8")); Payment.getInstance().pay(_activity, orderInfo, roleInfo3); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } break; case CodeU2A.PayFinished: QuickPlatformUtil.getInstance().payProcessing = false; break; case CodeU2A.CreateRole: GameRoleInfo roleInfo = new GameRoleInfo(); roleInfo.setServerID(_json.getString("sid")); roleInfo.setServerName(_json.getString("serverName")); roleInfo.setGameRoleName(_json.getString("roleName").trim().replace(" ", "")); roleInfo.setGameRoleID(_json.getString("roleID")); roleInfo.setGameBalance(_json.getString("money")); roleInfo.setVipLevel( _json.getString("vipLevel")); //设置当前用户vip等级,必须为数字整型字符串,请勿传"vip1"等类似字符串 roleInfo.setGameUserLevel(_json.getString("level"));//设置游戏角色等级 roleInfo.setPartyName(_json.getString("familyName").trim().replace(" ", ""));//设置帮派名称 roleInfo.setRoleCreateTime( _json.getString("createTime")); //UC,当乐与1881,TT渠道必传,值为10位数时间戳 roleInfo.setPartyId("1100"); //360渠道参数,设置帮派id,必须为整型字符串 roleInfo.setGameRolePower("38"); //360,TT语音渠道参数,设置角色战力,必须为整型字符串 roleInfo.setPartyRoleId("11"); //360渠道参数,设置角色在帮派中的id roleInfo.setPartyRoleName("帮主"); //360渠道参数,设置角色在帮派中的名称 roleInfo.setProfessionId("38"); //360渠道参数,设置角色职业id,必须为整型字符串 roleInfo.setProfession("法师"); //360渠道参数,设置角色职业名称 roleInfo.setFriendlist( "无"); //360渠道参数,设置好友关系列表,格式请参考:http://open.quicksdk.net/help/detail/aid/190 //User.getInstance().setGameRoleInfo(_activity, roleInfo, true); SetRoleInfoEx(_activity, roleInfo, true); // QuickPlatformUtil.getInstance().createRole(_activity, // _json.getString("sid"), // _json.getString("serverName"), // _json.getString("roleID"), // _json.getString("roleName").trim() // .replace(" ", ""), // _json.getString("level"), // _json.getString("familyName").trim() // .replace(" ", ""), // _json.getString("createTime"), // _json.getString("vipLevel"), // _json.getString("money")); break; case CodeU2A.RoleLogin: GameRoleInfo roleInfo1 = new GameRoleInfo(); roleInfo1.setServerID(_json.getString("sid")); roleInfo1.setServerName(_json.getString("serverName")); roleInfo1.setGameRoleName(_json.getString("roleName").trim().replace(" ", "")); roleInfo1.setGameRoleID(_json.getString("roleID")); roleInfo1.setGameBalance(_json.getString("money")); roleInfo1.setVipLevel( _json.getString("vipLevel")); //设置当前用户vip等级,必须为数字整型字符串,请勿传"vip1"等类似字符串 roleInfo1.setGameUserLevel(_json.getString("level"));//设置游戏角色等级 roleInfo1.setPartyName(_json.getString("familyName").trim().replace(" ", ""));//设置帮派名称 roleInfo1.setRoleCreateTime( _json.getString("createTime")); //UC,当乐与1881,TT渠道必传,值为10位数时间戳 roleInfo1.setPartyId("1100"); //360渠道参数,设置帮派id,必须为整型字符串 roleInfo1.setGameRolePower("38"); //360,TT语音渠道参数,设置角色战力,必须为整型字符串 roleInfo1.setPartyRoleId("11"); //360渠道参数,设置角色在帮派中的id roleInfo1.setPartyRoleName("帮主"); //360渠道参数,设置角色在帮派中的名称 roleInfo1.setProfessionId("38"); //360渠道参数,设置角色职业id,必须为整型字符串 roleInfo1.setProfession("法师"); //360渠道参数,设置角色职业名称 roleInfo1.setFriendlist( "无"); //360渠道参数,设置好友关系列表,格式请参考:http://open.quicksdk.net/help/detail/aid/190 //User.getInstance().setGameRoleInfo(_activity, roleInfo1, false); SetRoleInfoEx(_activity, roleInfo1, false); // QuickPlatformUtil.getInstance().enterWorld(_activity, // _json.getString("sid"), // _json.getString("serverName"), // _json.getString("roleID"), // _json.getString("roleName").trim() // .replace(" ", ""), // _json.getString("level"), // _json.getString("familyName").trim() // .replace(" ", ""), // _json.getString("vipLevel"), // _json.getString("money")); verifyRealName(_activity); break; case CodeU2A.RoleLevelUp: GameRoleInfo roleInfo2 = new GameRoleInfo(); roleInfo2.setServerID(_json.getString("sid")); roleInfo2.setServerName(_json.getString("serverName")); roleInfo2.setGameRoleName(_json.getString("roleName").trim().replace(" ", "")); roleInfo2.setGameRoleID(_json.getString("roleID")); roleInfo2.setGameBalance(_json.getString("money")); roleInfo2.setVipLevel( _json.getString("vipLevel")); //设置当前用户vip等级,必须为数字整型字符串,请勿传"vip1"等类似字符串 roleInfo2.setGameUserLevel(_json.getString("level"));//设置游戏角色等级 roleInfo2.setPartyName(_json.getString("familyName").trim().replace(" ", ""));//设置帮派名称 roleInfo2.setRoleCreateTime( _json.getString("createTime")); //UC,当乐与1881,TT渠道必传,值为10位数时间戳 roleInfo2.setPartyId("1100"); //360渠道参数,设置帮派id,必须为整型字符串 roleInfo2.setGameRolePower("38"); //360,TT语音渠道参数,设置角色战力,必须为整型字符串 roleInfo2.setPartyRoleId("11"); //360渠道参数,设置角色在帮派中的id roleInfo2.setPartyRoleName("帮主"); //360渠道参数,设置角色在帮派中的名称 roleInfo2.setProfessionId("38"); //360渠道参数,设置角色职业id,必须为整型字符串 roleInfo2.setProfession("法师"); //360渠道参数,设置角色职业名称 roleInfo2.setFriendlist( "无"); //360渠道参数,设置好友关系列表,格式请参考:http://open.quicksdk.net/help/detail/aid/190 //User.getInstance().setGameRoleInfo(_activity, roleInfo2, false); SetRoleInfoEx(_activity, roleInfo2, false); // QuickPlatformUtil.getInstance().levelUp(_activity, // _json.getString("sid"), // _json.getString("serverName"), // _json.getString("roleID"), // _json.getString("roleName").trim() // .replace(" ", ""), // _json.getString("level"), // _json.getString("familyName").trim() // .replace(" ", ""), // _json.getString("createTime"), // _json.getString("levelUpTime"), // _json.getString("vipLevel"), // _json.getString("money")); break; case CodeU2A.ClientPackage: break; case CodeU2A.JPushAddLocalMessage: addLocalNotification(_activity, _json.getInt("id"), _json.getString("title"), _json.getString("content"), _json.getLong("fireTime")); break; case CodeU2A.JPushRemoveLocalMessage: removeNotification(_activity, _json.getInt("id")); break; case CodeU2A.TencentLogin: //QuickPlatformUtil.getInstance().loginTencent(_activity, _json.getString("param")); break; case CodeU2A.SendRegistEvent: //QuickPlatformUtil.getInstance().SendRegisterEvent(); break; } } catch (JSONException e) { e.printStackTrace(); } } // 本地推送 public static void addLocalNotification(Activity activity, int id, String title, String content, long fireTime) { if (PushEnable) { try { JPushLocalNotification ln = new JPushLocalNotification(); ln.setBuilderId(0);// 设置样式 ln.setNotificationId(id);// id ln.setTitle(title);// 标题 ln.setContent(content);// 内容 ln.setBroadcastTime(fireTime);// 等待时间 JPushInterface.addLocalNotification(activity, ln); } catch (Exception e) { e.printStackTrace(); } } } public static void removeNotification(Activity activity, int id) { if (PushEnable) { JPushInterface.removeLocalNotification(activity, id); } } public static void GetExternalStorage() { Map<String, Object> _msg = new HashMap<>(); _msg.put("code", CodeA2U.ExternalStorage); _msg.put("path", Environment.getExternalStorageDirectory().getAbsolutePath()); UniversalUtil.sendMessageToUnity(_msg); } public static void InstallApp(Activity activity, String path) { File _file = new File(path); if (_file == null) { LogUtil.i(TAG, "找不到给定地址的apk: " + path); return; } try { Intent _intent = new Intent(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= 23) { _intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri _contentUri = FileProvider.getUriForFile(activity, "com.shandangceshi.snxxz.fileProvider", _file); _intent.setDataAndType(_contentUri, "application/vnd.android.package-archive"); } else { _intent.setDataAndType(Uri.fromFile(_file), "application/vnd.android.package-archive"); _intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } activity.startActivity(_intent); } catch (Exception e) { e.printStackTrace(); Toast.makeText(activity, "没有找到打开此类文件的程序", Toast.LENGTH_SHORT).show(); } } public static void LoginEx(final Activity activity) { activity.runOnUiThread(new Runnable() { @Override public void run() { QuickPlatformUtil.getInstance().login(activity); } }); } public static void LogoutEx(final Activity activity) { activity.runOnUiThread(new Runnable() { @Override public void run() { QuickPlatformUtil.getInstance().logout(activity); } }); } public static void SetRoleInfoEx(final Activity activity, final GameRoleInfo roleInfo, final boolean createRole) { activity.runOnUiThread(new Runnable() { @Override public void run() { User.getInstance().setGameRoleInfo(activity, roleInfo, createRole); } }); } public static void CopyContent(final Activity activity, final String content) { activity.runOnUiThread(new Runnable() { @Override public void run() { ClipboardManager _mgr = (ClipboardManager) activity.getSystemService( Context.CLIPBOARD_SERVICE); ClipData _data = ClipData.newPlainText("playerId", content); _mgr.setPrimaryClip(_data); } }); } public static void RestartApp(final Activity activity) { activity.runOnUiThread(new Runnable() { @Override public void run() { new Thread() { public void run() { String _pn = activity.getPackageName(); PackageManager _pm = activity.getPackageManager(); Intent _l = _pm.getLaunchIntentForPackage(_pn); _l.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(_l); android.os.Process.killProcess(android.os.Process.myPid()); } }.start(); activity.finish(); } }); } public static void init(final Activity activity) { final int _memoryTotal = (int) (UniversalUtil.getMemTotal() / 1024); if (_memoryTotal < 1024) { LogUtil.i(TAG, "检测设备内存不满足运行程序标准"); AlertDialog.Builder _builder = new AlertDialog.Builder(activity); _builder.setIcon(R.drawable.app_icon); _builder.setTitle("警告"); _builder.setMessage("您的手机内存不足,无法正常运行游戏"); _builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { android.os.Process.killProcess(android.os.Process.myPid()); } }); _builder.show(); return; } //PushEnable = activity.getPackageName().equals("com.xjaz.sp"); new Thread(new Runnable() { @Override public void run() { LogUtil.i(TAG, "开始执行初始化"); GetExternalStorage(); // ------------------------------- 设备信息 ------------------------------- Map<String, Object> _msgStruct = new HashMap<>(); _msgStruct.put("code", CodeA2U.DeviceInfo); _msgStruct.put("userAgent", System.getProperty("http.agent")); _msgStruct.put("mac", UniqueID.getLocalMac(activity)); _msgStruct.put("imei", UniqueID.getDeviceId(activity)); _msgStruct.put("android_id", Settings.System.getString(activity.getContentResolver(), Settings.System.ANDROID_ID)); _msgStruct.put("unique_id", UniqueID.get(activity)); _msgStruct.put("memoryTotal", _memoryTotal); UniversalUtil.sendMessageToUnity(_msgStruct); // ------------------------------- 极光推送 ------------------------------- String _registrationID = "0"; if (PushEnable) { JPushInterface.setDebugMode(true); JPushInterface.init(activity); final long _waitingTime = System.currentTimeMillis(); while (true) { // 等待获取极光registrationID if (!JPushInterface.getRegistrationID(activity).equals("")) { _registrationID = JPushInterface.getRegistrationID(activity); break; } long _escapeTime = System.currentTimeMillis() - _waitingTime; if (_escapeTime > 3000) { LogUtil.w(TAG, "等待获取极光推送registrationID超时: 3秒"); break; } } } _msgStruct.clear(); _msgStruct.put("code", CodeA2U.PushClientID); _msgStruct.put("clientID", _registrationID); UniversalUtil.sendMessageToUnity(_msgStruct); _msgStruct.clear(); _msgStruct.put("code", CodeA2U.SdkInitComplete); _msgStruct.put("channelPlatform", "quick"); //根据appid是否相同和后台配置 可调整混服和专服 //打包工具可添加自定义参数 String _appid = com.quicksdk.Extend.getInstance().getExtrasConfig("zfappid"); if (_appid == "") { //没有打包的自定义参数则取配置表 _appid = APP_ID; } //通知到unity中的账号已经加上渠道ID,保证appid和spid唯一对应, 需要注意和sdk交互时使用最原始的uid _msgStruct.put("yj_appid", _appid); _msgStruct.put("yj_spid", _appid); UniversalUtil.sendMessageToUnity(_msgStruct); LogUtil.i(TAG, "初始化执行完毕"); } }).start(); } public static void onCreate(Activity activity, Bundle savedInstanceState) { Sdk.getInstance().onCreate(activity); try { // check权限 if ((ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) || (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) { // 没有 , 申请权限 权限数组 ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 1); } else { QuickPlatformUtil.getInstance().onCreate(); Sdk.getInstance().init(activity,"16738592021815700006389081047799", "46221152"); } } catch (Exception e) { QuickPlatformUtil.getInstance().onCreate(); Sdk.getInstance().init(activity, "16738592021815700006389081047799", "46221152"); } QuickSDK.getInstance().setIsLandScape(true); } private static boolean m_IsFocus = true; public static void onWindowFocusChanged(boolean b) { if (b) { if (QuickPlatformUtil.getInstance().payProcessing) { Map<String, Object> _msgStruct = new HashMap<>(); _msgStruct.put("code", CodeA2U.FreePlatformPayCancel); UniversalUtil.sendMessageToUnity(_msgStruct); QuickPlatformUtil.getInstance().payProcessing = false; } } m_IsFocus = b; } public static void onNewIntent(final Activity activity, final Intent intent) { Sdk.getInstance().onNewIntent(intent); } public static void onActivityResult(int requestCode, int resultCode, final Intent data, final Activity activity) { Sdk.getInstance().onActivityResult(activity, requestCode, resultCode, data); } public static void onConfigurationChanged(final Configuration newConfig) {} public static void onRestart(final Activity activity) { Sdk.getInstance().onRestart(activity); } public static void onStart(final Activity activity) { Sdk.getInstance().onStart(activity); } public static void onPause(final Activity activity) { Sdk.getInstance().onPause(activity); } public static void onResume(final Activity activity) { Sdk.getInstance().onResume(activity); } public static void onStop(final Activity activity) { Sdk.getInstance().onStop(activity); } public static void onDestroy(final Activity activity) { Sdk.getInstance().onDestroy(activity); } private static void verifyRealName(final Activity activity) { activity.runOnUiThread(new Runnable() { @Override public void run() { // 判断渠道是否支持实名认证功能 if (com.quicksdk.Extend.getInstance().isFunctionSupported(com.quicksdk.FuncType.REAL_NAME_REGISTER)) { com.quicksdk.Extend.getInstance().callFunctionWithParamsCallBack(activity, com.quicksdk.FuncType.REAL_NAME_REGISTER, new com.quicksdk.BaseCallBack() { @Override public void onSuccess(Object... arg0) { if (arg0 != null && arg0.length > 0) { JSONObject jsonObject = (JSONObject) arg0[0]; Log.d("json", "==========" + jsonObject.toString()); try { // 用户id String uid = jsonObject.getString("uid"); // 年龄, 如果渠道没返回默认为-1 int age = jsonObject.getInt("age"); // 是否已实名 true表示已实名 // false表示未实名,如果渠道没返回默认为false boolean realName = jsonObject.getBoolean("realName"); // oppo实名认证失败之后是否可以继续游戏 true表示可以 // false表示不可以,如果渠道没返回默认为true boolean resumeGame = jsonObject.getBoolean("resumeGame"); // 预留字段,如果渠道没返回默认为""的字符串 String other = jsonObject.getString("other"); // 游戏根据返回信息做对应的逻辑处理 } catch (JSONException e) { } } } @Override public void onFailed(Object... arg0) { } }); } } }); } } Project/qkbtzf/src/game_qk/java/com/secondworld/universalsdk/QuickPlatformUtil.java
New file @@ -0,0 +1,226 @@ package com.secondworld.universalsdk; import android.app.Activity; import com.quicksdk.QuickSDK; import com.quicksdk.User; import com.quicksdk.entity.UserInfo; import com.quicksdk.notifier.ExitNotifier; import com.quicksdk.notifier.InitNotifier; import com.quicksdk.notifier.LoginNotifier; import com.quicksdk.notifier.LogoutNotifier; import com.quicksdk.notifier.PayNotifier; import com.quicksdk.notifier.SwitchAccountNotifier; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2020/8/25 0025. */ public class QuickPlatformUtil { private static QuickPlatformUtil m_Instance; private static final String TAG = "QKPlatformUtil"; public static QuickPlatformUtil getInstance() { if (m_Instance == null) { m_Instance = new QuickPlatformUtil(); } return m_Instance; } private Map<String, Object> m_Message = new HashMap<>(); public boolean payProcessing = false; private UserInfo USER; public Boolean isInited = false; public void onCreate(){ QuickSDK.getInstance().setInitNotifier(new InitNotifier() { @Override public void onSuccess() { m_Message.clear(); m_Message.put("code", CodeA2U.FreePlatformInitOk); UniversalUtil.sendMessageToUnity(m_Message); isInited = true; } @Override public void onFailed(String s, String s1) { m_Message.clear(); m_Message.put("code", CodeA2U.FreePlatformInitFail); UniversalUtil.sendMessageToUnity(m_Message); } }); QuickSDK.getInstance().setLoginNotifier(new LoginNotifier() { @Override public void onSuccess(UserInfo userInfo) { //登录成功,获取到用户信息userInfo //通过userInfo中的UID、token做服务器登录认证 m_Message.clear(); USER = userInfo; //根据回调获取用户信息 String token = USER.getToken(); //通知到unity中的账号已经加上渠道ID,保证appid和spid唯一对应 String userId = USER.getUID() + "@" + com.quicksdk.Extend.getInstance().getChannelType(); String userName = USER.getUserName(); try { JSONObject _info = new JSONObject(); _info.put("account", userId); _info.put("token", token); _info.put("userName", USER.getUID()); m_Message.put("code", CodeA2U.FreePlatformLoginOk); m_Message.put("info", _info); UniversalUtil.sendMessageToUnity(m_Message); } catch (JSONException e) { e.printStackTrace(); } } @Override public void onCancel() { //登录取消 m_Message.clear(); m_Message.put("code", CodeA2U.FreePlatformLoginFail); UniversalUtil.sendMessageToUnity(m_Message); } @Override public void onFailed(final String message, String trace) { //登录失败 m_Message.clear(); m_Message.put("code", CodeA2U.FreePlatformLoginFail); UniversalUtil.sendMessageToUnity(m_Message); } }); QuickSDK.getInstance().setLogoutNotifier(new LogoutNotifier() { @Override public void onSuccess() { //注销成功 m_Message.clear(); //需要把游戏切换回登陆前的场景,并重新弹出登录框等操作 m_Message.put("code", CodeA2U.FreePlatformLogoutOk); UniversalUtil.sendMessageToUnity(m_Message); } @Override public void onFailed(String message, String trace) { //注销失败,不做处理 } }); QuickSDK.getInstance().setSwitchAccountNotifier(new SwitchAccountNotifier() { @Override public void onSuccess(UserInfo userInfo) { //切换账号成功的回调,返回新账号的userInfo m_Message.clear(); USER = userInfo; //根据回调获取用户信息 String token = USER.getToken(); //通知到unity中的账号已经加上渠道ID,保证appid和spid唯一对应 String userId = USER.getUID() + "@" + com.quicksdk.Extend.getInstance().getChannelType(); String userName = USER.getUserName(); try { JSONObject _info = new JSONObject(); _info.put("userName", USER.getUID()); _info.put("token", token); _info.put("account", userId); m_Message.put("code", CodeA2U.FreePlatformSwitchAccountOk); m_Message.put("info", _info); UniversalUtil.sendMessageToUnity(m_Message); } catch (JSONException e) { e.printStackTrace(); } } @Override public void onCancel() { //切换账号取消 } @Override public void onFailed(String message, String trace) { //切换账号失败 } }); QuickSDK.getInstance().setPayNotifier(new PayNotifier() { @Override public void onSuccess(String sdkOrderID, String cpOrderID, String extrasParams) { //支付成功 // sdkOrderID:quick订单号 cpOrderID:游戏订单号 LogUtil.i(TAG, "Pay Success Info sdkOrderID: " + sdkOrderID + "cpOrderID: " + cpOrderID); m_Message.clear(); //根据回调获取支付订单信息 m_Message.put("code", CodeA2U.FreePlatformPayOk); UniversalUtil.sendMessageToUnity(m_Message); payProcessing = false; } @Override public void onCancel(String cpOrderID) { //支付取消 m_Message.clear(); //根据回调获取支付订单信息 LogUtil.i(TAG, "Pay Fail Info cpOrderID: " + cpOrderID); m_Message.put("code", CodeA2U.FreePlatformPayCancel); UniversalUtil.sendMessageToUnity(m_Message); payProcessing = false; } @Override public void onFailed(String cpOrderID, String message, String trace) { //支付失败 m_Message.clear(); //根据回调获取支付订单信息 LogUtil.i(TAG, "Pay Fail Info cpOrderID: " + cpOrderID); m_Message.put("code", CodeA2U.FreePlatformPayFail); UniversalUtil.sendMessageToUnity(m_Message); payProcessing = false; } }); QuickSDK.getInstance().setExitNotifier(new ExitNotifier() { @Override public void onSuccess() { //退出成功,游戏在此做自身的退出逻辑处理 m_Message.clear(); m_Message.put("code", CodeA2U.ExitGame); UniversalUtil.sendMessageToUnity(m_Message); payProcessing = false; } @Override public void onFailed(String message, String trace) { //退出失败,不做处理 } }); } public void login(final Activity activity) { User.getInstance().login(activity); } public void logout(final Activity activity) { User.getInstance().logout(activity); } } Project/qkbtzf/src/game_qk/java/com/secondworld/universalsdk/SplashActivity.java
New file @@ -0,0 +1,20 @@ package com.secondworld.universalsdk; import android.content.Intent; import com.quicksdk.QuickSdkSplashActivity; public class SplashActivity extends QuickSdkSplashActivity { @Override public int getBackgroundColor() { return 0; } @Override public void onSplashStop() { Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } } Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load01.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load02.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load03.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load04.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load05.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load06.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load07.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_load08.png
Project/qkbtzf/src/game_qk/res/drawable-hdpi/qk_game_loadbg.png
Project/qkbtzf/src/game_qk/res/drawable/qk_game_loading.xml
New file @@ -0,0 +1,30 @@ <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" > <item android:drawable="@drawable/qk_game_load01" android:duration="50"/> <item android:drawable="@drawable/qk_game_load02" android:duration="50"/> <item android:drawable="@drawable/qk_game_load03" android:duration="50"/> <item android:drawable="@drawable/qk_game_load04" android:duration="50"/> <item android:drawable="@drawable/qk_game_load05" android:duration="50"/> <item android:drawable="@drawable/qk_game_load06" android:duration="50"/> <item android:drawable="@drawable/qk_game_load07" android:duration="50"/> <item android:drawable="@drawable/qk_game_load08" android:duration="50"/> </animation-list> Project/qkbtzf/src/game_qk/res/layout/qk_game_view_loading.xml
New file @@ -0,0 +1,14 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:id="@+id/qk_img_loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="center" android:src="@drawable/qk_game_loading" /> </LinearLayout> Project/qkbtzf/src/game_qk/res/values/qk_game_style.xml
New file @@ -0,0 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <!-- 自定义loading dialog --> <style name="qk_game_style_loading" parent="android:style/Theme.Dialog"> <item name="android:windowFrame">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@drawable/qk_game_loadbg</item> <item name="android:windowIsFloating">true</item> <item name="android:windowContentOverlay">@null</item> </style> </resources> Project/qkbtzf/src/main/java/com/secondworld/universalsdk/BatteryUtil.java
New file @@ -0,0 +1,124 @@ package com.secondworld.universalsdk; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2018/7/15 0015. */ public class BatteryUtil { private static BatteryUtil s_Instance = null; public static BatteryUtil getInstance() { if (s_Instance == null) { s_Instance = new BatteryUtil(); } return s_Instance; } private BatteryBroadCastReceiver m_BatteryBroadCastReceiver; private BatteryUtil() {} public void start(Context context) { m_BatteryBroadCastReceiver = new BatteryBroadCastReceiver(); IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); context.registerReceiver(m_BatteryBroadCastReceiver, filter); } public void stop(Context context) { if (m_BatteryBroadCastReceiver != null) { try{ context.unregisterReceiver(m_BatteryBroadCastReceiver); m_BatteryBroadCastReceiver = null; }catch (IllegalArgumentException e) { if (!e.getMessage().contains("Receiver not registered")) { throw e; } } } } private class BatteryBroadCastReceiver extends BroadcastReceiver { private int m_BatteryLevel; private int m_Status; public BatteryBroadCastReceiver() { m_BatteryLevel = 0; } @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { int _batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); Map<String, Object> _msg = new HashMap<>(); if (_batteryLevel != m_BatteryLevel) { try { _msg.put("code", CodeA2U.BatteryLevel); _msg.put("level", _batteryLevel); UniversalUtil.sendMessageToUnity(_msg); m_BatteryLevel = _batteryLevel; } catch (Exception e) { e.printStackTrace(); } } int _status = intent.getIntExtra("status", 0); if (_status != m_Status) { _msg.clear(); int _transCode = 0; if (_status == BatteryManager.BATTERY_STATUS_CHARGING) { _transCode = 2; } else if (_status == BatteryManager.BATTERY_STATUS_NOT_CHARGING || _status == BatteryManager.BATTERY_STATUS_DISCHARGING) { _transCode = 1; } else if (_status == BatteryManager.BATTERY_STATUS_FULL) { _transCode = 3; } _msg.put("code", CodeA2U.BatteryCharging); _msg.put("status", _transCode); UniversalUtil.sendMessageToUnity(_msg); m_Status = _status; } } } } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/CodeA2U.java
New file @@ -0,0 +1,63 @@ package com.secondworld.universalsdk; /** * Created by Administrator on 2018/7/18 0018. */ public class CodeA2U { /** * 资源拷贝完成 */ public static final int AssetCopyFinished = 0; /** * 电量改变 */ public static final int BatteryLevel = 1; /** * 充电状态改变 */ public static final int BatteryCharging = 2; /** * 回调sdk逻辑完毕 * */ public static final int SdkInitComplete = 90; /** * 回调android设备信息 * */ public static final int DeviceInfo = 3; /** * 回调推送的独立id * */ public static final int PushClientID = 4; /** * 回调外部存储根目录地址 */ public static final int ExternalStorage = 5; /** * 触发了退出游戏逻辑, 打开二次确认界面 */ public static final int ExitGame = 6; /** * -------------------------------------------------------------------------------------------- * 以下为各自项目SDK相关 * -------------------------------------------------------------------------------------------- */ // ------------------------------------------------------------------------------------------ // 自由SDK相关回调Code // ------------------------------------------------------------------------------------------ public static final int FreePlatformInitOk = 10; public static final int FreePlatformInitFail = 11; public static final int FreePlatformLoginOk = 12; public static final int FreePlatformLoginFail = 13; public static final int FreePlatformLoginCancel = 14; public static final int FreePlatformLogoutOk = 15; public static final int FreePlatformLogoutFail = 16; public static final int FreePlatformSwitchAccountOk = 17; public static final int FreePlatformPayOk = 18; public static final int FreePlatformPayFail = 19; public static final int FreePlatformPayCancel = 20; public static final int FreePlatformRegisterOk = 21; } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/CodeU2A.java
New file @@ -0,0 +1,87 @@ package com.secondworld.universalsdk; /** * Created by Administrator on 2018/7/18 0018. */ public class CodeU2A { /** * 执行资源拷贝 */ public static final int AssetCopy = 0; /** * 执行开始电量改变,充电状态改变监听 */ public static final int BatteryListenStart = 1; /** * 执行停止电量改变,充电状态改变监听 */ public static final int BatteryListenStop = 2; /** * 获取唯一识别码 */ public static final int UniqueID = 3; /** * 申请在AndroidManifest文件中 */ public static final int RequestManifestPermissions = 4; /** * 单独动态申请某一个权限 */ public static final int RequestPermission = 5; /** * 重启应用 */ public static final int RestartApp = 6; /** * 拷贝文本信息 */ public static final int CopyContent = 7; /** * 打开网址 */ public static final int OpenWebView = 8; /** * SDK初始化, 完全自动初始化的流程, 完成必要逻辑后再回调回去 */ public static final int Init = 9; /** * 安装应用 */ public static final int InstallAPK = 10; /** * 外部存储根目录地址 */ public static final int ExteneralStorage = 11; public static final int CopyOneAsset = 12; /** * -------------------------------------------------------------------------------------------- * 以下为各自项目SDK相关 * -------------------------------------------------------------------------------------------- */ /** * 自由sdk相关 * */ public static final int FreePlatformInit = 100; public static final int FreePlatformLogin = 101; public static final int FreePlatformLogout = 102; public static final int FreePlatformSwitchAccount = 103; public static final int FreePlatformPay = 104; public static final int PayFinished = 105; public static final int CreateRole = 106; public static final int RoleLogin = 107; public static final int RoleLevelUp = 108; public static final int TencentLogin = 109; /** * 极光推送 * */ public static final int JPushAddLocalMessage = 200; public static final int JPushRemoveLocalMessage = 201; /** * ClientPackage向sdk发送分包id */ public static final int ClientPackage = 400; public static final int SendRegistEvent = 500; } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/CrashCatchUtil.java
New file @@ -0,0 +1,233 @@ package com.secondworld.universalsdk; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.os.Looper; import android.os.SystemClock; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2018/7/19 0019. */ public class CrashCatchUtil implements Thread.UncaughtExceptionHandler { private static final String TAG = "CrashCatchUtil"; private Context m_Context; private Thread.UncaughtExceptionHandler m_UncaughtExceptionHandler; private Map<String, String> m_DevicceInfo = new HashMap<>(); private CrashCatchUtil() {} private static CrashCatchUtil m_Instance; public static CrashCatchUtil getInstance() { if (m_Instance == null) { m_Instance = new CrashCatchUtil(); } return m_Instance; } public void init(Context context) { m_Context = context; m_UncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); autoClear(5); } @Override public void uncaughtException(Thread thread, Throwable throwable) { if (!handleException(throwable) && m_UncaughtExceptionHandler != null) { m_UncaughtExceptionHandler.uncaughtException(thread, throwable); } else { SystemClock.sleep(3000); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } private void recordDeviceInfo() { m_DevicceInfo.clear(); m_DevicceInfo.put("brand", Build.BRAND); m_DevicceInfo.put("model", Build.MODEL); m_DevicceInfo.put("android_version", String.valueOf(Build.VERSION.SDK_INT)); try { PackageManager _pkgMgr = m_Context.getPackageManager(); PackageInfo _pkgInfo = _pkgMgr.getPackageInfo(m_Context.getPackageName(), PackageManager.GET_ACTIVITIES); if (_pkgInfo != null) { m_DevicceInfo.put("versionName", _pkgInfo.versionName); m_DevicceInfo.put("versionCode", String.valueOf(_pkgInfo.versionCode)); } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } private boolean handleException(Throwable throwable) { if (throwable == null) { return false; } try { new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Toast.makeText(m_Context, "程序出现异常,即将重启", Toast.LENGTH_LONG).show(); Looper.loop(); } }).start(); recordDeviceInfo(); save(throwable); SystemClock.sleep(3000); } catch (Exception e) { e.printStackTrace(); } return true; } private String save(Throwable throwable) throws Exception { StringBuffer sb = new StringBuffer(); try { SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date = sDateFormat.format(new Date()); sb.append("\r\n" + date + "\n"); for (Map.Entry<String, String> entry : m_DevicceInfo.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); throwable.printStackTrace(printWriter); Throwable cause = throwable.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.flush(); printWriter.close(); String result = writer.toString(); sb.append(result); String fileName = writeFile(sb.toString()); return fileName; } catch (Exception e) { sb.append("写入崩溃日志时, 出现了异常状况...\r\n"); writeFile(sb.toString()); } return null; } private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); private String writeFile(String sb) throws Exception { String time = formatter.format(new Date()); String fileName = "crash-" + time + ".log"; String path = getPath(); File dir = new File(getPath()); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = new FileOutputStream(path + fileName, true); fos.write(sb.getBytes()); fos.flush(); fos.close(); return fileName; } private String getPath() { return m_Context.getExternalFilesDir("").getAbsolutePath() + File.separator + "crash" + File.separator; } /** * 文件删除 * * @param autoClearDay 文件保存天数 */ public void autoClear(final int autoClearDay) { delete(getPath(), new FilenameFilter() { @Override public boolean accept(File file, String filename) { String s = FileUtil.getFileNameWithoutExtension(filename); int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay; String date = "crash-" + getOtherDay(day); return date.compareTo(s) >= 0; } }); } private void delete(String path, FilenameFilter filter) { File _file = new File(path); if (!_file.exists()) { return; } File[] _files = _file.listFiles(filter); for (int i = _files.length - 1; i >= 0; i--) { _files[i].delete(); } } private String getOtherDay(int offset) { Calendar _calendar = Calendar.getInstance(); _calendar.add(Calendar.DATE, offset); return formatter.format(_calendar.getTime()); } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/DebugUtil.java
New file @@ -0,0 +1,59 @@ package com.secondworld.universalsdk; import android.app.Activity; import android.os.Environment; import android.util.Log; import java.io.File; /** * Created by Administrator on 2018/7/20 0020. */ public class DebugUtil { private final String TAG = "DebugUtil"; private static DebugUtil s_Instance; public static DebugUtil getInstance() { if (s_Instance == null) { s_Instance = new DebugUtil(); } return s_Instance; } private DebugUtil() {} private boolean m_Enable = false; private Activity m_Activity; public void init(Activity activity) { m_Activity = activity; String _path = Environment.getExternalStorageDirectory() + File.separator + activity.getPackageName(); Log.i(TAG, _path); File _dir = new File(_path); if (!_dir.exists()) { _dir.mkdir(); } _path = _path + File.separator + "SdkDebug"; _dir = new File(_path); m_Enable = _dir.exists(); if(m_Enable){ Log.i(TAG, "--------- SDK调试模式: 开启 ---------"); }else{ Log.i(TAG, "--------- SDK调试模式: 关闭 ---------"); } } public boolean enable() { return m_Enable; } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/FileUtil.java
New file @@ -0,0 +1,211 @@ package com.secondworld.universalsdk; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.content.res.AssetManager; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2018/6/14 0014. */ public class FileUtil { private static final String TAG = "H2Engine_FileUtil"; /** * Unity随包资源(StreamingAssets)拷贝至 persistentDataPath 路径下 */ public static void copyAssets(final Activity activity) { // 判断是否已经执行过 SharedPreferences _sp = activity.getPreferences(Context.MODE_PRIVATE); Boolean _isCopied = hasCopy(activity); LogUtil.i(TAG, "是否已经执行过拷贝逻辑: " + _isCopied); // 获取当前包的版本号 final String _currentVer = UniversalUtil.GetVersionName(activity); // 已经拷贝过, 则再次判断一次版本号 // 如果版本号不相同, 则重新进行拷贝 // 获取本地存储的版本号 String _installVer = _sp.getString(StaticDefine.LS_KEY_VERSION, ""); if (!_installVer.equals(_currentVer)) { LogUtil.i(TAG, "版本比较过后发现不同: " + _installVer + " != " + _currentVer); SharedPreferences.Editor _editor = _sp.edit(); // 存储此次的版本信息 _editor.putString(StaticDefine.LS_KEY_VERSION, _currentVer); _editor.apply(); if (_isCopied) { // 将本地存储修改为未拷贝过 deleteRecord(activity); _isCopied = false; } } if (_isCopied) { Map<String, Object> _msg = new HashMap<>(); _msg.put("code", CodeA2U.AssetCopyFinished); UniversalUtil.sendMessageToUnity(_msg); return; } new Thread(new Runnable() { @Override public void run() { String _dest = activity.getExternalFilesDir("").getAbsolutePath(); AssetManager _assetMgr = activity.getAssets(); try { String[] _fileNames = _assetMgr.list("android"); if (_fileNames != null) { for (String _fileName : _fileNames) { copy(activity, "android" + File.separator + _fileName, _dest + File.separator + _fileName); } } recordCopy(activity); Map<String, Object> _msg = new HashMap<>(); _msg.put("code", CodeA2U.AssetCopyFinished); UniversalUtil.sendMessageToUnity(_msg); } catch (Exception e) { e.printStackTrace(); } } }).start(); } public static void copy(Context context, String fileName) { String _originalPath = "android" + File.separator + fileName; String _destPath = context.getExternalFilesDir( "").getAbsolutePath() + File.separator + fileName; String _destDir = _destPath.substring(0, _destPath.lastIndexOf('/') + 1); File _file = new File(_destDir); if(!_file.exists()) { LogUtil.i(TAG,"单独拷贝 => 不存在指定路径: " + _destDir + ", 这里创建..."); _file.mkdir(); } try { InputStream _is = context.getAssets().open(_originalPath); FileOutputStream _fos = new FileOutputStream(new File(_destPath)); byte[] _buffer = new byte[1024]; int _byteCount; while ((_byteCount = _is.read(_buffer)) != -1) { _fos.write(_buffer, 0, _byteCount); } _fos.flush(); _is.close(); _fos.close(); LogUtil.i("FileUtil", "单独拷贝 => 文件: " + _originalPath + " 已拷贝至: " + _destPath); } catch (Exception e) { e.printStackTrace(); } } public static void copy(Context context, String original, String dest) { try { String _fileNames[] = context.getAssets().list(original); if (_fileNames.length > 0) { File _dir = new File(dest); _dir.mkdir(); LogUtil.i("FileUtil", "[" + original + "] 是一个文件夹, 创建文件夹: [" + dest + "]"); for (String _fileName : _fileNames) { copy(context, original + File.separator + _fileName, dest + File.separator + _fileName); } } else { InputStream _is = context.getAssets().open(original); FileOutputStream _fos = new FileOutputStream(new File(dest)); byte[] _buffer = new byte[1024]; int _byteCount; while ((_byteCount = _is.read(_buffer)) != -1) { _fos.write(_buffer, 0, _byteCount); } _fos.flush(); _is.close(); _fos.close(); LogUtil.i("FileUtil", "文件: " + original + " 已拷贝至: " + dest); } } catch (Exception e) { e.printStackTrace(); } } public static String getFileNameWithoutExtension(String fileName) { return fileName.substring(0, fileName.lastIndexOf(".")); } private static boolean hasCopy(Context context) { File _file = new File(context.getExternalFilesDir(""), "/assetCopyFinish.txt"); return _file.exists(); } private static void deleteRecord(Context context) { File _file = new File(context.getExternalFilesDir(""), "/assetCopyFinish.txt"); if (_file.exists()) { _file.delete(); } } private static void recordCopy(Context context) { File _file = new File(context.getExternalFilesDir(""), "/assetCopyFinish.txt"); try { FileOutputStream _fos = new FileOutputStream(_file); Writer _writer = new OutputStreamWriter(_fos, "UTF-8"); _writer.write(1); _writer.close(); _fos.close(); } catch (IOException e) { e.printStackTrace(); } } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/JPushReceiver.java
New file @@ -0,0 +1,147 @@ package com.secondworld.universalsdk; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import java.util.HashMap; import java.util.Map; import cn.jpush.android.api.JPushInterface; /** * Created by Administrator on 2018/6/16 0016. */ public class JPushReceiver extends BroadcastReceiver { private static final String TAG = "JPushReceiver"; @Override public void onReceive(Context context, Intent intent) { try { Bundle bundle = intent.getExtras(); Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle( bundle)); if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) { String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID); Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId); //send the Registration Id to your server... Map<String, Object> _msgStruct = new HashMap<>(); _msgStruct.put("code", CodeA2U.PushClientID); _msgStruct.put("clientID", regId); UniversalUtil.sendMessageToUnity(_msgStruct); } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) { processCustomMessage(context, bundle); } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) { Log.d(TAG, "[MyReceiver] 接收到推送下来的通知"); int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID); Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId); } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) { Log.d(TAG, "[MyReceiver] 用户点击打开了通知"); //打开自定义的Activity Intent i = new Intent(context, MainActivity.class); i.putExtras(bundle); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(i); } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) { Log.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString( JPushInterface.EXTRA_EXTRA)); //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等.. } else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) { boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false); Log.w(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected); } else { Log.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction()); } } catch (Exception e) { } } // 打印所有的 intent extra 数据 private static String printBundle(Bundle bundle) { StringBuilder sb = new StringBuilder(); // for (String key : bundle.keySet()) { // if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) { // sb.append("\nkey:" + key + ", value:" + bundle.getInt(key)); // }else if(key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)){ // sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key)); // } else if (key.equals(JPushInterface.EXTRA_EXTRA)) { // if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) { // Logger.i(TAG, "This message has no Extra data"); // continue; // } // // try { // JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA)); // Iterator<String> it = json.keys(); // // while (it.hasNext()) { // String myKey = it.next(); // sb.append("\nkey:" + key + ", value: [" + // myKey + " - " +json.optString(myKey) + "]"); // } // } catch (JSONException e) { // Logger.e(TAG, "Get message extra JSON error!"); // } // // } else { // sb.append("\nkey:" + key + ", value:" + bundle.get(key)); // } // } return sb.toString(); } // public static final String KEY_TITLE = "title"; // public static final String KEY_MESSAGE = "message"; // public static final String KEY_EXTRAS = "extras"; //send msg to MainActivity private void processCustomMessage(Context context, Bundle bundle) { Log.d(TAG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!![MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString( JPushInterface.EXTRA_MESSAGE)); // if (MainActivity.isForeground) { // String message = bundle.getString(JPushInterface.EXTRA_MESSAGE); // String extras = bundle.getString(JPushInterface.EXTRA_EXTRA); // Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION); // msgIntent.putExtra(MainActivity.KEY_MESSAGE, message); // if (!UniversalUtil.isEmpty(extras)) { // try { // JSONObject extraJson = new JSONObject(extras); // if (extraJson.length() > 0) { // msgIntent.putExtra(MainActivity.KEY_EXTRAS, extras); // } // } catch (JSONException e) { // // } // // } // LocalBroadcastManager.getInstance(context).sendBroadcast(msgIntent); // } } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/LogUtil.java
New file @@ -0,0 +1,114 @@ package com.secondworld.universalsdk; import android.app.Activity; import android.util.Log; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by Administrator on 2018/7/25 0025. */ public class LogUtil { private static final String Global_TAG = "h2EngineSdk"; private static final String TAG = "LogUtil"; public static boolean UPLOAD = false; private static boolean SAVE = false; private static boolean SHOW = true; private final static SimpleDateFormat m_DateFormatMS = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS"); private final static SimpleDateFormat m_DateFormatDay = new SimpleDateFormat("yyyy-MM-dd"); private static Activity m_Activity; public static void init(Activity activity, boolean showLog) { m_Activity = activity; SHOW = showLog; File _file = new File(getPath()); if (_file.exists()) { SAVE = true; i(TAG, "启动本地log存储功能"); } else { SAVE = false; i(TAG, "未启动本地log存储功能"); } } public static void i(String tag, String content) { content = ("[" + m_DateFormatMS.format(new Date()) + "]") + "[" + tag + "] " + content; Log.i(Global_TAG, content); if (SAVE) { write(content); } } public static void w(String tag, String content) { content = ("[" + m_DateFormatMS.format(new Date()) + "]") + "[" + tag + "] " + content; Log.w(Global_TAG, content); if (SAVE) { write(content); } } public static void e(String tag, String content) { content = ("[" + m_DateFormatMS.format(new Date()) + "]") + "[" + tag + "] " + content; Log.e(Global_TAG, content); if (SAVE) { write(content); } } private static String getPath() { if (m_Activity.getExternalFilesDir("") == null) { Log.i(TAG,"m_Activity.getExternalFilesDir(\"\") == null"); return ""; } return m_Activity.getExternalFilesDir("").getAbsolutePath() + File.separator + "debugLog" + File.separator; } private static void write(String content) { try { String time = m_DateFormatDay.format(new Date()); String fileName = "log_" + time + ".log"; FileOutputStream fos = new FileOutputStream(getPath() + fileName, true); fos.write(content.getBytes()); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } public static void upLoad() { if (!UPLOAD) { return; } } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/MainActivity.java
New file @@ -0,0 +1,339 @@ package com.secondworld.universalsdk; import android.Manifest; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; import android.os.Process; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.content.PermissionChecker; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.Toast; import com.quicksdk.QuickSDK; import com.quicksdk.Sdk; import com.secondworld.univeralsdk.R; import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; import android.util.DisplayMetrics; public class MainActivity extends UnityPlayerActivity { private static final String TAG = "MainActivity"; public static boolean isForeground = false; // 启用6.0以上权限回调code private final int REQUEST_RECORD_PERMISSION_SETTING = 999; public static final int SHOW_TENCENT_LOGIN = 0; public static final int HIDE_TENCENT_LOGIN = 1; private RelativeLayout m_MainContainer; private int mType; private boolean isNotch = false; private int gameWidth; private int gameHeight; @Override protected void onCreate(Bundle savedInstanceState) { // sInstance = this; super.onCreate(savedInstanceState); // LogUtil.i(TAG, "onCreate"); LogUtil.init(this, true); setContentView(R.layout.activity_main); m_MainContainer = (RelativeLayout) findViewById(R.id.main_container); String _brand = NotchPhoneUtil.getDeviceBrand(); if (_brand.toUpperCase().contains("VIVO")) { isNotch = NotchPhoneUtil.HasNotchVivo(MainActivity.this); mType = 1; } else if (_brand.toUpperCase().contains("HUAWEI") || _brand.toUpperCase().contains("HONOR")) { // isNotch = NotchPhoneUtil.hasNotchAtHuawei(this);; // mType = 2; } else if (_brand.toUpperCase().contains("OPPO")) { isNotch = NotchPhoneUtil.HasNotchOPPO(MainActivity.this); mType = 3; } else if (_brand.toUpperCase().contains("XIAOMI")) { isNotch = NotchPhoneUtil.HasNotchXiaoMi(); mType = 4; } NotchPhoneUtil.onConfigurationChanged(this, isNotch, mType, m_MainContainer); FrameLayout _frameLayout = (FrameLayout) findViewById(R.id.unity_view); View unityView = mUnityPlayer.getView(); _frameLayout.addView(unityView); //H2EngineSDK.onCreate(this, savedInstanceState); Sdk.getInstance().onCreate(this); try { // check权限 if ((ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) || (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) { // 没有 , 申请权限 权限数组 ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 1); } else { QuickPlatformUtil.getInstance().onCreate(); Sdk.getInstance().init(this,"16738592021815700006389081047799", "46221152"); } } catch (Exception e) { QuickPlatformUtil.getInstance().onCreate(); Sdk.getInstance().init(this, "16738592021815700006389081047799", "46221152"); } QuickSDK.getInstance().setIsLandScape(true); DisplayMetrics dm = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(dm); if(gameWidth == 0){ gameWidth = dm.widthPixels; } if(gameHeight == 0) { gameHeight = dm.heightPixels; } } @Override public void onWindowFocusChanged(boolean b) { //LogUtil.i(TAG, "onWindowFocusChanged: " + b); super.onWindowFocusChanged(b); H2EngineSDK.onWindowFocusChanged(b); } @Override protected void onNewIntent(Intent intent) { //LogUtil.i(TAG, "onNewIntent"); super.onNewIntent(intent); H2EngineSDK.onNewIntent(this, intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //LogUtil.i(TAG, "onActivityResult"); H2EngineSDK.onActivityResult(requestCode, resultCode, data, this); super.onActivityResult(requestCode, resultCode, data); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (grantResults != null && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 申请成功 QuickPlatformUtil.getInstance().onCreate(); if (!QuickPlatformUtil.getInstance().isInited) { Sdk.getInstance().init(this, "16738592021815700006389081047799", "46221152"); } } else { // 失败 这里逻辑以游戏为准 这里只是模拟申请失败 退出游戏 cp方可改为继续申请 或者其他逻辑 Log.e("Unity", "onRequestPermissionsResult Fail"); if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) && ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE) && ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) { Log.d("Unity", "ActivityCompat shouldShowRequestPermissionRationale true"); } else { Log.e("Unity", "ActivityCompat shouldShowRequestPermissionRationale false"); final AlertDialog.Builder normalDialog = new AlertDialog.Builder(this); normalDialog.setTitle("权限设置"); normalDialog.setMessage("请在设置中打开权限"); normalDialog.setPositiveButton("前往应用设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // ...To-do Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivityForResult(intent, REQUEST_RECORD_PERMISSION_SETTING); QuickPlatformUtil.getInstance().onCreate(); Sdk.getInstance().init(UnityPlayer.currentActivity, "16738592021815700006389081047799", "46221152"); } }); normalDialog.setNegativeButton("关闭", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(UnityPlayer.currentActivity, "权限被拒绝", Toast.LENGTH_SHORT).show(); QuickPlatformUtil.getInstance().onCreate(); Sdk.getInstance().init(UnityPlayer.currentActivity, "16738592021815700006389081047799", "46221152"); } }); // 显示 normalDialog.show(); } } } @Override public void onConfigurationChanged(Configuration newConfig) { //LogUtil.i(TAG, "onConfigurationChanged"); if (isNotch) { NotchPhoneUtil.onConfigurationChanged(this, isNotch, mType, m_MainContainer); } else { mUnityPlayer.getView().getLayoutParams().width = gameWidth; mUnityPlayer.getView().getLayoutParams().height = gameHeight; } H2EngineSDK.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig); } @Override protected void onStart() { LogUtil.i(TAG, "onStart"); H2EngineSDK.onStart(this); super.onStart(); } @Override protected void onStop() { //LogUtil.i(TAG, "onStop"); isForeground = false; H2EngineSDK.onStop(this); super.onStop(); } @Override protected void onResume() { //LogUtil.i(TAG, "onResume"); isForeground = true; H2EngineSDK.onResume(this); super.onResume(); // 检测本地存储权限是否有, 没有的话要提示用户 // if (PermissionChecker.checkPermission(this, // Manifest.permission.WRITE_EXTERNAL_STORAGE, // Process.myPid(), Process.myUid(), // getPackageName()) != PackageManager.PERMISSION_GRANTED // || PermissionChecker.checkPermission(this, // Manifest.permission.READ_EXTERNAL_STORAGE, // Process.myPid(), Process.myUid(), // getPackageName()) != PackageManager.PERMISSION_GRANTED) // { // new AlertDialog.Builder(this) // .setMessage("应用没有存储读取权限,点击确定至设置中开启,否则无法继续游戏.") // .setCancelable(false) // .setPositiveButton("确定", // new DialogInterface.OnClickListener() // { // @Override // public void onClick(DialogInterface dialogInterface, // int i) // { // UniversalUtil.hasGoToSetting = true; // Intent intent = new Intent( // Settings.ACTION_APPLICATION_DETAILS_SETTINGS); // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Uri uri = Uri.fromParts("package", // getPackageName(), // null); // intent.setData(uri); // startActivity(intent); // } // }) // .setNegativeButton("拒绝", // new DialogInterface.OnClickListener() // { // @Override // public void onClick(DialogInterface dialogInterface, // int i) // { // finish(); // } // }) // .show(); // } } @Override protected void onPause() { //LogUtil.i(TAG, "onPause"); H2EngineSDK.onPause(this); super.onPause(); } @Override protected void onDestroy() { //LogUtil.i(TAG, "onDestroy"); H2EngineSDK.onDestroy(this); super.onDestroy(); } @Override protected void onRestart() { //LogUtil.i(TAG, "onRestart"); H2EngineSDK.onRestart(this); super.onRestart(); } @Override public boolean onKeyDown(int i, KeyEvent keyEvent) { if (i == KeyEvent.KEYCODE_BACK) { if(QuickSDK.getInstance().isShowExitDialog()){ Sdk.getInstance().exit(this); } else{ // 游戏调用自身的退出对话框,点击确定后,调用quick的exit接口 new AlertDialog.Builder(MainActivity.this).setTitle("退出").setMessage("是否退出游戏?").setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { Sdk.getInstance().exit(MainActivity.this); } }).setNegativeButton("取消", null).show(); } } return super.onKeyDown(i, keyEvent); } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/NotchPhoneUtil.java
New file @@ -0,0 +1,347 @@ package com.secondworld.universalsdk; import android.app.Activity; import android.content.Context; import android.view.Surface; import android.view.ViewGroup; import android.widget.FrameLayout; import java.lang.reflect.Method; /** * Created by Administrator on 2018/9/11 0011. */ public class NotchPhoneUtil { private final static String TAG = "Notch"; /** * 华为手机判断是不是刘海手机 * * @param context * @return */ public static boolean hasNotchAtHuawei(Context context) { boolean ret = false; try { ClassLoader classLoader = context.getClassLoader(); Class HwNotchSizeUtil = classLoader.loadClass( "com.huawei.android.util.HwNotchSizeUtil"); Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen"); ret = (boolean) get.invoke(HwNotchSizeUtil); } catch (ClassNotFoundException e) { LogUtil.e(TAG, "hasNotchAtHuawei ClassNotFoundException"); } catch (NoSuchMethodException e) { LogUtil.e(TAG, "hasNotchAtHuawei NoSuchMethodException"); } catch (Exception e) { LogUtil.e(TAG, "hasNotchAtHuawei Exception"); } finally { return ret; } } /** * 华为手机获取刘海的宽高 * int[0]值为刘海宽度 int[1]值为刘海高度 */ public static int[] getNotchSizeAtHuawei(Context context) { int[] ret = new int[]{0, 0}; try { ClassLoader cl = context.getClassLoader(); Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil"); Method get = HwNotchSizeUtil.getMethod("getNotchSize"); ret = (int[]) get.invoke(HwNotchSizeUtil); } catch (ClassNotFoundException e) { LogUtil.e(TAG, "getNotchSizeAtHuawei ClassNotFoundException"); } catch (NoSuchMethodException e) { LogUtil.e(TAG, "getNotchSizeAtHuawei NoSuchMethodException"); } catch (Exception e) { LogUtil.e(TAG, "getNotchSizeAtHuawei Exception"); } finally { return ret; } } /** * OPPO判断是不是刘海手机, * OPPO不提供接口获取刘海尺寸,目前其有刘海屏的机型尺寸规格都是统一的。不排除以后机型会有变化。 * 刘海区域则都是宽度为324px, 高度为80px。 * * @param context * @return */ public static boolean HasNotchOPPO(Context context) { return context.getPackageManager().hasSystemFeature( "com.oppo.feature.screen.heteromorphism"); } public static final int VIVO_NOTCH = 0x00000020;//是否有刘海 /** * vivo判断是不是刘海手机 */ public static boolean HasNotchVivo(Context context) { boolean ret = false; try { ClassLoader classLoader = context.getClassLoader(); Class FtFeature = classLoader.loadClass("android.util.FtFeature"); Method method = FtFeature.getMethod("isFeatureSupport", int.class); ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH); } catch (ClassNotFoundException e) { LogUtil.e(TAG, "hasNotchAtVivo ClassNotFoundException"); } catch (NoSuchMethodException e) { LogUtil.e(TAG, "hasNotchAtVivo NoSuchMethodException"); } catch (Exception e) { LogUtil.e(TAG, "hasNotchAtVivo Exception"); } finally { return ret; } } /** * 小米手机判断是不是刘海手机 * * @return */ public static boolean HasNotchXiaoMi() { Boolean _hasNotchXiaoMi = getPropertyInt("ro.miui.notch", 0) == 1 ? true : false; LogUtil.i(TAG,"是否是小米刘海手机: " + _hasNotchXiaoMi); return _hasNotchXiaoMi; } private static int getPropertyInt(String key,int defaultValue) { int value = defaultValue; try { Class<?> c = Class.forName("android.os.SystemProperties"); Method get = c.getMethod("get", String.class, String.class); value = (int) (get.invoke(c, key, "unknown")); } catch (Exception e) { e.printStackTrace(); } finally { return value; } } /** * 小米手机获取刘海的高度 */ public static int getStatusBarHeight(Context context) { int statusBarHeight = 0; int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = context.getResources().getDimensionPixelSize(resourceId); } return statusBarHeight; } /** * 屏幕旋转汇总的方法 * * @param activity * @param isNotch * @param type * @param viewGroup */ public static void onConfigurationChanged(Activity activity, Boolean isNotch, int type, ViewGroup viewGroup) { if (getDisplayRotation(activity) == 0) { if (isNotch) { switch (type) { case 1: //vivo FrameLayout.LayoutParams lpvivo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lpvivo.topMargin = dp2px(activity, 32); lpvivo.leftMargin = 0; lpvivo.rightMargin = 0; viewGroup.setLayoutParams(lpvivo); break; case 2: //HUAWEI int[] sizeAtHuawei = NotchPhoneUtil.getNotchSizeAtHuawei(activity); FrameLayout.LayoutParams lphuawei = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lphuawei.topMargin = sizeAtHuawei[1]; lphuawei.leftMargin = 0; lphuawei.rightMargin = 0; viewGroup.setLayoutParams(lphuawei); break; case 3: //OPPO 目前都为 80px FrameLayout.LayoutParams lpOppo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lpOppo.topMargin = 80; lpOppo.leftMargin = 0; lpOppo.rightMargin = 0; viewGroup.setLayoutParams(lpOppo); break; case 4: //Xiaomi int sizeAtXiaomi = NotchPhoneUtil.getStatusBarHeight(activity); FrameLayout.LayoutParams lpXiaomi = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lpXiaomi.topMargin = sizeAtXiaomi; lpXiaomi.leftMargin = 0; lpXiaomi.rightMargin = 0; viewGroup.setLayoutParams(lpXiaomi); break; } } } else if (getDisplayRotation(activity) == 90) { leftAndRightChange(activity, isNotch, type, viewGroup); } else if (getDisplayRotation(activity) == 180) { } else if (getDisplayRotation(activity) == 270) { leftAndRightChange(activity, isNotch, type, viewGroup); } } /** * 左右横屏都是让 leftMargin 和rightMargin 空出一个刘海的距离 * * @param activity * @param isNotch * @param type * @param viewGroup */ private static void leftAndRightChange(Activity activity, Boolean isNotch, int type, ViewGroup viewGroup) { if (isNotch) { switch (type) { case 1: //vivo FrameLayout.LayoutParams lpvivo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lpvivo.leftMargin = dp2px(activity, 32); lpvivo.rightMargin = dp2px(activity, 32); lpvivo.topMargin = 0; lpvivo.bottomMargin = 0; viewGroup.setLayoutParams(lpvivo); break; case 2: //HUAWEI int[] sizeAtHuawei = NotchPhoneUtil.getNotchSizeAtHuawei(activity); FrameLayout.LayoutParams lphuawei = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lphuawei.leftMargin = sizeAtHuawei[1]; lphuawei.rightMargin = sizeAtHuawei[1]; lphuawei.topMargin = 0; lphuawei.bottomMargin = 0; viewGroup.setLayoutParams(lphuawei); break; case 3: //OPPO 目前都为 80px FrameLayout.LayoutParams lpOppo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lpOppo.leftMargin = 80; lpOppo.rightMargin = 80; lpOppo.topMargin = 0; lpOppo.bottomMargin = 0; viewGroup.setLayoutParams(lpOppo); break; case 4: //Xiaomi int sizeAtXiaomi = NotchPhoneUtil.getStatusBarHeight(activity); FrameLayout.LayoutParams lpXiaomi = (FrameLayout.LayoutParams) viewGroup.getLayoutParams(); lpXiaomi.leftMargin = sizeAtXiaomi; lpXiaomi.rightMargin = sizeAtXiaomi; lpXiaomi.topMargin = 0; lpXiaomi.bottomMargin = 0; viewGroup.setLayoutParams(lpXiaomi); break; } } } /** * 获取当前屏幕旋转角度 * * @param activity * @return 0表示是竖屏; 90表示是左横屏; 180表示是反向竖屏; 270表示是右横屏 */ public static int getDisplayRotation(Activity activity) { if (activity == null) { return 0; } int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); switch (rotation) { case Surface.ROTATION_0: return 0; case Surface.ROTATION_90: return 90; case Surface.ROTATION_180: return 180; case Surface.ROTATION_270: return 270; } return 0; } /** * px转dp * * @param context * @param dipValue */ public static int dp2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /** * 获取手机厂商 * * @return 手机厂商 Xiaomi HUAWEI vivo */ public static String getDeviceBrand() { return android.os.Build.BRAND; } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/StaticDefine.java
New file @@ -0,0 +1,19 @@ package com.secondworld.universalsdk; /** * Created by Administrator on 2018/6/14 0014. */ public class StaticDefine { public static final String UnityGameObjectName = "SDKUtility"; public static final String UnityHandleFuncName = "HandleSdkMessage"; public static final String LS_KEY_VERSION = "H2Engine_App_Version"; public static final String LS_KEY_COPIED = "H2Engine_Copy_Finished"; public final static String LS_KEY_IMEI = "H2Engine_DEVICE_IMEI"; public final static String LS_KEY_MAC = "H2Engine_DEVICE_MAC"; public final static String LS_KEY_ANDROID_ID = "H2Engine_DEVICE_ANDROID_ID"; public final static String LS_KEY_TENCENT_LOGINPARAM = "H2Engine_TENCENT_LOGIN_PARAM"; } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/UniqueID.java
New file @@ -0,0 +1,226 @@ package com.secondworld.universalsdk; import android.Manifest; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.provider.Settings; import android.support.v4.content.PermissionChecker; import android.telephony.TelephonyManager; import android.util.Log; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.net.NetworkInterface; import java.net.SocketException; import java.security.MessageDigest; import java.util.UUID; /** * Created by Administrator on 2018/7/12 0012. */ public class UniqueID { public static String get(Context context) { String _id = read(context); if (_id != null && !_id.equals("")) { return _id; } StringBuffer _buffer = new StringBuffer(); _id = getDeviceId(context); _buffer.append(_id); _id = getLocalMac(context).replace(":", ""); _buffer.append(_id); if (_buffer == null || _buffer.length() <= 0) { UUID _uuid = UUID.randomUUID(); _id = _uuid.toString().replace("-", ""); _buffer.append(_id); } _id = getMD5(_buffer.toString(), false); if (_id.length() > 0) { save(_id, context); } return _id; } private static String read(Context context) { File _file = new File(context.getExternalFilesDir(""), "/tsw_device_unique_id.txt"); if (!_file.exists()) { return null; } StringBuffer _buffer = new StringBuffer(); try { FileInputStream _fis = new FileInputStream(_file); InputStreamReader _isr = new InputStreamReader(_fis, "UTF-8"); Reader _in = new BufferedReader(_isr); int _index; while ((_index = _in.read()) > -1) { _buffer.append((char) _index); } _in.close(); return _buffer.toString(); } catch (IOException e) { e.printStackTrace(); } return null; } private static void save(String id, Context context) { File _file = new File(context.getExternalFilesDir(""), "/tsw_device_unique_id.txt"); try { Log.i("UniqueIDUtil", "path: " + _file.getAbsolutePath()); FileOutputStream _fos = new FileOutputStream(_file); Writer _writer = new OutputStreamWriter(_fos, "UTF-8"); _writer.write(id); _writer.close(); _fos.close(); } catch (IOException e) { e.printStackTrace(); } } public static String getAndroidID(Context context) { return Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID); } public static String getDeviceId(Context context) { SharedPreferences _sp = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); String _deviceId = _sp.getString(StaticDefine.LS_KEY_IMEI, ""); if (!_deviceId.equals("")) { return _deviceId; } TelephonyManager tm = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); if (PermissionChecker.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { _deviceId = tm.getDeviceId(); SharedPreferences.Editor _e = _sp.edit(); _e.putString(StaticDefine.LS_KEY_IMEI, _deviceId); _e.apply(); return _deviceId; } return ""; } public static String getLocalMac(Context context) { SharedPreferences _sp = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); String _macAddress = _sp.getString(StaticDefine.LS_KEY_MAC, ""); if (!_macAddress.equals("")) { return _macAddress; } StringBuffer _buffer = new StringBuffer(); NetworkInterface _networkInterface; try { _networkInterface = NetworkInterface.getByName("eth1"); if (_networkInterface == null) { _networkInterface = NetworkInterface.getByName("wlan0"); } if (_networkInterface == null) { return ""; } byte[] _addresses = _networkInterface.getHardwareAddress(); for (byte b : _addresses) { _buffer.append(String.format("%02X:", b)); } if (_buffer.length() > 0) { _buffer.deleteCharAt(_buffer.length() - 1); } _macAddress = _buffer.toString(); SharedPreferences.Editor _e = _sp.edit(); _e.putString(StaticDefine.LS_KEY_MAC, _macAddress); _e.apply(); } catch (SocketException e) { e.printStackTrace(); return ""; } return _macAddress; } public static String getMD5(String message, boolean upperCase) { String md5str = ""; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] input = message.getBytes(); byte[] buff = md.digest(input); md5str = bytesToHex(buff, upperCase); } catch (Exception e) { e.printStackTrace(); } return md5str; } private static String bytesToHex(byte[] bytes, boolean upperCase) { StringBuffer md5str = new StringBuffer(); int digital; for (int i = 0; i < bytes.length; i++) { digital = bytes[i]; if (digital < 0) { digital += 256; } if (digital < 16) { md5str.append("0"); } md5str.append(Integer.toHexString(digital)); } if (upperCase) { return md5str.toString().toUpperCase(); } return md5str.toString().toLowerCase(); } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/UniversalUtil.java
New file @@ -0,0 +1,401 @@ package com.secondworld.universalsdk; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PermissionInfo; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Process; import android.provider.Settings; import android.support.v4.content.PermissionChecker; import android.widget.Toast; import com.unity3d.player.UnityPlayer; import org.json.JSONObject; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.Map; /** * Created by Administrator on 2018/6/15 0015. */ public class UniversalUtil { private final static String TAG = "UniversalUtil"; /** * 获得应用的版本号 */ public static String GetVersionName(Context context) { PackageManager _packageManager = context.getPackageManager(); PackageInfo _packageInfo = null; try { _packageInfo = _packageManager.getPackageInfo(context.getPackageName(), 0); } catch (Exception e) { e.printStackTrace(); } if (_packageInfo != null) { return _packageInfo.versionName; } return null; } public static void sendMessageToUnity(Map<String, Object> jsonMap) { if (jsonMap == null || jsonMap.isEmpty()) { return; } JSONObject _jsonObject = new JSONObject(jsonMap); UnityPlayer.UnitySendMessage(StaticDefine.UnityGameObjectName, StaticDefine.UnityHandleFuncName, _jsonObject.toString()); } public static void InstallAPK(Context context, final String path) { File _file = new File(path); if (_file == null) { Toast.makeText(context, "给定的地址[" + path + "]找不到要安装的应用文件", Toast.LENGTH_SHORT).show(); return; } try { Intent _intent = new Intent(Intent.ACTION_VIEW); // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) // { // _intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Uri _contentUri = FileProvider.getUriForFile(context, // context.getPackageName() + ".fileProvider", // _file); // _intent.setDataAndType(_contentUri, "application/vnd.android.package-archive"); // } // else // { _intent.setDataAndType(Uri.fromFile(_file), "application/vnd.android.package-archive"); _intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // } context.startActivity(_intent); } catch (Exception e) { e.printStackTrace(); Toast.makeText(context, "找不到打开此类型文件的程序", Toast.LENGTH_SHORT).show(); } } public static void CopyTextToClipboard(final Activity activity, final String text) { activity.runOnUiThread(new Runnable() { @Override public void run() { ClipboardManager _mgr = (ClipboardManager) activity.getSystemService( Context.CLIPBOARD_SERVICE); ClipData _data = ClipData.newPlainText("playerId", text); _mgr.setPrimaryClip(_data); } }); } public static long getMemTotal() { try { FileReader fileReader = new FileReader("/proc/meminfo"); BufferedReader bufferedReader = new BufferedReader(fileReader, 4 * 1024); String str; while ((str = bufferedReader.readLine()) != null) { if (str.contains("MemTotal")) { break; } } bufferedReader.close(); fileReader.close(); String[] array = str.split("\\s+"); // 获得系统总内存,单位是KB return Integer.valueOf(array[1]).intValue(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return 0; } public static String getPublicIp(boolean useHttps) { String _ip; try { URL ipify = useHttps ? new URL("https://api.ipify.org") : new URL( "http://api.ipify.org"); URLConnection conn = ipify.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); _ip = in.readLine(); in.close(); } catch (IOException e) { e.printStackTrace(); } return ""; } public static String getIP(Context context) { NetworkInfo info = ((ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); if (info != null && info.isConnected()) { if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络 try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { return inetAddress.getHostAddress(); } } } } catch (SocketException e) { e.printStackTrace(); } } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络 WifiManager wifiManager = (WifiManager) context.getSystemService( Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); return intIP2StringIP(wifiInfo.getIpAddress()); } } else { //当前无网络连接,请在设置中打开网络 } return null; } private static String intIP2StringIP(int ip) { return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + (ip >> 24 & 0xFF); } public static boolean hasRWP = false; public static boolean hasGoToSetting = false; public static void CheckWriteAndReadExternalStorage(final Activity activity) { //Log.i("MainActivity", "CheckWriteAndReadExternalStorage 开始 hasGoToSetting: " + hasGoToSetting); if (hasRWP && !hasGoToSetting) { //Log.i("MainActivity", "1111 有权限"); return; } if (PermissionChecker.checkPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, Process.myPid(), Process.myUid(), activity.getPackageName()) == PackageManager.PERMISSION_GRANTED) { //Log.i("MainActivity", "有权限"); hasRWP = true; if (hasGoToSetting) { //Log.i("MainActivity", "去过设置界面, 这里重启"); activity.runOnUiThread(new Runnable() { @Override public void run() { new Thread() { public void run() { String _packageName = activity.getPackageName(); Intent _launch = activity.getBaseContext().getPackageManager().getLaunchIntentForPackage( _packageName); _launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(_launch); Process.killProcess(Process.myPid()); } }.start(); activity.finish(); } }); } return; } if (!hasRWP) { new AlertDialog.Builder(activity) .setMessage("应用没有存储读取权限,点击确定至设置中开启,否则无法继续游戏.") .setCancelable(false) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { UniversalUtil.hasGoToSetting = true; Intent intent = new Intent( Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Uri uri = Uri.fromParts("package", activity.getPackageName(), null); intent.setData(uri); activity.startActivity(intent); } }) .setNegativeButton("拒绝", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { activity.finish(); } }) .show(); } } public static boolean checkPermission22(Activity activity, String permission) { PackageManager _pkgMgr = activity.getPackageManager(); LogUtil.i(TAG, "开始检测权限: " + permission); try { PermissionInfo _info = _pkgMgr.getPermissionInfo(permission, PackageManager.GET_META_DATA); LogUtil.i(TAG, " |-- 保护级别: " + _info.protectionLevel); if (_info.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS && _info.protectionLevel != 4097) { LogUtil.i(TAG, " |-- 不是危险权限."); return false; } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } int _result = PermissionChecker.checkPermission(activity, permission, Process.myPid(), Process.myUid(), activity.getPackageName()); LogUtil.i(TAG, " |-- 获取类型: " + _result); if (_result == PackageManager.PERMISSION_GRANTED) { LogUtil.i(TAG, permission + " 有这个权限."); return false; } return true; } public static String getMetaString(Activity activity, String key) { PackageManager _pkgMgr = activity.getPackageManager(); ApplicationInfo _appInfo; try { _appInfo = _pkgMgr.getApplicationInfo(activity.getPackageName(), PackageManager.GET_META_DATA); return _appInfo.metaData.getString(key); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return null; } public static int getMetaInt(Activity activity, String key) { LogUtil.i(TAG, "将要获取的MetaKey: " + key); PackageManager _pkgMgr = activity.getPackageManager(); ApplicationInfo _appInfo; try { _appInfo = _pkgMgr.getApplicationInfo(activity.getPackageName(), PackageManager.GET_META_DATA); return _appInfo.metaData.getInt(key); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return -1; } public static boolean isEmpty(String s) { if (null == s) return true; if (s.length() == 0) return true; if (s.trim().length() == 0) return true; return false; } } Project/qkbtzf/src/main/java/com/secondworld/universalsdk/WebViewUtil.java
New file @@ -0,0 +1,187 @@ package com.secondworld.universalsdk; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.webkit.WebChromeClient; import android.webkit.WebResourceResponse; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.RelativeLayout; import com.secondworld.univeralsdk.R; /** * Created by Administrator on 2018/8/1 0001. */ public class WebViewUtil { private static Activity m_Activity; private static String m_ReceivedUrl; private static WebView m_WebView; private static Button m_BtnClose; public static void OpenWebView(final Activity activity, final String url) { m_Activity = activity; m_ReceivedUrl = url; activity.runOnUiThread(new Runnable() { @Override public void run() { if (m_WebView != null && m_WebView.getVisibility() == View.VISIBLE) { processClose(); return; } DisplayMetrics _dm = new DisplayMetrics(); m_Activity.getWindowManager().getDefaultDisplay().getMetrics(_dm); final float _scale = _dm.widthPixels * 1f / 1344; final int _width = (int) (_scale * 982); final int _height = (int) (_scale * 560); m_BtnClose = (Button) m_Activity.findViewById(R.id.webView_btn_close); ViewGroup.MarginLayoutParams _margin = new ViewGroup.MarginLayoutParams( m_BtnClose.getLayoutParams()); RelativeLayout.LayoutParams _params = new RelativeLayout.LayoutParams(_margin); _params.width = 0; _params.height = 0; _params.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.webView); _params.addRule(RelativeLayout.ALIGN_RIGHT, R.id.webView); m_BtnClose.setLayoutParams(_params); m_BtnClose.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { processClose(); } }); m_WebView = (WebView) m_Activity.findViewById(R.id.webView); ViewGroup.MarginLayoutParams margin = new ViewGroup.MarginLayoutParams( m_WebView.getLayoutParams()); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(margin); layoutParams.width = 0; layoutParams.height = 0; layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); m_WebView.setLayoutParams(layoutParams); m_WebView.getSettings().setJavaScriptEnabled(true); m_WebView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); view.loadUrl(m_ReceivedUrl); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http") || url.startsWith("https")) { //http和https协议开头的执行正常的流程 view.loadUrl(url); return true; } else { //其他的URL则会开启一个Acitity然后去调用原生APP return super.shouldOverrideUrlLoading(view, url); } } @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { if (url.startsWith("http") || url.startsWith("https")) { //http和https协议开头的执行正常的流程 return super.shouldInterceptRequest(view, url); } else { //其他的URL则会开启一个Acitity然后去调用原生APP try { Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); m_Activity.startActivity(in); } catch (ActivityNotFoundException e) { e.printStackTrace(); } return null; } } }); m_WebView.setWebChromeClient(new WebChromeClient() { @Override public void onReceivedTitle(WebView view, String title) { if (title.contains("I'm QQ")) { m_WebView.loadUrl(m_ReceivedUrl); } super.onReceivedTitle(view, title); } @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress == 100) { if (view.getUrl().contains("noticeweb")) { ViewGroup.MarginLayoutParams margin = new ViewGroup.MarginLayoutParams( m_WebView.getLayoutParams()); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( margin); layoutParams.width = _width; layoutParams.height = _height; layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); m_WebView.setLayoutParams(layoutParams); ViewGroup.MarginLayoutParams _margin = new ViewGroup.MarginLayoutParams( m_BtnClose.getLayoutParams()); RelativeLayout.LayoutParams _params = new RelativeLayout.LayoutParams( _margin); _params.width = (int) (180 * _scale); _params.height = (int) (72 * _scale); _params.rightMargin = (int) (250 * _scale); _params.bottomMargin = (int) (10 * _scale); _params.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.webView); _params.addRule(RelativeLayout.ALIGN_RIGHT, R.id.webView); m_BtnClose.setLayoutParams(_params); } } } }); m_WebView.loadUrl(m_ReceivedUrl); m_WebView.setVisibility(View.VISIBLE); m_BtnClose.setVisibility(View.VISIBLE); } }); } private static void processClose() { m_WebView.clearFocus(); m_WebView.clearCache(true); m_WebView.clearHistory(); m_WebView.clearFormData(); m_WebView.setVisibility(View.INVISIBLE); m_BtnClose.setVisibility(View.INVISIBLE); } } Project/qkbtzf/src/main/res/drawable-hdpi/jpush_ic_richpush_actionbar_back.png
Project/qkbtzf/src/main/res/drawable-hdpi/jpush_ic_richpush_actionbar_divider.png
Project/qkbtzf/src/main/res/drawable-hdpi/jpush_richpush_btn_selector.xml
New file @@ -0,0 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 获得焦点但未按下时的背景图片 --> <item android:state_focused="true" android:state_enabled="true" android:state_pressed="false" android:drawable="@drawable/jpush_ic_richpush_actionbar_back" /> <!-- 按下时的背景图片 --> <item android:state_enabled="true" android:state_pressed="true" android:drawable="@android:color/darker_gray" /> <!-- 按下时的背景图片 --> <item android:state_enabled="true" android:state_checked="true" android:drawable="@android:color/darker_gray" /> <!-- 默认时的背景图片 --> <item android:drawable="@drawable/jpush_ic_richpush_actionbar_back" /> </selector> Project/qkbtzf/src/main/res/drawable-hdpi/jpush_richpush_progressbar.xml
New file @@ -0,0 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 背景 gradient是渐变,corners定义的是圆角 --> <item android:id="@android:id/background"> <shape> <solid android:color="#ffffff" /> </shape> </item> <!-- 进度条 --> <item android:id="@android:id/progress"> <clip> <shape> <solid android:color="#4393ea" /> </shape> </clip> </item> </layer-list> Project/qkbtzf/src/main/res/drawable/app_icon.png
Project/qkbtzf/src/main/res/drawable/web_btn_close_icon.png
Project/qkbtzf/src/main/res/layout/activity_main.xml
New file @@ -0,0 +1,30 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_container" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/unity_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <WebView android:id="@+id/webView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="invisible" /> <Button android:id="@+id/webView_btn_close" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/webView" android:layout_alignRight="@id/webView" android:background="@drawable/web_btn_close_icon" android:text="我知道了" android:textSize="16dp" android:visibility="invisible" /> </RelativeLayout> Project/qkbtzf/src/main/res/layout/jpush_popwin_layout.xml
New file @@ -0,0 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/popLayoutId" style="@style/MyDialogStyle" android:orientation="vertical" android:layout_width="280dp" android:layout_height="250dp" > <WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/wvPopwin"/> </LinearLayout> Project/qkbtzf/src/main/res/layout/jpush_webview_layout.xml
New file @@ -0,0 +1,59 @@ <?xml version="1.0" encoding="utf-8"?> <cn.jpush.android.ui.FullScreenView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/actionbarLayoutId" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:id="@+id/rlRichpushTitleBar" android:layout_width="match_parent" android:layout_height="40.0dp" android:background="#29313a"> <ImageButton android:id="@+id/imgRichpushBtnBack" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="9dp" android:layout_marginRight="10dp" android:background="@drawable/jpush_richpush_btn_selector" /> <ImageView android:id="@+id/imgView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@id/imgRichpushBtnBack" android:clickable="false" android:src="@drawable/jpush_ic_richpush_actionbar_divider" /> <TextView android:id="@+id/tvRichpushTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="7dp" android:layout_marginRight="5dp" android:layout_toRightOf="@id/imgView" android:clickable="false" android:text=" " android:textSize="20sp" android:textColor="#ffffff" /> </RelativeLayout> <ProgressBar android:id="@+id/pushPrograssBar" android:layout_width="match_parent" android:layout_height="1dp" android:progress="0" android:progressDrawable="@drawable/jpush_richpush_progressbar" style="?android:attr/progressBarStyleHorizontal" /> <WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/fullWebView" android:background="#000000" /> </cn.jpush.android.ui.FullScreenView> Project/qkbtzf/src/main/res/values/colors.xml
New file @@ -0,0 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> </resources> Project/qkbtzf/src/main/res/values/jpush_style.xml
New file @@ -0,0 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="MyDialogStyle"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowFrame">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <item name="android:backgroundDimEnabled">true</item> </style> </resources> Project/qkbtzf/src/main/res/values/strings.xml
New file @@ -0,0 +1,4 @@ <resources> <string name="app_name">UniveralSDK</string> <string name="banhao">著作权:江苏易乐网络科技公司 运营单位:二四六零(镇江)智慧社区信息服务有限公司</r>出版:北京伯通电子出版社 软著登记号:2015SR235627 ISBN:ISBN 978-7-7979-0154-3 审批文号:新广出审[2016]1343号</string> </resources> Project/qkbtzf/src/main/res/values/styles.xml
New file @@ -0,0 +1,8 @@ <resources> <!-- Base application theme. --> <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> <!-- Customize your theme here. --> </style> </resources> Project/qkbtzf/src/main/res/xml/file_paths.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <paths> <external-path path="Android/data/com.shandangceshi.snxxz/" name="files_root" /> <external-path path="." name="external_storage_root" /> </paths> Project/settings.gradle
@@ -1,2 +1,3 @@ include ':qkbtzf' include ':app', ':mr_sdk', ':sp_sdk', ':js_sdk', ':yj_sdk', ':quicksdk_sdk', ':yl_sdk', ':xn_sdk', ':sd_sdk', ':ky_sdk', ':qk_sdk', ':qkcw2_sdk', ':qkbt_sdk' include ':sp_common_sdk'