Skip to content

Commit 4eccab8

Browse files
committed
implement android modules
1 parent 164a52f commit 4eccab8

15 files changed

+412
-76
lines changed

App/Platform/Alert.ios.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

App/Platform/Linking.ios.js

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
let NavigatorNavigationBarStyles = require('NavigatorNavigationBarStylesAndroid');
2+
3+
NavigatorNavigationBarStyles.General.TotalNavHeight = 48;
4+
5+
export default NavigatorNavigationBarStyles;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React from 'react';
2+
3+
import {
4+
ListView,
5+
RefreshControl,
6+
} from 'react-native';
7+
8+
import isPromise from 'is-promise';
9+
10+
function delay(time) {
11+
return new Promise((resolve) => setTimeout(resolve, time));
12+
}
13+
14+
class RefreshableListView extends React.Component {
15+
16+
static propTypes = {
17+
loadData: React.PropTypes.func.isRequired,
18+
minDisplayTime: React.PropTypes.number,
19+
minBetweenTime: React.PropTypes.number,
20+
androidRefreshable: React.PropTypes.bool,
21+
};
22+
23+
static defaultProps = {
24+
loadData: (() => {}),
25+
minDisplayTime: 300,
26+
minBetweenTime: 300,
27+
androidRefreshable: true,
28+
};
29+
30+
constructor(props) {
31+
super(props);
32+
33+
this.state = {};
34+
}
35+
36+
handleRefresh = () => {
37+
if (this.willRefresh) return;
38+
39+
this.willRefresh = true;
40+
41+
var loadingDataPromise = new Promise((resolve) => {
42+
var loadDataReturnValue = this.props.loadData(resolve);
43+
44+
if (isPromise(loadDataReturnValue)) {
45+
loadingDataPromise = loadDataReturnValue;
46+
}
47+
48+
Promise.all([
49+
loadingDataPromise,
50+
new Promise((resolve) => this.setState({isRefreshing: true}, resolve)),
51+
delay(this.props.minDisplayTime),
52+
])
53+
.then(() => delay(this.props.minBetweenTime))
54+
.then(() => {
55+
this.willRefresh = false;
56+
this.setState({isRefreshing: false});
57+
});
58+
});
59+
};
60+
61+
render() {
62+
const listViewProps = {
63+
dataSource: this.props.dataSource,
64+
renderRow: this.props.renderRow,
65+
renderFooter: this.props.renderFooter,
66+
style: [this.props.style, {flex: 1}],
67+
renderScrollComponent: this.props.renderScrollComponent,
68+
renderHeader: this.props.renderHeaderWrapper,
69+
};
70+
71+
const pullToRefreshProps = {
72+
style: [this.props.pullToRefreshStyle, {flex: 1}],
73+
refreshing: this.state.isRefreshing,
74+
onRefresh: this.handleRefresh,
75+
enabled: this.props.androidRefreshable,
76+
};
77+
78+
return (
79+
<RefreshControl {...pullToRefreshProps}>
80+
<ListView {...listViewProps} />
81+
</RefreshControl>
82+
);
83+
}
84+
}
85+
86+
export default RefreshableListView;

App/Platform/StatusBar.android.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react';
2+
3+
var StatusBar = {
4+
setNetworkActive(active) {
5+
},
6+
setHidden(hidden) {
7+
},
8+
setStyle(style) {
9+
},
10+
};
11+
12+
export default StatusBar;

App/Root/Launcher.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import AppConstants from '../Constants/AppConstants';
22
import Routes from '../Navigation/Routes';
33

44
import StatusBar from '../Platform/StatusBar';
5-
import Linking from '../Platform/Linking';
5+
6+
import {
7+
Linking
8+
} from 'react-native';
69

