我正在尝试在位置更新时从Android端收到一个事件。这是我的代码:
package com.prop;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.support.v4.content.LocalBroadcastManager;
import com.facebook.react.bridge.Arguments;
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 com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
public class GeoLocationModule extends ReactContextBaseJavaModule {
public GeoLocationModule(final ReactApplicationContext reactContext) {
super(reactContext);
BroadcastReceiver geoLocationReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Location message = intent.getParcelableExtra("message");
WritableMap map = Arguments.createMap();
WritableMap coordMap = Arguments.createMap();
coordMap.putDouble("latitude", message.getLatitude());
coordMap.putDouble("longitude", message.getLongitude());
coordMap.putDouble("accuracy", message.getAccuracy());
coordMap.putDouble("altitude", message.getAltitude());
coordMap.putDouble("heading", message.getBearing());
coordMap.putDouble("speed", message.getSpeed());
map.putMap("coords", coordMap);
map.putDouble("timestamp", message.getTime());
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("updateLocation", map);
}
};
LocalBroadcastManager.getInstance(getReactApplicationContext()).registerReceiver(geoLocationReceiver, new IntentFilter("GeoLocationUpdate"));
}
@Override
public String getName() {
return "GeoLocation";
}
@ReactMethod
public void startService(Promise promise) {
String result = "Success";
try {
Intent intent = new Intent(GeoLocationService.FOREGROUND);
intent.setClass(this.getReactApplicationContext(), GeoLocationService.class);
getReactApplicationContext().startService(intent);
} catch (Exception e) {
promise.reject(e);
return;
}
promise.resolve(result);
}
@ReactMethod
public void stopService(Promise promise) {
String result = "Success";
try {
Intent intent = new Intent(GeoLocationService.FOREGROUND);
intent.setClass(this.getReactApplicationContext(), GeoLocationService.class);
this.getReactApplicationContext().stopService(intent);
} catch (Exception e) {
promise.reject(e);
return;
}
promise.resolve(result);
}
private void sendEvent(Location message) {
WritableMap map = Arguments.createMap();
WritableMap coordMap = Arguments.createMap();
coordMap.putDouble("latitude", message.getLatitude());
coordMap.putDouble("longitude", message.getLongitude());
coordMap.putDouble("accuracy", message.getAccuracy());
coordMap.putDouble("altitude", message.getAltitude());
coordMap.putDouble("heading", message.getBearing());
coordMap.putDouble("speed", message.getSpeed());
map.putMap("coords", coordMap);
map.putDouble("timestamp", message.getTime());
getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("updateLocation", map);
}
}
并且在React本机端 DeviceEventEmitter 就像:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
DeviceEventEmitter
} from 'react-native';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
const updateLocation = (geoData) => {
alert(geoData)
};
DeviceEventEmitter.addListener('onSessionConnect', updateLocation);
type Props = {};
export default class App extends Component<Props> {
componentWillMount() {
alert('test');
DeviceEventEmitter.addListener('updateLocation', function (geoData) {
// handle event.
alert(geoData);
});
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit App.js
</Text>
<Text style={styles.instructions}>
{instructions}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
我无法弄清楚为什么它不会触发位置更新我的服务类是:
package com.prop;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.R;
public class GeoLocationService extends Service {
public static final String FOREGROUND = "com.prop.location.FOREGROUND";
private static int GEOLOCATION_NOTIFICATION_ID = 12345689;
LocationManager locationManager = null;
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
GeoLocationService.this.sendMessage(location);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {}
@Override
public void onProviderEnabled(String s) {}
@Override
public void onProviderDisabled(String s) {}
};
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onCreate() {
locationManager = getSystemService(LocationManager.class);
int permissionCheck = ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, locationListener);
}
}
private void sendMessage(Location location) {
try {
Intent intent = new Intent("GeoLocationUpdate");
intent.putExtra("message", location);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
locationManager.removeUpdates(locationListener);
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(GEOLOCATION_NOTIFICATION_ID, getCompatNotification());
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private Notification getCompatNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
String str = "Is using your location in the background";
builder
.setSmallIcon(com.prop.R.mipmap.ic_gps_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), com.prop.R.mipmap.ic_gps_icon))
.setContentTitle("App Name")
.setContentText(str)
.setTicker(str)
.setWhen(System.currentTimeMillis());
Intent startIntent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 1000, startIntent, 0);
builder.setContentIntent(contentIntent);
return builder.build();
}
}
请帮我解释为什么android方面没有发射或js方面没有接收事件。我的Android清单中有以下权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>