mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
supporting unified push as default if detected
This commit is contained in:
parent
42fedce27a
commit
855096d0ee
@ -18,6 +18,7 @@ import { Access } from 'src/access/Access';
|
|||||||
import { Dashboard } from 'src/dashboard/Dashboard';
|
import { Dashboard } from 'src/dashboard/Dashboard';
|
||||||
import { Session } from 'src/session/Session';
|
import { Session } from 'src/session/Session';
|
||||||
import ReceiveSharingIntent from 'react-native-receive-sharing-intent';
|
import ReceiveSharingIntent from 'react-native-receive-sharing-intent';
|
||||||
|
import {PermissionsAndroid} from 'react-native';
|
||||||
|
|
||||||
// silence warning: Sending `onAnimatedValueUpdate` with no listeners registered
|
// silence warning: Sending `onAnimatedValueUpdate` with no listeners registered
|
||||||
//LogBox.ignoreLogs(['Sending']);
|
//LogBox.ignoreLogs(['Sending']);
|
||||||
@ -27,6 +28,9 @@ export default function App() {
|
|||||||
const [sharing, setSharing] = useState();
|
const [sharing, setSharing] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
|
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS);
|
||||||
|
|
||||||
ReceiveSharingIntent.getReceivedFiles(files => {
|
ReceiveSharingIntent.getReceivedFiles(files => {
|
||||||
setSharing(files);
|
setSharing(files);
|
||||||
},
|
},
|
||||||
|
@ -158,8 +158,12 @@ dependencies {
|
|||||||
// The version of react-native is set by the React Native Gradle Plugin
|
// The version of react-native is set by the React Native Gradle Plugin
|
||||||
implementation("com.facebook.react:react-android")
|
implementation("com.facebook.react:react-android")
|
||||||
|
|
||||||
|
implementation 'androidx.core:core:1.8.0'
|
||||||
|
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
|
||||||
|
|
||||||
|
implementation 'com.github.UnifiedPush:android-connector:2.1.1'
|
||||||
|
|
||||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
||||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
@ -73,5 +74,19 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:enabled="true"
|
||||||
|
android:name=".CustomReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.unifiedpush.android.connector.MESSAGE"/>
|
||||||
|
<action android:name="org.unifiedpush.android.connector.UNREGISTERED"/>
|
||||||
|
<action android:name="org.unifiedpush.android.connector.NEW_ENDPOINT"/>
|
||||||
|
<action android:name="org.unifiedpush.android.connector.REGISTRATION_FAILED"/>
|
||||||
|
<action android:name="org.unifiedpush.android.connector.REGISTRATION_REFUSED"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.databag;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.unifiedpush.android.connector.MessagingReceiver;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import android.app.ActivityManager.RunningAppProcessInfo;
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.media.RingtoneManager;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactApplication;
|
||||||
|
import com.facebook.react.ReactInstanceManager;
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.ReactContext;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||||
|
|
||||||
|
public class CustomReceiver extends MessagingReceiver {
|
||||||
|
public CustomReceiver() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean forgrounded () {
|
||||||
|
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
|
||||||
|
ActivityManager.getMyMemoryState(appProcessInfo);
|
||||||
|
return (appProcessInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND || appProcessInfo.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewEndpoint(@NotNull Context context, @NotNull String endpoint, @NotNull String instance) {
|
||||||
|
|
||||||
|
final ReactInstanceManager reactInstanceManager =
|
||||||
|
((ReactApplication) context.getApplicationContext())
|
||||||
|
.getReactNativeHost()
|
||||||
|
.getReactInstanceManager();
|
||||||
|
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||||
|
|
||||||
|
WritableMap params = Arguments.createMap();
|
||||||
|
params.putString("instance", instance);
|
||||||
|
params.putString("endpoint", endpoint);
|
||||||
|
reactContext
|
||||||
|
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||||
|
.emit("unifiedPushURL", params);
|
||||||
|
|
||||||
|
// Called when a new endpoint be used for sending push messages
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRegistrationFailed(@NotNull Context context, @NotNull String instance) {
|
||||||
|
// called when the registration is not possible, eg. no network
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnregistered(@NotNull Context context, @NotNull String instance) {
|
||||||
|
// called when this application is unregistered from receiving push messages
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(@NotNull Context context, @NotNull byte[] message, @NotNull String instance) {
|
||||||
|
|
||||||
|
if (forgrounded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String strMessage = new String(message, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(context, MainActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, intent,
|
||||||
|
PendingIntent.FLAG_IMMUTABLE);
|
||||||
|
|
||||||
|
String channelId = "fcm_default_channel";
|
||||||
|
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||||
|
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context,
|
||||||
|
channelId)
|
||||||
|
.setSmallIcon(R.mipmap.ic_launcher)
|
||||||
|
.setContentTitle(strMessage).setAutoCancel(true).setSound(
|
||||||
|
defaultSoundUri).setContentIntent(pendingIntent);
|
||||||
|
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
|
||||||
|
Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
NotificationChannel channel = new NotificationChannel(channelId, "Channel human readable title",
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationManager.notify(0, notificationBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.databag;
|
package com.databag;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import com.facebook.react.ReactActivity;
|
import com.facebook.react.ReactActivity;
|
||||||
@ -7,6 +8,19 @@ import com.facebook.react.ReactActivityDelegate;
|
|||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||||
import com.facebook.react.defaults.DefaultReactActivityDelegate;
|
import com.facebook.react.defaults.DefaultReactActivityDelegate;
|
||||||
|
|
||||||
|
import org.unifiedpush.android.connector.UnifiedPush;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.unifiedpush.android.connector.RegistrationDialogContent;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactApplication;
|
||||||
|
import com.facebook.react.ReactInstanceManager;
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.ReactContext;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||||
|
|
||||||
public class MainActivity extends ReactActivity {
|
public class MainActivity extends ReactActivity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,6 +35,25 @@ public class MainActivity extends ReactActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(null);
|
super.onCreate(null);
|
||||||
|
MainActivity activityContext = this;
|
||||||
|
|
||||||
|
this.getSharedPreferences("unifiedpush.connector", Context.MODE_PRIVATE).edit().putBoolean("unifiedpush.no_distrib_dialog", true).apply();
|
||||||
|
|
||||||
|
|
||||||
|
ReactInstanceManager mReactInstanceManager = getReactNativeHost().getReactInstanceManager();
|
||||||
|
mReactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
|
||||||
|
public void onReactContextInitialized(ReactContext validContext) {
|
||||||
|
|
||||||
|
UnifiedPush.registerAppWithDialog(
|
||||||
|
activityContext,
|
||||||
|
"default",
|
||||||
|
new RegistrationDialogContent(),
|
||||||
|
new ArrayList<String>(),
|
||||||
|
getApplicationContext().getPackageName()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,3 +21,14 @@ buildscript {
|
|||||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url "https://www.jitpack.io"
|
||||||
|
content {
|
||||||
|
includeModule 'com.github.UnifiedPush', 'android-connector'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
export async function setAccountAccess(server, token, appName, appVersion, platform, deviceToken, notifications) {
|
export async function setAccountAccess(server, token, appName, appVersion, platform, deviceToken, pushType, notifications) {
|
||||||
let access = await fetchWithTimeout(`https://${server}/account/access?token=${token}&appName=${appName}&appVersion=${appVersion}&platform=${platform}&deviceToken=${deviceToken}`, { method: 'PUT', body: JSON.stringify(notifications) })
|
let access = await fetchWithTimeout(`https://${server}/account/access?token=${token}&appName=${appName}&appVersion=${appVersion}&platform=${platform}&deviceToken=${deviceToken}&pushType=${pushType}`, { method: 'PUT', body: JSON.stringify(notifications) })
|
||||||
checkResponse(access)
|
checkResponse(access)
|
||||||
return await access.json()
|
return await access.json()
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
import base64 from 'react-native-base64'
|
import base64 from 'react-native-base64'
|
||||||
|
|
||||||
export async function setLogin(username, server, password, appName, appVersion, platform, deviceToken, notifications) {
|
export async function setLogin(username, server, password, appName, appVersion, platform, deviceToken, pushType, notifications) {
|
||||||
let headers = new Headers()
|
let headers = new Headers()
|
||||||
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
|
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
|
||||||
let login = await fetchWithTimeout(`https://${server}/account/apps?appName=${appName}&appVersion=${appVersion}&platform=${platform}&deviceToken=${deviceToken}`, { method: 'POST', body: JSON.stringify(notifications), headers: headers })
|
let login = await fetchWithTimeout(`https://${server}/account/apps?appName=${appName}&appVersion=${appVersion}&platform=${platform}&deviceToken=${deviceToken}&pushType=${pushType}`, { method: 'POST', body: JSON.stringify(notifications), headers: headers })
|
||||||
checkResponse(login)
|
checkResponse(login)
|
||||||
return await login.json()
|
return await login.json()
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import { ChannelContext } from 'context/ChannelContext';
|
|||||||
import { RingContext } from 'context/RingContext';
|
import { RingContext } from 'context/RingContext';
|
||||||
import { getVersion, getApplicationName, getDeviceId } from 'react-native-device-info'
|
import { getVersion, getApplicationName, getDeviceId } from 'react-native-device-info'
|
||||||
import messaging from '@react-native-firebase/messaging';
|
import messaging from '@react-native-firebase/messaging';
|
||||||
|
import { DeviceEventEmitter } from 'react-native';
|
||||||
|
|
||||||
export function useAppContext() {
|
export function useAppContext() {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
@ -33,6 +34,7 @@ export function useAppContext() {
|
|||||||
|
|
||||||
const ws = useRef(null);
|
const ws = useRef(null);
|
||||||
const deviceToken = useRef(null);
|
const deviceToken = useRef(null);
|
||||||
|
const pushType = useRef(null);
|
||||||
const access = useRef(null);
|
const access = useRef(null);
|
||||||
const init = useRef(false);
|
const init = useRef(false);
|
||||||
|
|
||||||
@ -41,19 +43,23 @@ export function useAppContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
|
// select the unified token if available
|
||||||
|
DeviceEventEmitter.addListener('unifiedPushURL', (e) => {
|
||||||
|
deviceToken.current = e.endpoint;
|
||||||
|
pushType.current = "up";
|
||||||
|
});
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
try {
|
const token = await messaging().getToken();
|
||||||
deviceToken.current = await messaging().getToken();
|
if (!deviceToken.current) {
|
||||||
}
|
deviceToken.current = token;
|
||||||
catch (err) {
|
pushType.current = "fcm";
|
||||||
console.log(err);
|
|
||||||
//Alert.alert('FCM', err.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
deviceToken.current = null;
|
|
||||||
}
|
}
|
||||||
access.current = await store.actions.init();
|
access.current = await store.actions.init();
|
||||||
if (access.current) {
|
if (access.current) {
|
||||||
@ -104,7 +110,7 @@ export function useAppContext() {
|
|||||||
throw new Error('invalid session state');
|
throw new Error('invalid session state');
|
||||||
}
|
}
|
||||||
await addAccount(server, username, password, token);
|
await addAccount(server, username, password, token);
|
||||||
const session = await setLogin(username, server, password, getApplicationName(), getVersion(), getDeviceId(), deviceToken.current, notifications)
|
const session = await setLogin(username, server, password, getApplicationName(), getVersion(), getDeviceId(), deviceToken.current, pushType.current, notifications)
|
||||||
access.current = { server, token: session.appToken, guid: session.guid };
|
access.current = { server, token: session.appToken, guid: session.guid };
|
||||||
await store.actions.setSession(access.current);
|
await store.actions.setSession(access.current);
|
||||||
await setSession();
|
await setSession();
|
||||||
@ -116,7 +122,7 @@ export function useAppContext() {
|
|||||||
if (!init.current || access.current) {
|
if (!init.current || access.current) {
|
||||||
throw new Error('invalid session state');
|
throw new Error('invalid session state');
|
||||||
}
|
}
|
||||||
const session = await setAccountAccess(server, token, getApplicationName(), getVersion(), getDeviceId(), deviceToken.current, notifications);
|
const session = await setAccountAccess(server, token, getApplicationName(), getVersion(), getDeviceId(), deviceToken.current, pushType.current, notifications);
|
||||||
access.current = { server, token: session.appToken, guid: session.guid };
|
access.current = { server, token: session.appToken, guid: session.guid };
|
||||||
await store.actions.setSession(access.current);
|
await store.actions.setSession(access.current);
|
||||||
await setSession();
|
await setSession();
|
||||||
@ -129,7 +135,7 @@ export function useAppContext() {
|
|||||||
throw new Error('invalid session state');
|
throw new Error('invalid session state');
|
||||||
}
|
}
|
||||||
const acc = username.split('@');
|
const acc = username.split('@');
|
||||||
const session = await setLogin(acc[0], acc[1], password, getApplicationName(), getVersion(), getDeviceId(), deviceToken.current, notifications)
|
const session = await setLogin(acc[0], acc[1], password, getApplicationName(), getVersion(), getDeviceId(), deviceToken.current, pushType.current, notifications)
|
||||||
access.current = { server: acc[1], token: session.appToken, guid: session.guid };
|
access.current = { server: acc[1], token: session.appToken, guid: session.guid };
|
||||||
await store.actions.setSession(access.current);
|
await store.actions.setSession(access.current);
|
||||||
await setSession();
|
await setSession();
|
||||||
@ -143,8 +149,10 @@ export function useAppContext() {
|
|||||||
}
|
}
|
||||||
updateState({ loggingOut: true });
|
updateState({ loggingOut: true });
|
||||||
try {
|
try {
|
||||||
await messaging().deleteToken();
|
if (pushType.current == "fcm") {
|
||||||
deviceToken.current = await messaging().getToken();
|
await messaging().deleteToken();
|
||||||
|
deviceToken.current = await messaging().getToken();
|
||||||
|
}
|
||||||
await clearLogin(state.server, state.token);
|
await clearLogin(state.server, state.token);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
|
Loading…
Reference in New Issue
Block a user