1.fix
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
|||||||
39
android/app/src/main/java/com/rnpay/AppUtilsModule.java
Normal file
39
android/app/src/main/java/com/rnpay/AppUtilsModule.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package com.rnpay;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.Promise;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AppUtilsModule extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
|
public AppUtilsModule(ReactApplicationContext reactContext) {
|
||||||
|
super(reactContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "AppUtilsModule";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void isModifiedAppInstalled(String scheme, Promise promise) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme + "://check"));
|
||||||
|
PackageManager pm = getReactApplicationContext().getPackageManager();
|
||||||
|
List<android.content.pm.ResolveInfo> list = pm.queryIntentActivities(intent, 0);
|
||||||
|
promise.resolve(list != null && !list.isEmpty());
|
||||||
|
} catch (Exception e) {
|
||||||
|
promise.reject("CHECK_ERROR", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
android/app/src/main/java/com/rnpay/AppUtilsPackage.java
Normal file
23
android/app/src/main/java/com/rnpay/AppUtilsPackage.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package com.rnpay;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.bridge.NativeModule;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AppUtilsPackage implements ReactPackage {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||||
|
return Arrays.<NativeModule>asList(new AppUtilsModule(reactContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,8 +23,7 @@ public class MainApplication extends Application implements ReactApplication {
|
|||||||
protected List<ReactPackage> getPackages() {
|
protected List<ReactPackage> getPackages() {
|
||||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
packages.add(new AppUtilsPackage());
|
||||||
// packages.add(new MyReactNativePackage());
|
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
res/paytm.png
BIN
res/paytm.png
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 5.2 KiB |
@@ -589,14 +589,18 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
|
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
|
||||||
<TouchableOpacity onPress={() => {
|
<TouchableOpacity
|
||||||
const domain = getServerDomain();
|
onPress={() => {
|
||||||
const colonIdx = domain.lastIndexOf(':');
|
const domain = getServerDomain();
|
||||||
const host = colonIdx > 0 ? domain.substring(0, colonIdx) : domain;
|
const colonIdx = domain.lastIndexOf(':');
|
||||||
const port = colonIdx > 0 ? domain.substring(colonIdx + 1) : '';
|
const host = colonIdx > 0 ? domain.substring(0, colonIdx) : domain;
|
||||||
this.setState({ showServerSettings: true, settingsHost: host, settingsPort: port });
|
const port = colonIdx > 0 ? domain.substring(colonIdx + 1) : '';
|
||||||
}}>
|
this.setState({ showServerSettings: true, settingsHost: host, settingsPort: port });
|
||||||
<Text style={{ fontSize: 13, color: '#3498db' }}>⚙</Text>
|
}}
|
||||||
|
hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
|
||||||
|
style={{ padding: 6 }}
|
||||||
|
>
|
||||||
|
<Text style={{ fontSize: 20, color: '#3498db' }}>⚙</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={() => this.setState({ showAddWallet: true })} style={s.addBtn}>
|
<TouchableOpacity onPress={() => this.setState({ showAddWallet: true })} style={s.addBtn}>
|
||||||
<Text style={s.addBtnText}>+ Add</Text>
|
<Text style={s.addBtnText}>+ Add</Text>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { Alert, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
import { Alert, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||||
import { onProxyMessage, proxySendMessage, paytmPay } from 'rnwalletman';
|
import { onProxyMessage, proxySendMessage, paytmPay } from 'rnwalletman';
|
||||||
|
import { isModifiedAppInstalled } from '../services/appUtils';
|
||||||
|
|
||||||
export default function TestScreen() {
|
export default function TestScreen() {
|
||||||
const subRef = useRef<ReturnType<typeof onProxyMessage> | null>(null);
|
const subRef = useRef<ReturnType<typeof onProxyMessage> | null>(null);
|
||||||
@@ -26,6 +27,18 @@ export default function TestScreen() {
|
|||||||
proxySendMessage({ type: 'echo', messageId: `echo_${Date.now()}`, data: { text: `hello_${Date.now()}` } });
|
proxySendMessage({ type: 'echo', messageId: `echo_${Date.now()}`, data: { text: `hello_${Date.now()}` } });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePaytmMagicPackage = () => {
|
||||||
|
isModifiedAppInstalled('iwpaytmgtk')
|
||||||
|
.then(installed => Alert.alert('Paytm 魔改包', installed ? '已安装' : '未安装'))
|
||||||
|
.catch(err => Alert.alert('检测失败', String(err)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePhonePeMagicPackage = () => {
|
||||||
|
isModifiedAppInstalled('iwphonepegtk')
|
||||||
|
.then(installed => Alert.alert('PhonePe 魔改包', installed ? '已安装' : '未安装'))
|
||||||
|
.catch(err => Alert.alert('检测失败', String(err)));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.sectionTitle}>测试工具</Text>
|
<Text style={styles.sectionTitle}>测试工具</Text>
|
||||||
@@ -35,6 +48,12 @@ export default function TestScreen() {
|
|||||||
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handleEcho}>
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handleEcho}>
|
||||||
<Text style={styles.btnText}>Echo 测试</Text>
|
<Text style={styles.btnText}>Echo 测试</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handlePaytmMagicPackage}>
|
||||||
|
<Text style={styles.btnText}>Paytm 魔改包检测是否安装</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handlePhonePeMagicPackage}>
|
||||||
|
<Text style={styles.btnText}>PhonePe 魔改包检测是否安装</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Submodule servers/walletman updated: 5762febe51...82bbbe9a31
8
services/appUtils.ts
Normal file
8
services/appUtils.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { NativeModules, Platform } from 'react-native';
|
||||||
|
|
||||||
|
export async function isModifiedAppInstalled(scheme: string): Promise<boolean> {
|
||||||
|
if (Platform.OS !== 'android') return false;
|
||||||
|
const { AppUtilsModule } = NativeModules;
|
||||||
|
if (!AppUtilsModule) return false;
|
||||||
|
return await AppUtilsModule.isModifiedAppInstalled(scheme);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user