Android Oreo tweaks (#217)
* display notifications on Android 8.0 Oreo and higher using required notification channels * fix daemon background service implementation for Android Oreo
This commit is contained in:
parent
338cd20132
commit
88fdc1b503
17 changed files with 1466 additions and 1376 deletions
42
Vagrantfile
vendored
42
Vagrantfile
vendored
|
@ -3,10 +3,10 @@ echoed=false
|
||||||
Vagrant.configure("2") do |config|
|
Vagrant.configure("2") do |config|
|
||||||
config.vm.box = "ubuntu/bionic64"
|
config.vm.box = "ubuntu/bionic64"
|
||||||
#config.disksize.size = "20GB"
|
#config.disksize.size = "20GB"
|
||||||
|
|
||||||
config.vm.provider "virtualbox" do |v|
|
config.vm.provider "virtualbox" do |v|
|
||||||
host = RbConfig::CONFIG['host_os']
|
host = RbConfig::CONFIG['host_os']
|
||||||
|
|
||||||
# Give VM 1/4 system memory & access to all cpu cores on the host
|
# Give VM 1/4 system memory & access to all cpu cores on the host
|
||||||
if host =~ /darwin/
|
if host =~ /darwin/
|
||||||
cpus = `sysctl -n hw.ncpu`.to_i
|
cpus = `sysctl -n hw.ncpu`.to_i
|
||||||
|
@ -20,25 +20,25 @@ Vagrant.configure("2") do |config|
|
||||||
cpus = `wmic cpu get NumberOfCores`.split("\n")[2].to_i
|
cpus = `wmic cpu get NumberOfCores`.split("\n")[2].to_i
|
||||||
mem = `wmic OS get TotalVisibleMemorySize`.split("\n")[2].to_i / 1024 /4
|
mem = `wmic OS get TotalVisibleMemorySize`.split("\n")[2].to_i / 1024 /4
|
||||||
end
|
end
|
||||||
|
|
||||||
mem = mem / 1024 / 4
|
mem = mem / 1024 / 4
|
||||||
mem = [mem, 2048].max # Minimum 2048
|
mem = [mem, 2048].max # Minimum 2048
|
||||||
|
|
||||||
if echoed === false
|
if echoed === false
|
||||||
echoed=true
|
echoed=true
|
||||||
puts("Memory", mem)
|
puts("Memory", mem)
|
||||||
puts("CPUs", cpus)
|
puts("CPUs", cpus)
|
||||||
end
|
end
|
||||||
|
|
||||||
#v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/home_vagrant_lbry-android", "1"]
|
#v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/home_vagrant_lbry-android", "1"]
|
||||||
#v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/vagrant", "1"]
|
#v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/vagrant", "1"]
|
||||||
v.customize ["modifyvm", :id, "--memory", mem]
|
v.customize ["modifyvm", :id, "--memory", mem]
|
||||||
v.customize ["modifyvm", :id, "--cpus", cpus]
|
v.customize ["modifyvm", :id, "--cpus", cpus]
|
||||||
end
|
end
|
||||||
|
|
||||||
config.vm.synced_folder "./", "/home/vagrant/lbry-android"
|
config.vm.synced_folder "./", "/home/vagrant/lbry-android"
|
||||||
|
|
||||||
|
|
||||||
config.vm.provision "shell", inline: <<-SHELL
|
config.vm.provision "shell", inline: <<-SHELL
|
||||||
dpkg --add-architecture i386
|
dpkg --add-architecture i386
|
||||||
apt-get update
|
apt-get update
|
||||||
|
@ -50,22 +50,22 @@ Vagrant.configure("2") do |config|
|
||||||
python2.7 setup.py install
|
python2.7 setup.py install
|
||||||
cd ../
|
cd ../
|
||||||
rm -rf ./buildozer
|
rm -rf ./buildozer
|
||||||
|
|
||||||
# Install additonal buildozer dependencies
|
# Install additonal buildozer dependencies
|
||||||
sudo apt-get install cython
|
sudo apt-get install cython
|
||||||
|
|
||||||
# Install node
|
# Install node
|
||||||
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
|
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
|
||||||
sudo apt-get install -y nodejs
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
export HOME=/home/vagrant
|
export HOME=/home/vagrant
|
||||||
|
|
||||||
cp $HOME/lbry-android/buildozer.spec.vagrant $HOME/lbry-android/buildozer.spec
|
cp $HOME/lbry-android/buildozer.spec.vagrant $HOME/lbry-android/buildozer.spec
|
||||||
|
|
||||||
mkdir -p cd $HOME/.buildozer/android/platform/
|
mkdir -p cd $HOME/.buildozer/android/platform/
|
||||||
wget -q 'https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip' -P $HOME/.buildozer/android/platform/
|
wget -q 'https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip' -P $HOME/.buildozer/android/platform/
|
||||||
wget -q 'https://dl.google.com/android/android-sdk_r23-linux.tgz' -P $HOME/.buildozer/android/platform/
|
wget -q 'https://dl.google.com/android/android-sdk_r23-linux.tgz' -P $HOME/.buildozer/android/platform/
|
||||||
wget -q 'https://dl.google.com/android/repository/android-23_r02.zip' -P $HOME/.buildozer/android/platform/
|
wget -q 'https://dl.google.com/android/repository/platform-26_r02.zip' -P $HOME/.buildozer/android/platform/
|
||||||
wget -q 'https://dl.google.com/android/repository/build-tools_r26.0.1-linux.zip' -P $HOME/.buildozer/android/platform/
|
wget -q 'https://dl.google.com/android/repository/build-tools_r26.0.1-linux.zip' -P $HOME/.buildozer/android/platform/
|
||||||
unzip -qq $HOME/.buildozer/android/platform/android-ndk-r13b-linux-x86_64.zip -d $HOME/.buildozer/android/platform/
|
unzip -qq $HOME/.buildozer/android/platform/android-ndk-r13b-linux-x86_64.zip -d $HOME/.buildozer/android/platform/
|
||||||
rm $HOME/.buildozer/android/platform/android-ndk-r13b-linux-x86_64.zip
|
rm $HOME/.buildozer/android/platform/android-ndk-r13b-linux-x86_64.zip
|
||||||
|
@ -73,25 +73,25 @@ Vagrant.configure("2") do |config|
|
||||||
rm $HOME/.buildozer/android/platform/android-sdk_r23-linux.tgz
|
rm $HOME/.buildozer/android/platform/android-sdk_r23-linux.tgz
|
||||||
mv $HOME/.buildozer/android/platform/android-sdk-linux $HOME/.buildozer/android/platform/android-sdk-23
|
mv $HOME/.buildozer/android/platform/android-sdk-linux $HOME/.buildozer/android/platform/android-sdk-23
|
||||||
unzip -qq $HOME/.buildozer/android/platform/android-23_r02.zip -d $HOME/.buildozer/android/platform/android-sdk-23/platforms
|
unzip -qq $HOME/.buildozer/android/platform/android-23_r02.zip -d $HOME/.buildozer/android/platform/android-sdk-23/platforms
|
||||||
rm $HOME/.buildozer/android/platform/android-23_r02.zip
|
rm $HOME/.buildozer/android/platform/platform-26_r02.zip
|
||||||
mv $HOME/.buildozer/android/platform/android-sdk-23/platforms/android-6.0 $HOME/.buildozer/android/platform/android-sdk-23/platforms/android-23
|
mv $HOME/.buildozer/android/platform/android-sdk-23/platforms/android-8.0.0 $HOME/.buildozer/android/platform/android-sdk-23/platforms/android-26
|
||||||
mkdir -p $HOME/.buildozer/android/platform/android-sdk-23/build-tools
|
mkdir -p $HOME/.buildozer/android/platform/android-sdk-23/build-tools
|
||||||
unzip -qq $HOME/.buildozer/android/platform/build-tools_r26.0.1-linux.zip -d $HOME/.buildozer/android/platform/android-sdk-23/build-tools
|
unzip -qq $HOME/.buildozer/android/platform/build-tools_r26.0.1-linux.zip -d $HOME/.buildozer/android/platform/android-sdk-23/build-tools
|
||||||
rm $HOME/.buildozer/android/platform/build-tools_r26.0.1-linux.zip
|
rm $HOME/.buildozer/android/platform/build-tools_r26.0.1-linux.zip
|
||||||
mv $HOME/.buildozer/android/platform/android-sdk-23/build-tools/android-8.0.0 $HOME/.buildozer/android/platform/android-sdk-23/build-tools/26.0.1
|
mv $HOME/.buildozer/android/platform/android-sdk-23/build-tools/android-8.0.0 $HOME/.buildozer/android/platform/android-sdk-23/build-tools/26.0.1
|
||||||
mkdir -p $HOME/.buildozer/android/platform/android-sdk-23/licenses
|
mkdir -p $HOME/.buildozer/android/platform/android-sdk-23/licenses
|
||||||
|
|
||||||
rm -rf $HOME/.buildozer/android/platform/android-sdk-23/tools
|
rm -rf $HOME/.buildozer/android/platform/android-sdk-23/tools
|
||||||
# https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
|
# https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
|
||||||
wget -q https://dl.google.com/android/repository/tools_r25.2.5-linux.zip
|
wget -q https://dl.google.com/android/repository/tools_r25.2.5-linux.zip
|
||||||
unzip -o -q ./tools_r25.2.5-linux.zip -d $HOME/.buildozer/android/platform/android-sdk-23/
|
unzip -o -q ./tools_r25.2.5-linux.zip -d $HOME/.buildozer/android/platform/android-sdk-23/
|
||||||
rm sdk-tools-linux-3859397.zip
|
rm sdk-tools-linux-3859397.zip
|
||||||
|
|
||||||
echo $'\nd56f5187479451eabf01fb78af6dfcb131a6481e' > $HOME/.buildozer/android/platform/android-sdk-23/licenses/android-sdk-license
|
echo $'\nd56f5187479451eabf01fb78af6dfcb131a6481e' > $HOME/.buildozer/android/platform/android-sdk-23/licenses/android-sdk-license
|
||||||
|
|
||||||
sudo chown -r vagrant $HOME
|
sudo chown -r vagrant $HOME
|
||||||
|
|
||||||
echo "Installing React Native via NPM..."
|
echo "Installing React Native via NPM..."
|
||||||
sudo npm install -g react-native-cli
|
sudo npm install -g react-native-cli
|
||||||
SHELL
|
SHELL
|
||||||
end
|
end
|
||||||
|
|
2620
app/package-lock.json
generated
2620
app/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SETTINGS } from 'lbry-redux';
|
import { SETTINGS } from 'lbry-redux';
|
||||||
import { Text, View, ScrollView, Switch } from 'react-native';
|
import { Text, View, ScrollView, Switch, NativeModules } from 'react-native';
|
||||||
import PageHeader from '../../component/pageHeader';
|
import PageHeader from '../../component/pageHeader';
|
||||||
import settingsStyle from '../../styles/settings';
|
import settingsStyle from '../../styles/settings';
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ class SettingsPage extends React.PureComponent {
|
||||||
static navigationOptions = {
|
static navigationOptions = {
|
||||||
title: 'Settings'
|
title: 'Settings'
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
backgroundPlayEnabled,
|
backgroundPlayEnabled,
|
||||||
|
@ -16,10 +16,7 @@ class SettingsPage extends React.PureComponent {
|
||||||
showNsfw,
|
showNsfw,
|
||||||
setClientSetting
|
setClientSetting
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// If no true / false value set, default to true
|
|
||||||
const actualKeepDaemonRunning = (keepDaemonRunning === undefined || keepDaemonRunning === null) ? true : keepDaemonRunning;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<PageHeader title={"Settings"}
|
<PageHeader title={"Settings"}
|
||||||
|
@ -34,7 +31,7 @@ class SettingsPage extends React.PureComponent {
|
||||||
<Switch value={backgroundPlayEnabled} onValueChange={(value) => setClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED, value)} />
|
<Switch value={backgroundPlayEnabled} onValueChange={(value) => setClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED, value)} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={settingsStyle.row}>
|
<View style={settingsStyle.row}>
|
||||||
<View style={settingsStyle.switchText}>
|
<View style={settingsStyle.switchText}>
|
||||||
<Text style={settingsStyle.label}>Show NSFW content</Text>
|
<Text style={settingsStyle.label}>Show NSFW content</Text>
|
||||||
|
@ -43,14 +40,19 @@ class SettingsPage extends React.PureComponent {
|
||||||
<Switch value={showNsfw} onValueChange={(value) => setClientSetting(SETTINGS.SHOW_NSFW, value)} />
|
<Switch value={showNsfw} onValueChange={(value) => setClientSetting(SETTINGS.SHOW_NSFW, value)} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={settingsStyle.row}>
|
<View style={settingsStyle.row}>
|
||||||
<View style={settingsStyle.switchText}>
|
<View style={settingsStyle.switchText}>
|
||||||
<Text style={settingsStyle.label}>Keep the daemon background service running when the app is suspended.</Text>
|
<Text style={settingsStyle.label}>Keep the daemon background service running when the app is suspended.</Text>
|
||||||
<Text style={settingsStyle.description}>Enable this option for quicker app launch and to keep the synchronisation with the blockchain up to date.</Text>
|
<Text style={settingsStyle.description}>Enable this option for quicker app launch and to keep the synchronisation with the blockchain up to date.</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={settingsStyle.switchContainer}>
|
<View style={settingsStyle.switchContainer}>
|
||||||
<Switch value={actualKeepDaemonRunning} onValueChange={(value) => setClientSetting(SETTINGS.KEEP_DAEMON_RUNNING, value)} />
|
<Switch value={keepDaemonRunning} onValueChange={(value) => {
|
||||||
|
setClientSetting(SETTINGS.KEEP_DAEMON_RUNNING, value);
|
||||||
|
if (NativeModules.DaemonServiceControl) {
|
||||||
|
NativeModules.DaemonServiceControl.setKeepDaemonRunning(value);
|
||||||
|
}
|
||||||
|
}} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -1,8 +1,22 @@
|
||||||
import { ACTIONS } from 'lbry-redux';
|
import { AsyncStorage } from 'react-native';
|
||||||
|
import { ACTIONS, SETTINGS } from 'lbry-redux';
|
||||||
|
|
||||||
|
getAsyncStorageItem = key => {
|
||||||
|
return AsyncStorage.getItem(key).then(value => {
|
||||||
|
if (['true', 'false'].indexOf(value) > -1) {
|
||||||
|
return value === 'true';
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
clientSettings: {}
|
clientSettings: {
|
||||||
|
backgroundPlayEnabled: getAsyncStorageItem(SETTINGS.BACKGROUND_PLAY_ENABLED),
|
||||||
|
keepDaemonRunning: getAsyncStorageItem(SETTINGS.KEEP_DAEMON_RUNNING),
|
||||||
|
showNsfw: getAsyncStorageItem(SETTINGS.SHOW_NSFW)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
||||||
|
@ -10,6 +24,7 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
||||||
const clientSettings = Object.assign({}, state.clientSettings);
|
const clientSettings = Object.assign({}, state.clientSettings);
|
||||||
|
|
||||||
clientSettings[key] = value;
|
clientSettings[key] = value;
|
||||||
|
AsyncStorage.setItem(key, String(value));
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
clientSettings,
|
clientSettings,
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.15#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
|
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git@v0.20.4#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
@ -148,7 +148,7 @@ android.react_src = ./app
|
||||||
|
|
||||||
# (list) Gradle dependencies to add (currently works only with sdl2_gradle
|
# (list) Gradle dependencies to add (currently works only with sdl2_gradle
|
||||||
# bootstrap)
|
# bootstrap)
|
||||||
android.gradle_dependencies = com.android.support:appcompat-v7:23.4.0, com.facebook.react:react-native:0.55.3, com.mixpanel.android:mixpanel-android:5+, com.google.android.gms:play-services-gcm:11.0.4+
|
android.gradle_dependencies = com.android.support:appcompat-v7:26.0.1, com.facebook.react:react-native:0.55.3, com.mixpanel.android:mixpanel-android:5+, com.google.android.gms:play-services-gcm:11.0.4+
|
||||||
|
|
||||||
# (str) python-for-android branch to use, defaults to master
|
# (str) python-for-android branch to use, defaults to master
|
||||||
#p4a.branch = stable
|
#p4a.branch = stable
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.15#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
|
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git@v0.20.4#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
@ -148,7 +148,7 @@ android.react_src = ./app
|
||||||
|
|
||||||
# (list) Gradle dependencies to add (currently works only with sdl2_gradle
|
# (list) Gradle dependencies to add (currently works only with sdl2_gradle
|
||||||
# bootstrap)
|
# bootstrap)
|
||||||
android.gradle_dependencies = com.android.support:appcompat-v7:23.4.0, com.facebook.react:react-native:0.55.3, com.mixpanel.android:mixpanel-android:5+, com.google.android.gms:play-services-gcm:11.0.4+
|
android.gradle_dependencies = com.android.support:appcompat-v7:26.0.1, com.facebook.react:react-native:0.55.3, com.mixpanel.android:mixpanel-android:5+, com.google.android.gms:play-services-gcm:11.0.4+
|
||||||
|
|
||||||
# (str) python-for-android branch to use, defaults to master
|
# (str) python-for-android branch to use, defaults to master
|
||||||
#p4a.branch = stable
|
#p4a.branch = stable
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = openssl, sqlite3, hostpython2, android, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.15#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
|
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git@v0.20.4#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
@ -86,10 +86,10 @@ fullscreen = 0
|
||||||
#android.presplash_color = #FFFFFF
|
#android.presplash_color = #FFFFFF
|
||||||
|
|
||||||
# (list) Permissions
|
# (list) Permissions
|
||||||
android.permissions = ACCESS_NETWORK_STATE,BLUETOOTH,INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE
|
android.permissions = ACCESS_NETWORK_STATE,BLUETOOTH,INTERNET,READ_EXTERNAL_STORAGE,READ_PHONE_STATE,WRITE_EXTERNAL_STORAGE
|
||||||
|
|
||||||
# (int) Android API to use
|
# (int) Android API to use
|
||||||
android.api = 23
|
android.api = 26
|
||||||
|
|
||||||
# (int) Minimum API required
|
# (int) Minimum API required
|
||||||
android.minapi = 21
|
android.minapi = 21
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.1'
|
classpath 'com.android.tools.build:gradle:2.3.1'
|
||||||
|
@ -11,6 +11,9 @@ buildscript {
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url 'https://maven.google.com'
|
||||||
|
}
|
||||||
maven {
|
maven {
|
||||||
// All of React Native (JS, Android binaries) is installed from npm
|
// All of React Native (JS, Android binaries) is installed from npm
|
||||||
url "$rootDir/react/node_modules/react-native/android"
|
url "$rootDir/react/node_modules/react-native/android"
|
||||||
|
@ -31,9 +34,9 @@ android {
|
||||||
targetSdkVersion {{ android_api }}
|
targetSdkVersion {{ android_api }}
|
||||||
versionCode {{ args.numeric_version }}
|
versionCode {{ args.numeric_version }}
|
||||||
versionName '{{ args.version }}'
|
versionName '{{ args.version }}'
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "x86"
|
abiFilters "armeabi-v7a", "x86"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ android {
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
jniLibs.srcDir 'libs'
|
jniLibs.srcDir 'libs'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,15 @@ package io.lbry.browser;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -29,16 +32,46 @@ import org.renpy.android.ResourceManager;
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
*/
|
*/
|
||||||
public class LbrynetService extends PythonService {
|
public class LbrynetService extends PythonService {
|
||||||
|
|
||||||
|
private static final String NOTIFICATION_CHANNEL_ID = "io.lbry.browser.DAEMON_NOTIFICATION_CHANNEL";
|
||||||
|
|
||||||
public static String TAG = "LbrynetService";
|
public static String TAG = "LbrynetService";
|
||||||
|
|
||||||
public static LbrynetService serviceInstance;
|
public static LbrynetService serviceInstance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canDisplayNotification() {
|
public boolean canDisplayNotification() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStartForeground(Bundle extras) {
|
||||||
|
String serviceTitle = extras.getString("serviceTitle");
|
||||||
|
String serviceDescription = "The LBRY Browser daemon service is running in the background.";
|
||||||
|
|
||||||
|
Context context = getApplicationContext();
|
||||||
|
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
NOTIFICATION_CHANNEL_ID, "LBRY Browser", NotificationManager.IMPORTANCE_LOW);
|
||||||
|
channel.setDescription("LBRY Broswer daemon service notification channel");
|
||||||
|
channel.setShowBadge(false);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
|
||||||
|
Intent contextIntent = new Intent(context, MainActivity.class);
|
||||||
|
PendingIntent pIntent = PendingIntent.getActivity(context, 0, contextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||||
|
Notification notification = builder.setContentTitle(serviceTitle)
|
||||||
|
.setContentText(serviceDescription)
|
||||||
|
.setContentIntent(pIntent)
|
||||||
|
.setWhen(System.currentTimeMillis())
|
||||||
|
.setSmallIcon(R.drawable.ic_lbry)
|
||||||
|
.setOngoing(true)
|
||||||
|
.build();
|
||||||
|
startForeground(1, notification);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int startType() {
|
public int startType() {
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
|
@ -66,7 +99,7 @@ public class LbrynetService extends PythonService {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
serviceInstance = null;
|
serviceInstance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAppRoot() {
|
public String getAppRoot() {
|
||||||
String app_root = getApplicationContext().getFilesDir().getAbsolutePath() + "/app";
|
String app_root = getApplicationContext().getFilesDir().getAbsolutePath() + "/app";
|
||||||
return app_root;
|
return app_root;
|
||||||
|
|
|
@ -51,6 +51,8 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
|
||||||
|
|
||||||
public static final String DEVICE_ID_KEY = "deviceId";
|
public static final String DEVICE_ID_KEY = "deviceId";
|
||||||
|
|
||||||
|
public static final String SETTING_KEEP_DAEMON_RUNNING = "keepDaemonRunning";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag which indicates whether or not the service is running. Will be updated in the
|
* Flag which indicates whether or not the service is running. Will be updated in the
|
||||||
* onResume method.
|
* onResume method.
|
||||||
|
@ -218,7 +220,7 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
// check service running setting and end it here
|
// check service running setting and end it here
|
||||||
SharedPreferences sp = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
SharedPreferences sp = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||||
boolean shouldKeepDaemonRunning = sp.getBoolean("keepDaemonRunning", true);
|
boolean shouldKeepDaemonRunning = sp.getBoolean(SETTING_KEEP_DAEMON_RUNNING, true);
|
||||||
if (!shouldKeepDaemonRunning) {
|
if (!shouldKeepDaemonRunning) {
|
||||||
serviceRunning = isServiceRunning(LbrynetService.class);
|
serviceRunning = isServiceRunning(LbrynetService.class);
|
||||||
if (serviceRunning) {
|
if (serviceRunning) {
|
||||||
|
|
|
@ -3,12 +3,14 @@ package io.lbry.browser.reactmodules;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
|
||||||
import io.lbry.browser.LbrynetService;
|
import io.lbry.browser.LbrynetService;
|
||||||
|
import io.lbry.browser.MainActivity;
|
||||||
import io.lbry.browser.ServiceHelper;
|
import io.lbry.browser.ServiceHelper;
|
||||||
|
|
||||||
public class DaemonServiceControlModule extends ReactContextBaseJavaModule {
|
public class DaemonServiceControlModule extends ReactContextBaseJavaModule {
|
||||||
|
@ -33,4 +35,14 @@ public class DaemonServiceControlModule extends ReactContextBaseJavaModule {
|
||||||
public void stopService() {
|
public void stopService() {
|
||||||
ServiceHelper.stop(context, LbrynetService.class);
|
ServiceHelper.stop(context, LbrynetService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void setKeepDaemonRunning(boolean value) {
|
||||||
|
if (context != null) {
|
||||||
|
SharedPreferences sp = context.getSharedPreferences(MainActivity.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = sp.edit();
|
||||||
|
editor.putBoolean(MainActivity.SETTING_KEEP_DAEMON_RUNNING, value);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package io.lbry.browser.reactmodules;
|
package io.lbry.browser.reactmodules;
|
||||||
|
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationManagerCompat;
|
import android.support.v4.app.NotificationManagerCompat;
|
||||||
|
|
||||||
|
@ -28,18 +31,22 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
private HashMap<String, Integer> downloadIdNotificationIdMap = new HashMap<String, Integer>();
|
private HashMap<String, Integer> downloadIdNotificationIdMap = new HashMap<String, Integer>();
|
||||||
|
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#");
|
||||||
|
|
||||||
private static final int MAX_PROGRESS = 100;
|
private static final int MAX_PROGRESS = 100;
|
||||||
|
|
||||||
private static final String GROUP_DOWNLOADS = "io.lbry.browser.GROUP_DOWNLOADS";
|
private static final String GROUP_DOWNLOADS = "io.lbry.browser.GROUP_DOWNLOADS";
|
||||||
|
|
||||||
|
private static final String NOTIFICATION_CHANNEL_ID = "io.lbry.browser.DOWNLOADS_NOTIFICATION_CHANNEL";
|
||||||
|
|
||||||
|
private static boolean channelCreated = false;
|
||||||
|
|
||||||
public static final String NOTIFICATION_ID_KEY = "io.lbry.browser.notificationId";
|
public static final String NOTIFICATION_ID_KEY = "io.lbry.browser.notificationId";
|
||||||
|
|
||||||
public static final int GROUP_ID = 0;
|
public static final int GROUP_ID = 0;
|
||||||
|
|
||||||
public static boolean groupCreated = false;
|
public static boolean groupCreated = false;
|
||||||
|
|
||||||
public DownloadManagerModule(ReactApplicationContext reactContext) {
|
public DownloadManagerModule(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
this.context = reactContext;
|
this.context = reactContext;
|
||||||
|
@ -53,15 +60,27 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "LbryDownloadManager";
|
return "LbryDownloadManager";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createNotificationChannel() {
|
||||||
|
// Only applies to Android 8.0 Oreo (API Level 26) or higher
|
||||||
|
if (!channelCreated && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
NOTIFICATION_CHANNEL_ID, "LBRY Downloads", NotificationManager.IMPORTANCE_LOW);
|
||||||
|
channel.setDescription("LBRY file downloads");
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createNotificationGroup() {
|
private void createNotificationGroup() {
|
||||||
if (!groupCreated) {
|
if (!groupCreated) {
|
||||||
Intent intent = new Intent(context, NotificationDeletedReceiver.class);
|
Intent intent = new Intent(context, NotificationDeletedReceiver.class);
|
||||||
intent.putExtra(NOTIFICATION_ID_KEY, GROUP_ID);
|
intent.putExtra(NOTIFICATION_ID_KEY, GROUP_ID);
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, GROUP_ID, intent, 0);
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, GROUP_ID, intent, 0);
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||||
builder.setContentTitle("Active downloads")
|
builder.setContentTitle("Active downloads")
|
||||||
.setContentText("Active downloads")
|
.setContentText("Active downloads")
|
||||||
.setSmallIcon(R.drawable.ic_file_download_black_24dp)
|
.setSmallIcon(R.drawable.ic_file_download_black_24dp)
|
||||||
|
@ -70,11 +89,11 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
.setGroupSummary(true)
|
.setGroupSummary(true)
|
||||||
.setDeleteIntent(pendingIntent);
|
.setDeleteIntent(pendingIntent);
|
||||||
notificationManager.notify(GROUP_ID, builder.build());
|
notificationManager.notify(GROUP_ID, builder.build());
|
||||||
|
|
||||||
groupCreated = true;
|
groupCreated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PendingIntent getLaunchPendingIntent(String uri) {
|
private PendingIntent getLaunchPendingIntent(String uri) {
|
||||||
Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||||
launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
|
@ -84,10 +103,11 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void startDownload(String id, String fileName) {
|
public void startDownload(String id, String fileName) {
|
||||||
|
createNotificationChannel();
|
||||||
createNotificationGroup();
|
createNotificationGroup();
|
||||||
|
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||||
// The file URI is used as the unique ID
|
// The file URI is used as the unique ID
|
||||||
builder.setContentIntent(getLaunchPendingIntent(id))
|
builder.setContentIntent(getLaunchPendingIntent(id))
|
||||||
.setContentTitle(String.format("Downloading %s...", fileName))
|
.setContentTitle(String.format("Downloading %s...", fileName))
|
||||||
|
@ -114,6 +134,7 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createNotificationChannel();
|
||||||
createNotificationGroup();
|
createNotificationGroup();
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
NotificationCompat.Builder builder = builders.get(notificationId);
|
NotificationCompat.Builder builder = builders.get(notificationId);
|
||||||
|
@ -128,12 +149,12 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
.setContentText(String.format("%s", formatBytes(totalBytes)))
|
.setContentText(String.format("%s", formatBytes(totalBytes)))
|
||||||
.setProgress(0, 0, false);
|
.setProgress(0, 0, false);
|
||||||
notificationManager.notify(notificationId, builder.build());
|
notificationManager.notify(notificationId, builder.build());
|
||||||
|
|
||||||
downloadIdNotificationIdMap.remove(id);
|
downloadIdNotificationIdMap.remove(id);
|
||||||
builders.remove(notificationId);
|
builders.remove(notificationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void stopDownload(String id, String filename) {
|
public void stopDownload(String id, String filename) {
|
||||||
if (!downloadIdNotificationIdMap.containsKey(id)) {
|
if (!downloadIdNotificationIdMap.containsKey(id)) {
|
||||||
|
@ -144,14 +165,14 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
if (!builders.containsKey(notificationId)) {
|
if (!builders.containsKey(notificationId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
NotificationCompat.Builder builder = builders.get(notificationId);
|
NotificationCompat.Builder builder = builders.get(notificationId);
|
||||||
notificationManager.cancel(notificationId);
|
notificationManager.cancel(notificationId);
|
||||||
|
|
||||||
downloadIdNotificationIdMap.remove(id);
|
downloadIdNotificationIdMap.remove(id);
|
||||||
builders.remove(notificationId);
|
builders.remove(notificationId);
|
||||||
|
|
||||||
if (builders.values().size() == 0) {
|
if (builders.values().size() == 0) {
|
||||||
notificationManager.cancel(GROUP_ID);
|
notificationManager.cancel(GROUP_ID);
|
||||||
groupCreated = false;
|
groupCreated = false;
|
||||||
|
|
BIN
src/main/res/drawable-hdpi/ic_lbry.png
Normal file
BIN
src/main/res/drawable-hdpi/ic_lbry.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
BIN
src/main/res/drawable-mdpi/ic_lbry.png
Normal file
BIN
src/main/res/drawable-mdpi/ic_lbry.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
BIN
src/main/res/drawable-xhdpi/ic_lbry.png
Normal file
BIN
src/main/res/drawable-xhdpi/ic_lbry.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
BIN
src/main/res/drawable-xxhdpi/ic_lbry.png
Normal file
BIN
src/main/res/drawable-xxhdpi/ic_lbry.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
BIN
src/main/res/drawable-xxxhdpi/ic_lbry.png
Normal file
BIN
src/main/res/drawable-xxxhdpi/ic_lbry.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
Loading…
Reference in a new issue