Expo.FileSystem.downloadAsync 不显示下载通知

2024-03-21

我正在使用世博会FileSystem下载 pdf 文件。 API 响应进入 success 函数。但是,我无法向用户显示下载的文件。

预期的行为应该就像我们通常在状态栏上看到通知图标一样,单击图标会打开您的文件。

FileSystem.downloadAsync(
  'https://bitcoin.org/bitcoin.pdf',
  FileSystem.documentDirectory + 'Stay_Overview.xlsx'
).then(({ uri }) => {
   console.log('Finished downloading to ', uri);
})
 .catch(error => {
    console.error(error);
 });

这个有一个或两个技巧,但这里有一个使用 Expo 的解决方案,适用于 iOS 和 Android。

在新建的Expo项目中,修改以下两个文件:

  • App.js
import React, { Component } from 'react';
import { View, ScrollView, StyleSheet, Button, Alert, Platform, Text, TouchableWithoutFeedback } from 'react-native';
import { FileSystem, Constants, Notifications, Permissions } from 'expo';
import Toast, {DURATION} from 'react-native-easy-toast';

async function getiOSNotificationPermission() {
  const { status } = await Permissions.getAsync(
    Permissions.NOTIFICATIONS
  );
  if (status !== 'granted') {
    await Permissions.askAsync(Permissions.NOTIFICATIONS);
  }
}

export default class App extends Component {
  constructor(props) {
    super(props);
    // this.toast = null;
    this.listenForNotifications = this.listenForNotifications.bind(this);
    // this.openFile = this.openFile.bind(this);
    this.state = {
      filePreviewText: ''
    }
  }

