Merge branch 'dev'
This commit is contained in:
commit
02bb2c0318
|
@ -6,7 +6,7 @@ UnifiedPush provider for Nextcloud - android application
|
|||
height="80">](https://f-droid.org/packages/org.unifiedpush.distributor.nextpush/)
|
||||
|
||||
## Usage
|
||||
This application require the [server application](https://github.com/UP-NextPush/server-app) to be intalled on the server and the [Nextcloud application](https://apps.nextcloud.com/apps/android_nextcloud_app) on the mobile phone.
|
||||
This application require the [server application](https://github.com/UP-NextPush/server-app) to be installed on the server and the [Nextcloud application](https://apps.nextcloud.com/apps/android_nextcloud_app) on the mobile phone.
|
||||
|
||||
## Credit
|
||||
This application has been inspired by [Nextcloud Push Notifier](https://gitlab.com/Nextcloud-Push/nextcloud-push-notifier)
|
||||
|
|
|
@ -17,8 +17,8 @@ android {
|
|||
applicationId "org.unifiedpush.distributor.nextpush"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 30
|
||||
versionCode 6
|
||||
versionName "1.0.1"
|
||||
versionCode 7
|
||||
versionName "1.1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
|
|
@ -65,11 +65,14 @@ fun nextcloudAppNotInstalledDialog(context: Context) {
|
|||
builder.show()
|
||||
}
|
||||
|
||||
fun isConnected(context: Context) : Boolean {
|
||||
fun isConnected(context: Context, showDialog: Boolean = false) : Boolean {
|
||||
try {
|
||||
ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(context)
|
||||
} catch (e: NextcloudFilesAppAccountNotFoundException) {
|
||||
nextcloudAppNotInstalledDialog(context)
|
||||
if (showDialog) {
|
||||
nextcloudAppNotInstalledDialog(context)
|
||||
}
|
||||
return false
|
||||
} catch (e: NoCurrentAccountSelectedException) {
|
||||
Log.d(TAG,"Device is not connected")
|
||||
return false
|
||||
|
|
|
@ -46,7 +46,7 @@ class MainActivity : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
setSupportActionBar(findViewById(R.id.toolbar))
|
||||
if (isConnected(this)) {
|
||||
if (isConnected(this, showDialog = true)) {
|
||||
showMain()
|
||||
} else {
|
||||
findViewById<Button>(R.id.button_connection).setOnClickListener {
|
||||
|
|
|
@ -48,6 +48,23 @@ fun sendEndpoint(context: Context, connectorToken: String) {
|
|||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun sendRegistrationFailed(
|
||||
context: Context,
|
||||
application: String,
|
||||
connectorToken: String,
|
||||
message: String = ""
|
||||
) {
|
||||
if (application.isNullOrBlank()) {
|
||||
return
|
||||
}
|
||||
val broadcastIntent = Intent()
|
||||
broadcastIntent.`package` = application
|
||||
broadcastIntent.action = ACTION_REGISTRATION_FAILED
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, connectorToken)
|
||||
broadcastIntent.putExtra(EXTRA_MESSAGE, message)
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun sendUnregistered(context: Context, connectorToken: String) {
|
||||
val application = getApp(context, connectorToken)
|
||||
if (application.isNullOrBlank()) {
|
||||
|
@ -76,3 +93,11 @@ fun getEndpoint(context: Context, connectorToken: String): String {
|
|||
val appToken = db.getAppToken(connectorToken)
|
||||
return "${getUrl(context)}/push/$appToken"
|
||||
}
|
||||
|
||||
fun isTokenOk(context: Context, connectorToken: String, app: String): Boolean {
|
||||
val db = getDb(context)
|
||||
if (connectorToken !in db.listTokens()) {
|
||||
return true
|
||||
}
|
||||
return db.getPackageName(connectorToken) == app
|
||||
}
|
||||
|
|
|
@ -4,12 +4,15 @@ import android.content.BroadcastReceiver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import org.unifiedpush.distributor.nextpush.account.isConnected
|
||||
|
||||
import org.unifiedpush.distributor.nextpush.distributor.*
|
||||
import org.unifiedpush.distributor.nextpush.api.createQueue
|
||||
import org.unifiedpush.distributor.nextpush.api.delQueue
|
||||
import org.unifiedpush.distributor.nextpush.api.apiCreateApp
|
||||
import org.unifiedpush.distributor.nextpush.api.apiDeleteApp
|
||||
import org.unifiedpush.distributor.nextpush.services.wakeLock
|
||||
import java.lang.Exception
|
||||
|
||||
/**
|
||||
* THIS SERVICE IS USED BY OTHER APPS TO REGISTER
|
||||
|
@ -20,6 +23,7 @@ private const val TAG = "RegisterBroadcastReceiver"
|
|||
class RegisterBroadcastReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
wakeLock?.acquire(10000L /*10 secs*/)
|
||||
when (intent!!.action) {
|
||||
ACTION_REGISTER ->{
|
||||
Log.i(TAG,"REGISTER")
|
||||
|
@ -29,10 +33,27 @@ class RegisterBroadcastReceiver : BroadcastReceiver() {
|
|||
Log.w(TAG,"Trying to register an app without packageName")
|
||||
return
|
||||
}
|
||||
if (!isConnected(context!!, showDialog = false)) {
|
||||
sendRegistrationFailed(
|
||||
context,
|
||||
application,
|
||||
connectorToken,
|
||||
message = "NextPush is not connected"
|
||||
)
|
||||
return
|
||||
}
|
||||
if (!isTokenOk(context, connectorToken, application)) {
|
||||
sendRegistrationFailed(
|
||||
context,
|
||||
application,
|
||||
connectorToken
|
||||
)
|
||||
return
|
||||
}
|
||||
if (connectorToken !in createQueue) {
|
||||
createQueue.add(connectorToken)
|
||||
apiCreateApp(
|
||||
context!!.applicationContext,
|
||||
context.applicationContext,
|
||||
application,
|
||||
connectorToken
|
||||
) {
|
||||
|
@ -52,15 +73,24 @@ class RegisterBroadcastReceiver : BroadcastReceiver() {
|
|||
if (connectorToken !in delQueue) {
|
||||
delQueue.add(connectorToken)
|
||||
sendUnregistered(context.applicationContext, connectorToken)
|
||||
apiDeleteApp(context.applicationContext, connectorToken) {
|
||||
val db = getDb(context.applicationContext)
|
||||
db.unregisterApp(connectorToken)
|
||||
Log.d(TAG, "Unregistration is finished")
|
||||
try {
|
||||
apiDeleteApp(context.applicationContext, connectorToken) {
|
||||
val db = getDb(context.applicationContext)
|
||||
db.unregisterApp(connectorToken)
|
||||
Log.d(TAG, "Unregistration is finished")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Could not delete app")
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Already deleting $connectorToken")
|
||||
}
|
||||
}
|
||||
}
|
||||
wakeLock?.let {
|
||||
if (it.isHeld) {
|
||||
it.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ fun createForegroundNotification(context: Context): Notification {
|
|||
appName,
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).let {
|
||||
it.description = context.getString(R.string.listening_notif_description)
|
||||
it.description = context.getString(R.string.foreground_notif_description)
|
||||
it
|
||||
}
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
|
@ -50,9 +50,9 @@ fun createForegroundNotification(context: Context): Notification {
|
|||
|
||||
return builder
|
||||
.setContentTitle(context.getString(R.string.app_name))
|
||||
.setContentText(context.getString(R.string.listening_notif_description))
|
||||
.setContentText(context.getString(R.string.foreground_notif_description))
|
||||
.setSmallIcon(R.drawable.ic_launcher_notification)
|
||||
.setTicker(context.getString(R.string.listening_notif_ticker))
|
||||
.setTicker(context.getString(R.string.foreground_notif_ticker))
|
||||
.setPriority(Notification.PRIORITY_LOW) // for under android 26 compatibility
|
||||
.setContentIntent(intent)
|
||||
.setOngoing(true)
|
||||
|
|
|
@ -22,6 +22,11 @@ class SSEListener (val context: Context) : EventSourceListener() {
|
|||
override fun onOpen(eventSource: EventSource, response: Response) {
|
||||
deleteWarningNotification(context)
|
||||
nFails = 0
|
||||
wakeLock?.let {
|
||||
while (it.isHeld) {
|
||||
it.release()
|
||||
}
|
||||
}
|
||||
try {
|
||||
Log.d(TAG, "onOpen: " + response.code)
|
||||
} catch (e: Exception) {
|
||||
|
@ -31,6 +36,7 @@ class SSEListener (val context: Context) : EventSourceListener() {
|
|||
|
||||
override fun onEvent(eventSource: EventSource, id: String?, type: String?, data: String) {
|
||||
Log.d(TAG, "New SSE message event=$type message=$data")
|
||||
wakeLock?.acquire(10000L /*10 secs*/)
|
||||
when (type) {
|
||||
"warning" -> Log.d(TAG, "Warning event received.")
|
||||
"ping" -> Log.d(TAG, "SSE ping received.")
|
||||
|
@ -53,18 +59,22 @@ class SSEListener (val context: Context) : EventSourceListener() {
|
|||
db.unregisterApp(connectorToken)
|
||||
}
|
||||
}
|
||||
wakeLock?.let {
|
||||
if (it.isHeld) {
|
||||
it.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClosed(eventSource: EventSource) {
|
||||
Log.d(TAG, "onClosed: $eventSource")
|
||||
isServiceStarted = false
|
||||
nFails += 1
|
||||
createWarningNotification(context)
|
||||
startListener(context)
|
||||
}
|
||||
|
||||
override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
|
||||
Log.d(TAG, "onFailure")
|
||||
isServiceStarted = false
|
||||
nFails += 1
|
||||
if (nFails > 1)
|
||||
createWarningNotification(context)
|
||||
|
|
|
@ -24,8 +24,10 @@ import org.unifiedpush.distributor.nextpush.api.apiSync
|
|||
import java.lang.Exception
|
||||
|
||||
private const val TAG = "StartService"
|
||||
const val WAKE_LOCK_TAG = "NextPush:StartService:lock"
|
||||
var isServiceStarted = false
|
||||
var nFails = 0
|
||||
var wakeLock: PowerManager.WakeLock? = null
|
||||
|
||||
fun startListener(context: Context){
|
||||
Log.d(TAG, "Starting the Listener")
|
||||
|
@ -39,7 +41,6 @@ fun startListener(context: Context){
|
|||
|
||||
class StartService: Service(){
|
||||
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private var isCallbackRegistered = false
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
|
@ -65,12 +66,26 @@ class StartService: Service(){
|
|||
|
||||
override fun onDestroy() {
|
||||
Log.d(TAG, "Destroyed")
|
||||
if (isServiceStarted) {
|
||||
startListener(this)
|
||||
} else {
|
||||
stopService()
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopService() {
|
||||
Log.d(TAG, "Stopping Service")
|
||||
apiDestroy()
|
||||
super.onDestroy()
|
||||
wakeLock?.let {
|
||||
while (it.isHeld) {
|
||||
it.release()
|
||||
}
|
||||
}
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
private fun startService() {
|
||||
if (isServiceStarted) return
|
||||
if (isServiceStarted && nFails == 0) return
|
||||
isServiceStarted = true
|
||||
|
||||
try {
|
||||
|
@ -83,8 +98,8 @@ class StartService: Service(){
|
|||
|
||||
// we need this lock so our service gets not affected by Doze Mode
|
||||
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
|
||||
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "EndlessService::lock").apply {
|
||||
acquire()
|
||||
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG).apply {
|
||||
acquire(10000L /*10 secs*/)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +113,7 @@ class StartService: Service(){
|
|||
connectivityManager.registerDefaultNetworkCallback(object : NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
Log.d(TAG, "Network is CONNECTED")
|
||||
startService()
|
||||
startListener(this@StartService)
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<string name="main_applications_title">Registered applications</string>
|
||||
|
||||
<string name="help"></string>
|
||||
<string name="listening_notif_description">Listening for incoming notifications</string>
|
||||
<string name="foreground_notif_description">Notification to run in the foreground</string>
|
||||
<string name="connection_button">Login</string>
|
||||
<string name="connection_description">You are not connected to Nextcloud yet</string>
|
||||
<string name="action_logout">Logout</string>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<string name="action_restart">Restart Service</string>
|
||||
<string name="warning_notif_description">NextPush is disconnected</string>
|
||||
<string name="warning_notif_ticker">Warning</string>
|
||||
<string name="listening_notif_ticker">Listening</string>
|
||||
<string name="foreground_notif_ticker">Foreground</string>
|
||||
<string name="message_missing_nextcloud_app">Nextcloud Files is not installed on your device.\nPlease install it</string>
|
||||
<string name="uri_market_nextcloud_app">market://details?id=com.nextcloud.client</string>
|
||||
<string name="market_chooser_title">Market</string>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
- Improve battery management
|
||||
- Change foreground notif wording
|
||||
- Follow spec 2.0.0
|
Loading…
Reference in New Issue