710
var Launcher = {
811
launch: function(root, action) {

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ In the `ios` directory
1818
### Android
1919

2020
* You might need to do this to run it in Android Studio or on real device: `adb reverse tcp:8081 tcp:8081`
21+
* And for the sample server: `adb reverse tcp:3000 tcp:3000`
2122
* To run from command line try: `react-native run-android`
2223
### Server
2324

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package com.sample;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
import android.content.SharedPreferences;
6+
import android.content.pm.PackageInfo;
7+
import android.content.pm.PackageManager;
8+
import android.os.Build;
9+
import android.os.Bundle;
10+
import android.provider.Settings;
11+
import com.facebook.react.bridge.*;
12+
import com.sample.utils.LocaleUtils;
13+
import com.sample.utils.LocaleUtils;
14+
15+
import javax.annotation.Nullable;
16+
import java.util.UUID;
17+
18+
public class EnvironmentManager extends ReactContextBaseJavaModule {
19+
static final String UUID_PARAM_NAME = "uuid";
20+
21+
private static final String PREFS_DEBUG_SERVER_HOST_KEY = "debug_http_host";
22+
private static final String EMULATOR_LOCALHOST = "10.0.2.2";
23+
private static final String GENYMOTION_LOCALHOST = "10.0.3.2";
24+
private static final String DEVICE_LOCALHOST = "localhost";
25+
26+
private Context mApplication;
27+
private Activity mActivity;
28+
29+
public EnvironmentManager(ReactApplicationContext reactContext) {
30+
super(reactContext);
31+
mApplication = getReactApplicationContext().getApplicationContext();
32+
}
33+
34+
@Override
35+
public String getName() {
36+
return "EnvironmentManager";
37+
}
38+
39+
@ReactMethod
40+
public void get(Callback callback) {
41+
WritableMap environment = Arguments.createMap();
42+
43+
PackageInfo packageInfo = null;
44+
try {
45+
packageInfo = mApplication.getPackageManager().getPackageInfo(mApplication.getPackageName(), 0);
46+
} catch (PackageManager.NameNotFoundException e) {
47+
e.printStackTrace();
48+
}
49+
50+
environment.putString("name", "debug");
51+
//environment.putString("name", BuildConfig.ENVIRONMENT);
52+
environment.putBoolean("simulator", Build.FINGERPRINT.startsWith("generic"));
53+
environment.putString("buildCode", String.valueOf(packageInfo.versionCode));
54+
environment.putString("version", String.valueOf(packageInfo.versionName));
55+
environment.putString("uuid", getUuid());
56+
environment.putString("locale", LocaleUtils.getDefaultLocaleForServer());
57+
environment.putString("packageName", mApplication.getPackageName());
58+
environment.putInt("clientApplicationId", 95);
59+
environment.putString("osVersion", "Android " + android.os.Build.VERSION.RELEASE);
60+
environment.putString("phoneVersion", getPhoneVersion());
61+
environment.putString("apiKey", "ecd3641df005e2a911ca78ce6d56064212esdere");
62+
environment.putString("remoteAPIHost", getRemoteApiHostWithPort());
63+
64+
callback.invoke(environment);
65+
}
66+
67+
private boolean isRunningOnGenymotion() {
68+
return Build.FINGERPRINT.contains("vbox");
69+
}
70+
71+
private boolean isRunningOnStockEmulator() {
72+
return Build.FINGERPRINT.contains("generic");
73+
}
74+
75+
private String getRemoteApiHostWithPort() {
76+
return getRemoteAPIHost() + ":" + getPortNumber();
77+
}
78+
79+
private String getRemoteAPIHost() {
80+
if ("debug".equals("remote")) {
81+
//if (BuildConfig.ENVIRONMENT.equals("remote")) {
82+
return getLocalIpAddress();
83+
} else if (isRunningOnGenymotion()) {
84+
return GENYMOTION_LOCALHOST;
85+
} else if (isRunningOnStockEmulator()) {
86+
return EMULATOR_LOCALHOST;
87+
} else {
88+
if (getLocalIpAddress() != null && !getLocalIpAddress().isEmpty()) {
89+
return getLocalIpAddress();
90+
}
91+
return DEVICE_LOCALHOST;
92+
}
93+
}
94+
95+
private @Nullable String getLocalIpAddress() {
96+
Bundle extras = getCurrentActivity().getIntent().getExtras();
97+
if (extras != null) {
98+
String localIpAddress = extras.getString("LOCAL_IP_ADDRESS");
99+
if (localIpAddress!= null) {
100+
return localIpAddress;
101+
}
102+
}
103+
return null;
104+
}
105+
106+
private String getPortNumber() {
107+
Bundle extras = getCurrentActivity().getIntent().getExtras();
108+
if (extras != null) {
109+
String portNumber = extras.getString("PORT_NUMBER");
110+
if (portNumber != null) {
111+
return portNumber;
112+
}
113+
}
114+
115+
return "3001";
116+
}
117+
118+
private String getUuid() {
119+
SharedPreferences prefs = mApplication.getSharedPreferences(
120+
SampleConstants.APP_PREFS_NAME, Context.MODE_PRIVATE);
121+
String uuid = prefs.getString(UUID_PARAM_NAME, null);
122+
123+
if (uuid == null) {
124+
String androidId = Settings.Secure.getString(mApplication.getContentResolver(), Settings.Secure.ANDROID_ID);
125+
uuid = androidId != null ? androidId : UUID.randomUUID().toString();
126+
uuid = "Sample_" + uuid;
127+
SharedPreferences.Editor editor = prefs.edit();
128+
editor.putString(UUID_PARAM_NAME, uuid);
129+
editor.apply();
130+
}
131+
132+
return uuid;
133+
}
134+
135+
private String getPhoneVersion() {
136+
String manufacturer = android.os.Build.MANUFACTURER;
137+
String model = android.os.Build.MODEL;
138+
if (model.startsWith(manufacturer)) {
139+
return capitalize(model);
140+
} else {
141+
return capitalize(manufacturer) + " " + model;
142+
}
143+
}
144+
145+
private static String capitalize(String str) {
146+
if (str == null || str.length() == 0) {
147+
return "";
148+
}
149+
char[] arr = str.toCharArray();
150+
boolean capitalizeNext = true;
151+
String phrase = "";
152+
for (char c : arr) {
153+
if (capitalizeNext && Character.isLetter(c)) {
154+
phrase += Character.toUpperCase(c);
155+
capitalizeNext = false;
156+
continue;
157+
} else if (Character.isWhitespace(c)) {
158+
capitalizeNext = true;
159+
}
160+
phrase += c;
161+
}
162+
return phrase;
163+
}
164+
165+
}

android/app/src/main/java/com/sample/MainApplication.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ protected boolean getUseDeveloperSupport() {
2323
@Override
2424
protected List<ReactPackage> getPackages() {
2525
return Arrays.<ReactPackage>asList(
26-
new MainReactPackage()
26+
new MainReactPackage(),
27+
new SamplePackage()
2728
);
2829
}
2930
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.sample;
2+
3+
public class SampleConstants {
4+
public static final String APP_PREFS_NAME = "sample-app-prefs";
5+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.sample;
2+
3+
import android.app.Activity;
4+
import com.facebook.react.ReactPackage;
5+
import com.facebook.react.bridge.JavaScriptModule;
6+
import com.facebook.react.bridge.NativeModule;
7+
import com.facebook.react.bridge.ReactApplicationContext;
8+
import com.facebook.react.uimanager.ViewManager;
9+
10+
import java.util.ArrayList;
11+
import java.util.Collections;
12+
import java.util.List;
13+
14+
public class SamplePackage implements ReactPackage {
15+
private Activity mActivity;
16+
17+
//public SamplePackage(Activity activity) {
18+
// mActivity = activity;
19+
//}
20+
21+
@Override
22+
public List<Class<? extends JavaScriptModule>> createJSModules() {
23+
return Collections.emptyList();
24+
}
25+
26+
@Override
27+
public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
28+
return Collections.emptyList();
29+
}
30+
31+
@Override
32+
public List<NativeModule> createNativeModules(
33+
ReactApplicationContext reactContext) {
34+
List<NativeModule> modules = new ArrayList<>();
35+
36+
modules.add(new EnvironmentManager(reactContext));
37+
modules.add(new TestRunnerManager(reactContext));
38+
39+
return modules;
40+
}
41+
42+
}

0 commit comments

Comments
 (0)