  _handleButtonPress = () => {
    let fileName = 'document.txt';
    let fileUri = FileSystem.documentDirectory + fileName;
    FileSystem.downloadAsync(
      "https://raw.githubusercontent.com/expo/expo/master/README.md",
      fileUri
    ).then(({ uri }) => {
      console.log('Finished downloading to ', uri);

      const localnotification = {
        title: 'Download has finished',
        body: fileName + " has been downloaded. Tap to open file.",
        android: {
          sound: true,
        },
        ios: {
          sound: true,
        },

        data: {
          fileUri: uri
        },
      };
      localnotification.data.title = localnotification.title;
      localnotification.data.body = localnotification.body;
      let sendAfterFiveSeconds = Date.now();
      sendAfterFiveSeconds += 3000;

      const schedulingOptions = { time: sendAfterFiveSeconds };
      Notifications.scheduleLocalNotificationAsync(
        localnotification,
        schedulingOptions
      );
    })
    .catch(error => {
        console.error(error);
        Alert.alert(error);
    });
  };
  listenForNotifications = () => {
    const _this = this;

    Notifications.addListener(notification => {
      if (notification.origin === 'received') {
        // We could also make our own design for the toast
        // _this.refs.toast.show(<View><Text>hello world!</Text></View>);

        const toastDOM = 
          <TouchableWithoutFeedback 
            onPress={() => {this.openFile(notification.data.fileUri)}}
            style={{padding: '10', backgroundColor: 'green'}}>
            <Text style={styles.toastText}>{notification.data.body}</Text>
          </TouchableWithoutFeedback>;

        _this.toast.show(toastDOM, DURATION.FOREVER);
      } else if (notification.origin === 'selected') {
        this.openFile(notification.data.fileUri);
      }
        // Expo.Notifications.setBadgeNumberAsync(number);
        // Notifications.setBadgeNumberAsync(10);
        // Notifications.presentLocalNotificationAsync(notification);
        // Alert.alert(notification.title, notification.body);
    });
  };
  componentWillMount() {
    getiOSNotificationPermission();
    this.listenForNotifications();
  }
  componentDidMount() {
    // let asset = Asset.fromModule(md);
    // Toast.show('Hello World');
  }
  openFile = (fileUri) => {
    this.toast.close(40);
    console.log('Opening file ' + fileUri);
    FileSystem.readAsStringAsync(fileUri)
    .then((fileContents) => {
      // Get file contents in binary and convert to text
      // let fileTextContent = parseInt(fileContents, 2);
      this.setState({filePreviewText: fileContents});
    });
  }
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.buttonsContainer}>
          <Button style={styles.button}
            title={"Download text file"}
            onPress={this._handleButtonPress}
          />
          <Button style={styles.button}
            title={"Clear File Preview"}
            onPress={() => {this.setState({filePreviewText: ""})}}
          />
        </View>
        <ScrollView style={styles.filePreview}>
          <Text>{this.state.filePreviewText}</Text>
        </ScrollView>
        <Toast ref={ (ref) => this.toast=ref }/>
      </View>
    );
            // <Toast
        //   ref={ (ref) => this.toast=ref }
        //   style={{backgroundColor:'green'}}
        //   textStyle={{color:'white'}}
        //   position={'bottom'}
        //   positionValue={100}
        //   opacity={0.8}
        // />
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  },
  buttonsContainer: {
    flexDirection: 'row',
  },
  button: {
    flex: 1
  },
  filePreview: {
    flex: 1,
    padding: 10,
  },
  toastText: {
    color: 'white',
    padding: 5,
    justifyContent: 'flex-start',
  },
});
  • package.json:添加以下依赖项(fork of反应本机轻松烤面包 https://github.com/crazycodeboy/react-native-easy-toast/)
"react-native-easy-toast": "git+https://github.com/SiavasFiroozbakht/react-native-easy-toast.git"

关于此解决方案有几个重要注意事项:

  • 使用Expo API最多,用于外部本地通知和文件写入/读取,这限制了当前的解决方案到无法 https://docs.expo.io/versions/v32.0.0/sdk/filesystem/写入除 Expo 自己的目录之外的其他位置。

  • 下载文件后,如果应用程序处于活动状态,则会向用户显示可自定义的 toast(Expo 目前不支持前台通知),或者发送本地推送通知以让用户知道下载已完成。单击这两个中的任何一个将在视图中显示文件的内容,使用<Text>成分。

  • The crazycodeboy/react-native-easy-toast由于 toast 的限制,当前忽略触摸事件,因此尚未直接使用 repo。分叉的存储库使此功能在原始存储库中实现合并请求之前可用。我建议在修补后切换回原来的版本,因为我可能不会维护我的版本。

  • 虽然这个项目也可用 https://snack.expo.io/@siavas/stackoverflow-47979921在 Snack 中,由于需要,它不会运行使用 git 存储库 https://expo.canny.io/feature-requests/p/load-snack-dependencies-from-github in package.json如上所述,以及变量范围的其他明显不一致。这可以通过合并请求或 Snack 中的新功能来解决。

  • 可能支持其他文件类型由世博会本身 https://docs.expo.io/versions/v32.0.0/sdk/filesystem/或通过外部包,例如这个 PDF 查看器 https://github.com/xcarpentier/rn-pdf-reader-js。但是,该代码必须进一步调整。

  • Toast(内部通知)是用TouchableWithoutFeedback https://facebook.github.io/react-native/docs/touchablewithoutfeedback组件,虽然有其他类似的 https://facebook.github.io/react-native/docs/handling-touches在 React Native 中存在各种差异。该组件可以在代码中自定义(搜索toastDOM), but 甚至可能是可更换的 https://expo.canny.io/feature-requests/p/implement-foreground-notifications-on-ios-using-new-native-willpresentnotificati未来可通过世博会的内部通知进行。

  • 最后,文件下载后,有意将通知延迟三秒——这使我们能够在应用程序处于后台时测试通知。请随意消除延迟并立即触发通知 https://docs.expo.io/versions/latest/sdk/notifications/#exponotificationspresentlocalnotificationasynclocalnotification.

就是这样!我认为这为使用 Expo 下载和预览文件提供了一个良好的起点。

代码库也可以在 GitHub 上找到 https://github.com/SiavasFiroozbakht/StackOverflow-47979921.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Expo.FileSystem.downloadAsync 不显示下载通知 的相关文章

随机推荐

  • 如何从根 Angular 对象获取 $rootElement

    我的目标是找到任意 Angular 项目中的根元素 如果我所拥有的只是angular目的 这显然不太合规 所以一个破解的解决方案就可以了 我的第一个方法是find ng app 但这在引导应用程序上失败 我一直在尝试各种角度模块 但陷入了僵
  • MongoDB 如何查找哪个多边形包含指定点?

    我将许多多边形插入MongoDB 2 4 8 并希望找到指定点所在的多边形 这似乎是一个常见问题 但在阅读了谷歌的所有文档后 我没有得到结果 所以提出这个问题 e g db addr poly insert loc type Polygon
  • 我们可以在 标签内添加

    当我在锚标记内编写 html 代码时 我的 Dreamweaver 编辑器在锚标记中显示错误 不应该使用内部标签吗 编写 使用标签有什么规则吗 我正在使用 Html 5 这是我的代码 http jsfiddle net CfPnj http
  • 如何根据Json反序列化JArray数据创建DataTable?

    我有以下 JArray 数据 我需要根据 Jarray 中的列名动态创建一个数据表 然后我需要插入数据 你能帮我做这个手术吗 pre PID 3 FirstName parveen LastName a Gender male PID 8
  • 尝试升级到 1.22 时 MediaWiki DB 连接错误

    我在共享主机服务器上安装了 MediaWiki 它的版本是 1 19 1 我正在尝试更新到 1 22 2 文档表明一步更新应该可以解决此问题 我已经在过去的更新中成功完成了几次此操作 并且正在遵循以前的注释 我建立了一个新目录 其中包含1
  • 将 .keystore 转换为 .jks 以签署 apk

    我有一个 Android 应用程序 我试图使用 quixxi com 来保护它 但它要求我再次签署该应用程序 但要做到这一点 它必须使用 jks 文件 但我的密钥库是 keystore 我在 C 中使用 Xamarin Android 和
  • 想要隐藏 Jackson 映射到 JSON 的对象的某些字段

    我有一个 User 类 我想使用 Jackson 将其映射到 JSON public class User private String name private int age private int securityCode gette
  • 如何阻止链接在 Gmail 的集成迷你浏览器中打开

    在 Android 上 当用户使用 Gmail 打开邮件并单击邮件中包含的链接时 该 URL 会在某种 迷你浏览器 中打开 顶部有一个特殊的栏 就我而言 URL 是可移植 Web 应用程序 PWA 应在 Chrome 浏览器本身中打开 使用
  • CardLayout 中的可滚动 JPanel?

    我一直在寻找一种方法来添加垂直滚动条JPanel依次添加到CardLayout控制板 我查找了这里所有与实现可滚动相关的帖子JPanel但我不知道如何用这个特定的方法来实现它CardLayout Oracle 也没有给出我可以使用的示例 也
  • sparql 主题的完整树

    例如 当我有一个人图时 例如约翰和约翰有工作地址 家庭地址 电话号码 关系等 是否有可能在不知道它是什么的情况下检索与 john 及其子类相关的所有内容 这样我就可以检索例如以下内容 John lt address lt house num
  • 为什么 ++x 是左值而 x++ 是右值? [复制]

    这个问题在这里已经有答案了 所以我一直在阅读左值和右值 我对两者之间的区别有点困惑 x and x 当谈到这个分类时 Why is x左值和x 右值 x返回对您增加的对象的引用 其中x 返回一个临时副本x的旧值 至少这将是按照惯例实现这些运
  • Android WebView Java-Javascript 桥接器

    我想知道是否可以从Java代码中获取Javascript变量值 换句话说 我在 WebView 中有 JS 代码 并且我需要能够从 WebView 的 JS 代码获取变量 是的 可以通过安装 Java JS 桥 然后将 JS 注入到收集数据
  • 非常纠结 cocoapods / ruby​​ 设置

    这工作正常 然后突然就不行了 我希望我知道为什么 真的卡住了 在网上找不到任何东西 我正在开发一个 ObjectiveC 项目 我尝试用以下方法重置一切 sudo gem uninstall ruby sudo gem uninstall
  • 实体框架花费大量时间初始化模型

    我面临 EF 花费大量时间 跨越数小时 来初始化模型的问题 该模型如下所示 大约有 20 个类从 A1 派生 大约 30 个类从 A2 派生 我必须从 TPT 战略转向 TPH 战略解决问题 https stackoverflow com
  • Swift 中的 NSExpression 计算器

    我正在尝试复制需要用Objective C写计算器 https stackoverflow com questions 15090475 need to write calculator in objective c在 Swift 中 但我
  • 使用 ArrayList 将文本文件拆分并存储到数组中

    我一直在开发一个测验应用程序 它使用文本文件来存储问题 问题的格式如下 QUESTION CHOICE A CHOICE B CHOICE C CHOICE D ANSWER 我希望它读取每一行并将其分成 6 个不同的部分 作为分割字符串并
  • 为什么这个 Flexbox 布局在 Safari 中会被破坏?

    所以我在 CSS 中设计了这个 想法是有一个标题 其余部分作为可滚动内容 有一个链接到现场演示在底部 Alas in Safari it is broken and looks like this 可以看到 表头的高度计算错误 导致绿框溢出
  • 与 React 一起使用时如何检测 keyPress 上的“Enter”键

    我正在使用 ReactJs 来开发我的应用程序 我试图通过处理 onKeyPress 事件在按下 Enter 时提交输入文本 它检测其他输入 但不输入 我尝试过不同的方法 event key event charCode event key
  • Cassandra RandomPartitioner 版本 1.2.3

    我使用 apt 在 debian 上安装 Cassandra 1 2 3 我之前使用的是 tarball 1 1 7 安装 安装后 我将 cassandra yaml 中的分区器从 Murmur3Partitioner 更改为 Random
  • Expo.FileSystem.downloadAsync 不显示下载通知

    我正在使用世博会FileSystem下载 pdf 文件 API 响应进入 success 函数 但是 我无法向用户显示下载的文件 预期的行为应该就像我们通常在状态栏上看到通知图标一样 单击图标会打开您的文件 FileSystem downl