@norcy/react-native-toolkit 0.2.7 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/android/build.gradle +7 -0
- package/android/buildscript.gradle +15 -0
- package/android/dependencies.gradle +149 -0
- package/android/gradle.properties +4 -4
- package/android/root.gradle +37 -0
- package/android/settings.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +1 -1
- package/android/src/main/java/com/norcy/reactnativetoolkit/BaseToolkitActivity.java +42 -0
- package/android/src/main/java/com/norcy/reactnativetoolkit/BaseToolkitApplication.java +63 -0
- package/android/src/main/java/com/norcy/reactnativetoolkit/CheckPackageInstallationModule.java +48 -0
- package/android/src/main/java/com/norcy/reactnativetoolkit/NCYAPI.java +191 -0
- package/android/src/main/java/com/norcy/reactnativetoolkit/NCYReport.java +48 -0
- package/android/src/main/java/com/norcy/reactnativetoolkit/PreferencesManager.java +50 -0
- package/android/src/main/java/com/{norcyreactnativetoolkit → norcy/reactnativetoolkit}/ReactNativeToolkitModule.kt +2 -1
- package/android/src/main/java/com/{norcyreactnativetoolkit → norcy/reactnativetoolkit}/ReactNativeToolkitPackage.kt +8 -2
- package/android/src/main/java/com/norcy/reactnativetoolkit/UMengManager.java +54 -0
- package/lib/commonjs/AppLink.js.map +1 -1
- package/lib/commonjs/SentryManager.js +31 -23
- package/lib/commonjs/SentryManager.js.map +1 -1
- package/lib/commonjs/Tool.js +26 -0
- package/lib/commonjs/Tool.js.map +1 -1
- package/lib/module/AppLink.js.map +1 -1
- package/lib/module/SentryManager.js +32 -24
- package/lib/module/SentryManager.js.map +1 -1
- package/lib/module/Tool.js +27 -1
- package/lib/module/Tool.js.map +1 -1
- package/lib/typescript/AppLink.d.ts +1 -2
- package/lib/typescript/AppLink.d.ts.map +1 -1
- package/lib/typescript/SentryManager.d.ts.map +1 -1
- package/lib/typescript/Tool.d.ts +3 -0
- package/lib/typescript/Tool.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/AppLink.ts +2 -3
- package/src/SentryManager.ts +37 -27
- package/src/Tool.ts +39 -1
- package/.circleci/config.yml +0 -98
- package/.editorconfig +0 -15
- package/.gitattributes +0 -3
- package/.github/workflows/publish-on-main.yml +0 -32
- package/.gitignore +0 -66
- package/.husky/pre-commit +0 -2
- package/.prettierrc +0 -8
- package/.watchmanconfig +0 -6
- package/babel.config.js +0 -3
- package/cocoa_plugins/cocoapods-rn-toolkit/Gemfile +0 -13
- package/cocoa_plugins/cocoapods-rn-toolkit/LICENSE.txt +0 -22
- package/cocoa_plugins/cocoapods-rn-toolkit/README.md +0 -27
- package/cocoa_plugins/cocoapods-rn-toolkit/Rakefile +0 -13
- package/cocoa_plugins/cocoapods-rn-toolkit/cocoapods-rn-toolkit.gemspec +0 -28
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/command/toolkit.rb +0 -44
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/command.rb +0 -1
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/common_build_settings.rb +0 -12
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/gem_version.rb +0 -3
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/ios17_uigraphics.rb +0 -57
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/library_search_paths.rb +0 -41
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit/xcode16_rnziparchive.rb +0 -15
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods-rn-toolkit.rb +0 -1
- package/cocoa_plugins/cocoapods-rn-toolkit/lib/cocoapods_plugin.rb +0 -32
- package/cocoa_plugins/cocoapods-rn-toolkit/spec/command/toolkit_spec.rb +0 -12
- package/cocoa_plugins/cocoapods-rn-toolkit/spec/spec_helper.rb +0 -50
- package/locales/en-US.json +0 -1
- package/locales/zh-CN.json +0 -1
- package/tsconfig.json +0 -27
- package/yarn.lock +0 -10168
package/README.md
CHANGED
|
@@ -8,6 +8,18 @@ App 工厂核心组件
|
|
|
8
8
|
yarn add @norcy/react-native-toolkit
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Android 引入
|
|
12
|
+
|
|
13
|
+
App 端需要在 `android/app/build.gradle` 中添加:
|
|
14
|
+
|
|
15
|
+
```gradle
|
|
16
|
+
dependencies {
|
|
17
|
+
implementation 'com.umeng.umsdk:common:9.6.3'
|
|
18
|
+
implementation 'com.umeng.umsdk:asms:1.8.0'
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
11
23
|
## 维护
|
|
12
24
|
【重要】TS 校验和 ESLint 校验
|
|
13
25
|
|
package/android/build.gradle
CHANGED
|
@@ -127,4 +127,11 @@ dependencies {
|
|
|
127
127
|
// noinspection GradleDynamicVersion
|
|
128
128
|
api 'com.facebook.react:react-native:+'
|
|
129
129
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
130
|
+
|
|
131
|
+
// react-native-splash-screen 强制依赖 - 宿主 App 必须安装
|
|
132
|
+
implementation project(':react-native-splash-screen')
|
|
133
|
+
|
|
134
|
+
// 友盟统计
|
|
135
|
+
implementation 'com.umeng.umsdk:common:9.6.3'
|
|
136
|
+
implementation 'com.umeng.umsdk:asms:1.8.0'
|
|
130
137
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ext.applyBuildscriptExt = {
|
|
2
|
+
ext.buildToolsVersion = "29.0.3"
|
|
3
|
+
ext.minSdkVersion = 21
|
|
4
|
+
ext.compileSdkVersion = 33
|
|
5
|
+
ext.targetSdkVersion = 33
|
|
6
|
+
ext.kotlinVersion = "1.6.0"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
ext.applyBuildscriptRepos = { handler ->
|
|
10
|
+
handler.maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
|
|
11
|
+
handler.maven { url 'https://repo1.maven.org/maven2/' }
|
|
12
|
+
handler.mavenCentral()
|
|
13
|
+
handler.google()
|
|
14
|
+
}
|
|
15
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
ext.applyDefaultConfig = { targetProject ->
|
|
2
|
+
targetProject.android {
|
|
3
|
+
compileSdkVersion targetProject.rootProject.ext.compileSdkVersion
|
|
4
|
+
|
|
5
|
+
defaultConfig {
|
|
6
|
+
minSdkVersion targetProject.rootProject.ext.minSdkVersion
|
|
7
|
+
targetSdkVersion targetProject.rootProject.ext.targetSdkVersion
|
|
8
|
+
multiDexEnabled true
|
|
9
|
+
missingDimensionStrategy 'store', 'play'
|
|
10
|
+
ndk {
|
|
11
|
+
abiFilters "armeabi-v7a", "arm64-v8a"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
splits {
|
|
16
|
+
abi {
|
|
17
|
+
reset()
|
|
18
|
+
enable false
|
|
19
|
+
universalApk true
|
|
20
|
+
include "armeabi-v7a", "arm64-v8a"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
signingConfigs {
|
|
25
|
+
debug {
|
|
26
|
+
storeFile targetProject.file('debug.keystore')
|
|
27
|
+
storePassword 'android'
|
|
28
|
+
keyAlias 'androiddebugkey'
|
|
29
|
+
keyPassword 'android'
|
|
30
|
+
}
|
|
31
|
+
release {
|
|
32
|
+
if (targetProject.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
|
|
33
|
+
storeFile targetProject.file(targetProject.MYAPP_RELEASE_STORE_FILE)
|
|
34
|
+
storePassword targetProject.MYAPP_RELEASE_STORE_PASSWORD
|
|
35
|
+
keyAlias targetProject.MYAPP_RELEASE_KEY_ALIAS
|
|
36
|
+
keyPassword targetProject.MYAPP_RELEASE_KEY_PASSWORD
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ext.applyCommonDependencies = { targetProject ->
|
|
44
|
+
def enableHermes = targetProject.ext.react.get("enableHermes", false)
|
|
45
|
+
def jscFlavor = 'org.webkit:android-jsc:+'
|
|
46
|
+
|
|
47
|
+
targetProject.dependencies {
|
|
48
|
+
implementation fileTree(dir: "libs", include: ["*.jar"])
|
|
49
|
+
|
|
50
|
+
//noinspection GradleDynamicVersion
|
|
51
|
+
implementation "com.facebook.react:react-native:0.62.2.9.1"
|
|
52
|
+
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
|
53
|
+
implementation 'com.android.support:multidex:2.0.1'
|
|
54
|
+
|
|
55
|
+
implementation 'com.umeng.umsdk:common:9.6.3'
|
|
56
|
+
implementation 'com.umeng.umsdk:asms:1.8.0'
|
|
57
|
+
implementation 'com.umeng.umsdk:uyumao:1.1.2'
|
|
58
|
+
|
|
59
|
+
implementation targetProject.project(':react-native-splash-screen')
|
|
60
|
+
implementation targetProject.project(':react-native-blob-util')
|
|
61
|
+
|
|
62
|
+
if (enableHermes) {
|
|
63
|
+
def hermesPath = "../../node_modules/hermes-engine/android/"
|
|
64
|
+
debugImplementation files(hermesPath + "hermes-debug.aar")
|
|
65
|
+
releaseImplementation files(hermesPath + "hermes-release.aar")
|
|
66
|
+
} else {
|
|
67
|
+
implementation jscFlavor
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
ext.applyBuildTypes = { targetProject ->
|
|
73
|
+
targetProject.android {
|
|
74
|
+
buildTypes {
|
|
75
|
+
debug {
|
|
76
|
+
signingConfig signingConfigs.debug
|
|
77
|
+
resValue "string", "app_name", "@string/app_name_debug"
|
|
78
|
+
}
|
|
79
|
+
release {
|
|
80
|
+
signingConfig signingConfigs.release
|
|
81
|
+
minifyEnabled false
|
|
82
|
+
proguardFiles targetProject.android.getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
|
83
|
+
crunchPngs false
|
|
84
|
+
resValue "string", "app_name", "@string/app_name_release"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
ext.applyCommonAndroidConfig = { targetProject ->
|
|
91
|
+
targetProject.android {
|
|
92
|
+
compileOptions {
|
|
93
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
94
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
packagingOptions {
|
|
98
|
+
pickFirst "lib/armeabi-v7a/libc++_shared.so"
|
|
99
|
+
pickFirst "lib/arm64-v8a/libc++_shared.so"
|
|
100
|
+
pickFirst "lib/x86/libc++_shared.so"
|
|
101
|
+
pickFirst "lib/x86_64/libc++_shared.so"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
lintOptions {
|
|
105
|
+
checkReleaseBuilds false
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
applicationVariants.all { variant ->
|
|
109
|
+
variant.outputs.each { output ->
|
|
110
|
+
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
|
111
|
+
def abi = output.getFilter("ABI")
|
|
112
|
+
if (abi != null) {
|
|
113
|
+
output.versionCodeOverride =
|
|
114
|
+
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
targetProject.tasks.create('copyDownloadableDepsToLibs', Copy) {
|
|
121
|
+
from targetProject.configurations.compile
|
|
122
|
+
into 'libs'
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
ext.applyCommonPlugins = { targetProject ->
|
|
127
|
+
targetProject.apply from: targetProject.file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle")
|
|
128
|
+
targetProject.applyNativeModulesAppBuildGradle(targetProject)
|
|
129
|
+
|
|
130
|
+
targetProject.apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
|
131
|
+
targetProject.apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
|
|
132
|
+
|
|
133
|
+
targetProject.ext.sentryCli = [
|
|
134
|
+
logLevel: "debug",
|
|
135
|
+
sentryProperties: "../sentry.properties"
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
ext.applyAll = { targetProject ->
|
|
140
|
+
targetProject.ext.react = [enableHermes: false]
|
|
141
|
+
targetProject.apply from: targetProject.file("../../node_modules/react-native/react.gradle")
|
|
142
|
+
|
|
143
|
+
applyDefaultConfig(targetProject)
|
|
144
|
+
applyBuildTypes(targetProject)
|
|
145
|
+
applyCommonAndroidConfig(targetProject)
|
|
146
|
+
applyCommonPlugins(targetProject)
|
|
147
|
+
applyCommonDependencies(targetProject)
|
|
148
|
+
}
|
|
149
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ReactNativeToolkit_kotlinVersion=1.
|
|
2
|
-
ReactNativeToolkit_compileSdkVersion=
|
|
3
|
-
ReactNativeToolkit_buildToolsVersion=
|
|
4
|
-
ReactNativeToolkit_targetSdkVersion=
|
|
1
|
+
ReactNativeToolkit_kotlinVersion=1.6.0
|
|
2
|
+
ReactNativeToolkit_compileSdkVersion=33
|
|
3
|
+
ReactNativeToolkit_buildToolsVersion=29.0.3
|
|
4
|
+
ReactNativeToolkit_targetSdkVersion=33
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
def REACT_NATIVE_VERSION = new File(['node', '--print',"JSON.parse(require('fs').readFileSync(require.resolve('react-native/package.json'), 'utf-8')).version"].execute(null, rootDir).text.trim())
|
|
2
|
+
|
|
3
|
+
allprojects {
|
|
4
|
+
repositories {
|
|
5
|
+
maven { url 'https://raw.githubusercontent.com/Norcy/maven/master/repository/' }
|
|
6
|
+
mavenLocal()
|
|
7
|
+
maven {
|
|
8
|
+
url("$rootDir/../node_modules/react-native/android")
|
|
9
|
+
}
|
|
10
|
+
maven {
|
|
11
|
+
url("$rootDir/../node_modules/jsc-android/dist")
|
|
12
|
+
}
|
|
13
|
+
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
|
|
14
|
+
maven { url 'https://repo1.maven.org/maven2/' }
|
|
15
|
+
mavenCentral()
|
|
16
|
+
google()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
configurations.all {
|
|
20
|
+
resolutionStrategy {
|
|
21
|
+
force "com.facebook.react:react-native:" + '0.62.2.9.1'
|
|
22
|
+
force 'androidx.core:core-ktx:1.6.0'
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
afterEvaluate { project ->
|
|
27
|
+
if (project.hasProperty("android")) {
|
|
28
|
+
android {
|
|
29
|
+
compileOptions {
|
|
30
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
31
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package com.norcy.reactnativetoolkit;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactActivity;
|
|
4
|
+
import android.content.Intent;
|
|
5
|
+
import android.net.Uri;
|
|
6
|
+
import android.os.Bundle;
|
|
7
|
+
import android.view.WindowManager;
|
|
8
|
+
import android.content.res.Configuration;
|
|
9
|
+
import org.devio.rn.splashscreen.SplashScreen;
|
|
10
|
+
|
|
11
|
+
public abstract class BaseToolkitActivity extends ReactActivity {
|
|
12
|
+
@Override
|
|
13
|
+
protected void onCreate(Bundle savedInstanceState) {
|
|
14
|
+
// 处理 DEBUG 模式下的屏幕常亮
|
|
15
|
+
if (getReactNativeHost().getUseDeveloperSupport()) {
|
|
16
|
+
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
17
|
+
} else {
|
|
18
|
+
SplashScreen.show(this, true);
|
|
19
|
+
}
|
|
20
|
+
super.onCreate(savedInstanceState);
|
|
21
|
+
|
|
22
|
+
// 处理 App Links
|
|
23
|
+
handleAppLinks();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Override
|
|
27
|
+
public void onConfigurationChanged(Configuration newConfig) {
|
|
28
|
+
super.onConfigurationChanged(newConfig);
|
|
29
|
+
getReactInstanceManager().onConfigurationChanged(this, newConfig);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private void handleAppLinks() {
|
|
33
|
+
Intent appLinkIntent = getIntent();
|
|
34
|
+
String appLinkAction = appLinkIntent.getAction();
|
|
35
|
+
Uri appLinkData = appLinkIntent.getData();
|
|
36
|
+
// 子类可以通过 getAppLinkData() 获取这些数据
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected Uri getAppLinkData() {
|
|
40
|
+
return getIntent().getData();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
package com.norcy.reactnativetoolkit;
|
|
2
|
+
|
|
3
|
+
import android.app.Application;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.ReactApplication;
|
|
6
|
+
import com.facebook.react.ReactNativeHost;
|
|
7
|
+
import com.facebook.react.ReactPackage;
|
|
8
|
+
import com.facebook.soloader.SoLoader;
|
|
9
|
+
|
|
10
|
+
import java.util.List;
|
|
11
|
+
|
|
12
|
+
public abstract class BaseToolkitApplication extends Application implements ReactApplication {
|
|
13
|
+
private final ReactNativeHost mReactNativeHost;
|
|
14
|
+
|
|
15
|
+
public BaseToolkitApplication() {
|
|
16
|
+
mReactNativeHost = createReactNativeHost();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 让子类可以完全控制要使用哪些包
|
|
20
|
+
protected abstract List<ReactPackage> getPackages();
|
|
21
|
+
|
|
22
|
+
// 让子类决定如何获取 JS Bundle URL,返回 null 则使用默认的 bundle
|
|
23
|
+
protected abstract String getJSBundleUrl();
|
|
24
|
+
|
|
25
|
+
// 让子类提供友盟统计的 AppKey
|
|
26
|
+
protected abstract String getUmengAppKey();
|
|
27
|
+
|
|
28
|
+
protected ReactNativeHost createReactNativeHost() {
|
|
29
|
+
return new ReactNativeHost(this) {
|
|
30
|
+
@Override
|
|
31
|
+
public boolean getUseDeveloperSupport() {
|
|
32
|
+
return BuildConfig.DEBUG;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Override
|
|
36
|
+
protected List<ReactPackage> getPackages() {
|
|
37
|
+
return BaseToolkitApplication.this.getPackages();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
protected String getJSBundleFile() {
|
|
42
|
+
return BaseToolkitApplication.this.getJSBundleUrl();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Override
|
|
46
|
+
protected String getJSMainModuleName() {
|
|
47
|
+
return "index";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Override
|
|
53
|
+
public ReactNativeHost getReactNativeHost() {
|
|
54
|
+
return mReactNativeHost;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Override
|
|
58
|
+
public void onCreate() {
|
|
59
|
+
super.onCreate();
|
|
60
|
+
SoLoader.init(this, false);
|
|
61
|
+
UMengManager.getInstance().setup(this, getUmengAppKey());
|
|
62
|
+
}
|
|
63
|
+
}
|
package/android/src/main/java/com/norcy/reactnativetoolkit/CheckPackageInstallationModule.java
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package com.norcy.reactnativetoolkit;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.NativeModule;
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
5
|
+
import com.facebook.react.bridge.ReactContext;
|
|
6
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
7
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
8
|
+
import com.facebook.react.bridge.Callback;
|
|
9
|
+
|
|
10
|
+
import android.content.Intent;
|
|
11
|
+
import android.content.pm.PackageManager;
|
|
12
|
+
import android.content.Context;
|
|
13
|
+
import android.net.Uri;
|
|
14
|
+
|
|
15
|
+
public class CheckPackageInstallationModule extends ReactContextBaseJavaModule {
|
|
16
|
+
Context ctx;
|
|
17
|
+
public CheckPackageInstallationModule(ReactApplicationContext reactContext) {
|
|
18
|
+
super(reactContext);
|
|
19
|
+
this.ctx = reactContext.getApplicationContext();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Override
|
|
23
|
+
public String getName() {
|
|
24
|
+
return "CheckPackageInstallation";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@ReactMethod
|
|
28
|
+
public void isPackageInstalled(String packageName, Callback cb) {
|
|
29
|
+
PackageManager pm = this.ctx.getPackageManager();
|
|
30
|
+
try {
|
|
31
|
+
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
|
|
32
|
+
cb.invoke(true);
|
|
33
|
+
} catch (Exception e) {
|
|
34
|
+
cb.invoke(false);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ReactMethod
|
|
39
|
+
public void goToMarket(String packageName, String marketPackage, String marketActivity) {
|
|
40
|
+
Uri uri = Uri.parse("market://details?id=" + packageName);
|
|
41
|
+
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
|
42
|
+
// https://www.cnblogs.com/upwgh/p/11054397.html
|
|
43
|
+
// intent.setClassName(marketPackage, marketActivity);
|
|
44
|
+
intent.setPackage(marketPackage);
|
|
45
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
46
|
+
ctx.startActivity(intent);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
package com.norcy.reactnativetoolkit;
|
|
2
|
+
|
|
3
|
+
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
|
4
|
+
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
|
5
|
+
|
|
6
|
+
import android.app.Activity;
|
|
7
|
+
import android.content.Context;
|
|
8
|
+
import android.content.Intent;
|
|
9
|
+
import android.content.pm.PackageManager;
|
|
10
|
+
import android.net.Uri;
|
|
11
|
+
import android.os.Build;
|
|
12
|
+
import android.os.Environment;
|
|
13
|
+
import android.provider.Settings;
|
|
14
|
+
import android.webkit.MimeTypeMap;
|
|
15
|
+
import androidx.core.content.FileProvider;
|
|
16
|
+
|
|
17
|
+
import com.facebook.react.bridge.ActivityEventListener;
|
|
18
|
+
import com.facebook.react.bridge.Promise;
|
|
19
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
20
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
21
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
22
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
23
|
+
|
|
24
|
+
import androidx.core.app.ActivityCompat;
|
|
25
|
+
import androidx.core.content.ContextCompat;
|
|
26
|
+
|
|
27
|
+
import java.io.File;
|
|
28
|
+
|
|
29
|
+
public class NCYAPI extends ReactContextBaseJavaModule implements ActivityEventListener {
|
|
30
|
+
private static final int REQUEST_CODE = 228228;
|
|
31
|
+
public static final String NAME = "ManageExternalStorage";
|
|
32
|
+
Promise promise;
|
|
33
|
+
|
|
34
|
+
public NCYAPI(ReactApplicationContext reactContext) {
|
|
35
|
+
super(reactContext);
|
|
36
|
+
reactContext.addActivityEventListener(this);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Override
|
|
40
|
+
public String getName() {
|
|
41
|
+
return "NCYAPI";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@ReactMethod
|
|
45
|
+
public void onAgree() {
|
|
46
|
+
UMengManager.getInstance().onUserAgree();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
50
|
+
public void setData(String key, String value) {
|
|
51
|
+
PreferencesManager.getInstance(getReactApplicationContext()).setString(key, value);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
55
|
+
public String getData(String key) {
|
|
56
|
+
return PreferencesManager.getInstance(getReactApplicationContext()).getString(key, "");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@ReactMethod
|
|
60
|
+
public void checkManagePermission(Promise promise) {
|
|
61
|
+
if (Build.VERSION.SDK_INT >= 30) {
|
|
62
|
+
promise.resolve(Environment.isExternalStorageManager());
|
|
63
|
+
} else {
|
|
64
|
+
int result = ContextCompat.checkSelfPermission(getReactApplicationContext(), READ_EXTERNAL_STORAGE);
|
|
65
|
+
int result1 = ContextCompat.checkSelfPermission(getReactApplicationContext(), WRITE_EXTERNAL_STORAGE);
|
|
66
|
+
promise.resolve(result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@ReactMethod
|
|
72
|
+
public void requestManagePermission(Promise promise) {
|
|
73
|
+
this.promise = promise;
|
|
74
|
+
if (Build.VERSION.SDK_INT >= 30) {
|
|
75
|
+
try {
|
|
76
|
+
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
|
|
77
|
+
intent.addCategory("android.intent.category.DEFAULT");
|
|
78
|
+
intent.setData(Uri.parse(String.format("package:%s",getReactApplicationContext().getPackageName())));
|
|
79
|
+
getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE, null);
|
|
80
|
+
} catch (Exception e) {
|
|
81
|
+
Intent intent = new Intent();
|
|
82
|
+
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
|
|
83
|
+
getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE, null);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
if (ActivityCompat.shouldShowRequestPermissionRationale(getCurrentActivity(), WRITE_EXTERNAL_STORAGE)) {
|
|
87
|
+
ActivityCompat.requestPermissions(getCurrentActivity(), new String[]{WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
|
|
88
|
+
} else {
|
|
89
|
+
int result = ContextCompat.checkSelfPermission(getReactApplicationContext(), READ_EXTERNAL_STORAGE);
|
|
90
|
+
int result1 = ContextCompat.checkSelfPermission(getReactApplicationContext(), WRITE_EXTERNAL_STORAGE);
|
|
91
|
+
this.promise.resolve(result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 分享指定的文件
|
|
98
|
+
* @param filePath 文件路径
|
|
99
|
+
* @param options 可选参数,如标题、MIME类型等
|
|
100
|
+
* @param promise Promise对象返回结果
|
|
101
|
+
*/
|
|
102
|
+
@ReactMethod
|
|
103
|
+
public void shareFile(String filePath, ReadableMap options, Promise promise) {
|
|
104
|
+
try {
|
|
105
|
+
// 检查文件是否存在
|
|
106
|
+
File file = new File(filePath);
|
|
107
|
+
if (!file.exists()) {
|
|
108
|
+
promise.reject("FILE_NOT_FOUND", "文件不存在: " + filePath);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 获取当前活动的Activity
|
|
113
|
+
Activity currentActivity = getCurrentActivity();
|
|
114
|
+
if (currentActivity == null) {
|
|
115
|
+
promise.reject("ACTIVITY_NOT_FOUND", "无法获取当前Activity");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 创建分享 Intent
|
|
120
|
+
Intent intent = new Intent(Intent.ACTION_SEND);
|
|
121
|
+
Uri fileUri;
|
|
122
|
+
|
|
123
|
+
// 适配 Android 7.0 及以上版本
|
|
124
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
125
|
+
fileUri = FileProvider.getUriForFile(
|
|
126
|
+
getReactApplicationContext(),
|
|
127
|
+
getReactApplicationContext().getPackageName() + ".provider",
|
|
128
|
+
file
|
|
129
|
+
);
|
|
130
|
+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
131
|
+
} else {
|
|
132
|
+
fileUri = Uri.fromFile(file);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 根据文件扩展名确定MIME类型
|
|
136
|
+
String mimeType = null;
|
|
137
|
+
if (options != null && options.hasKey("mimeType")) {
|
|
138
|
+
mimeType = options.getString("mimeType");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (mimeType == null) {
|
|
142
|
+
String extension = MimeTypeMap.getFileExtensionFromUrl(file.getAbsolutePath());
|
|
143
|
+
if (extension != null) {
|
|
144
|
+
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 如果无法确定MIME类型,使用通用类型
|
|
149
|
+
if (mimeType == null) {
|
|
150
|
+
mimeType = "*/*";
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
intent.setType(mimeType);
|
|
154
|
+
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
|
155
|
+
|
|
156
|
+
// 设置标题(如果提供)
|
|
157
|
+
String title = "分享文件";
|
|
158
|
+
if (options != null && options.hasKey("title")) {
|
|
159
|
+
title = options.getString("title");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 通过当前Activity启动
|
|
163
|
+
currentActivity.startActivity(Intent.createChooser(intent, title));
|
|
164
|
+
|
|
165
|
+
// 返回成功结果
|
|
166
|
+
promise.resolve(true);
|
|
167
|
+
} catch (Exception e) {
|
|
168
|
+
promise.reject("SHARE_ERROR", e.getMessage(), e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@Override
|
|
173
|
+
public void onNewIntent(Intent intent) {
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@Override
|
|
178
|
+
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
|
|
179
|
+
if (REQUEST_CODE != requestCode) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (Build.VERSION.SDK_INT >= 30) {
|
|
184
|
+
this.promise.resolve(Environment.isExternalStorageManager());
|
|
185
|
+
} else {
|
|
186
|
+
int result = ContextCompat.checkSelfPermission(getReactApplicationContext(), READ_EXTERNAL_STORAGE);
|
|
187
|
+
int result1 = ContextCompat.checkSelfPermission(getReactApplicationContext(), WRITE_EXTERNAL_STORAGE);
|
|
188
|
+
this.promise.resolve(result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package com.norcy.reactnativetoolkit;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments;
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
5
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
6
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
7
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
8
|
+
import com.facebook.react.bridge.WritableMap;
|
|
9
|
+
import com.umeng.analytics.MobclickAgent;
|
|
10
|
+
|
|
11
|
+
public class NCYReport extends ReactContextBaseJavaModule {
|
|
12
|
+
public NCYReport(ReactApplicationContext reactContext) {
|
|
13
|
+
super(reactContext);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Override
|
|
17
|
+
public String getName() {
|
|
18
|
+
return "NCYReport";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@ReactMethod
|
|
22
|
+
public void report(String key, ReadableMap params) {
|
|
23
|
+
WritableMap attributes = Arguments.createMap();
|
|
24
|
+
attributes.merge(params);
|
|
25
|
+
MobclickAgent.onEventObject(getReactApplicationContext(), key, attributes.toHashMap());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@ReactMethod
|
|
29
|
+
public void signIn(String userId) {
|
|
30
|
+
MobclickAgent.onProfileSignIn(userId);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@ReactMethod
|
|
34
|
+
public void signOut() {
|
|
35
|
+
MobclickAgent.onProfileSignOff();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ReactMethod
|
|
39
|
+
public void enterPage(String pageName) {
|
|
40
|
+
MobclickAgent.onPageStart(pageName);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@ReactMethod
|
|
44
|
+
public void leavePage(String pageName) {
|
|
45
|
+
MobclickAgent.onPageEnd(pageName);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|