From 7eb7b714a1bc35ce5cc7e4d1a8fd87353054d2e3 Mon Sep 17 00:00:00 2001 From: Jean-Noel Date: Sun, 28 Jun 2020 18:32:03 +0900 Subject: [PATCH 1/9] I18N: French (global review/fix autotranslate) --- .../MultilingualResources/Covid19Radar.fr.xlf | 342 +++++++++--------- 1 file changed, 161 insertions(+), 181 deletions(-) diff --git a/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.fr.xlf b/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.fr.xlf index 99998659..3eea6ab5 100644 --- a/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.fr.xlf +++ b/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.fr.xlf @@ -17,14 +17,12 @@ COVID-19 Contact App - COVID-19Radar - Please verify the translation’s accuracy as the source string was updated after it was translated. + COVID-19 Contact App App Name License - Contrat de licence - Please verify the translation’s accuracy as the source string was updated after it was translated. + Contrat de licence ライセンス @@ -63,8 +61,7 @@ How to use - Manuel - Please verify the translation’s accuracy as the source string was updated after it was translated. + Guide d'utilisation Tab How to use @@ -99,472 +96,456 @@ App Settings - Paramètres - Please verify the translation’s accuracy as the source string was updated after it was translated. + Paramètres アプリの設定 Cancel - Annuler + Annuler Deleting - Suppression en cours + Suppression en cours Ask your family and friends to participate - Partager l'application - Please verify the translation’s accuracy as the source string was updated after it was translated. + Partager l'application 本アプリを広めましょう Share - Partager + Partager Sharing positive information and anonymous notification to others - Partager des informations positives et une notification anonyme à d’autres + S'enregistrer comme testé positif et notifier anonymement les autres Button NotifyOtherPage Stop - réinitialiser - Please verify the translation’s accuracy as the source string was updated after it was translated. + Réinitialiser 使用中止 Privacy Policy - politique de confidentialité + Politique de confidentialité Waiting for register - En attente de registre + En attente d'enregistrement Do you really want to reset all the data? - Voulez-vous vraiment réinitialiser toutes les données? + Voulez-vous vraiment réinitialiser toutes les données ? Delete all data - Supprimer toutes les données + Supprimer toutes les données All settings and data have been deleted. Please restart the application. - Tous les paramètres et données ont été supprimés. S’il vous plaît redémarrer l’application. + Tous les paramètres et données ont été supprimés. Veuillez redémarrer l’application. Return to registration - Retour à l’inscription + Retour à l’inscription Positive registration - Enregistrement positif + Enregistrement positif Would you like to register positively later? - Souhaitez-vous vous inscrire positivement plus tard? + Souhaitez-vous vous inscrire comme testé positif plus tard ? Help protect your family and friends by anonymously registering test results. - Si vous êtes positif avec la nouvelle Corona, s’il vous plaît coopérer avec l’enregistrement positif pour protéger les gens autour de vous. - Please verify the translation’s accuracy as the source string was updated after it was translated. + Afin de protéger les gens autour de vous, merci de bien vouloir coopérer en vous enregistrant anonymement si vous êtes testé positif au COVID-19. 周りの人達を守るために匿名での陽性登録へのご協力をお願いいたします。 One more person using this app is one more step towards containing the spread of COVID-19. - Cette application est si efficace que beaucoup de gens l’installent, donc s’il vous plaît partager l’application avec les gens autour de vous. - Please verify the translation’s accuracy as the source string was updated after it was translated. + L'efficacité de cette application s'accroît avec le nombre d'utilisateurs actifs. Merci de bien vouloir partager l’application avec les gens autour de vous. 本アプリは多くの方にお使いいただくほど効果を発揮します。 How to use this app - Comment utiliser - Please verify the translation’s accuracy as the source string was updated after it was translated. + Manuel d'utilisation 使い方 What is a 'close contact'? - Identification terminale - Please verify the translation’s accuracy as the source string was updated after it was translated. + Qu'est-ce qu'un «contact rapproché» ? 接触の記録方法 Checking close contacts - Méthode de confirmation de contact - Please verify the translation’s accuracy as the source string was updated after it was translated. + Confirmation des contacts rapprochés 接触の確認方法 When tested positive - S’il est déterminé à être infecté - Please verify the translation’s accuracy as the source string was updated after it was translated. + Si vous êtes testé positif 感染していると判定されたら Stop / delete close contact history - Enregistrement stop/supprimer - Please verify the translation’s accuracy as the source string was updated after it was translated. + Arrêter / supprimer l'enregistrement des contacts 記録の停止/削除 When you run this app, each smartphone will generate a random code. No personal information and no location information including GPS data is collected. - Lorsque vous exécutez cette application, chaque smartphone génère et dispose d’un code de contact. De plus, cette application n’acquiert aucune information relative à des renseignements personnels tels que le numéro de téléphone et les informations de localisation. - Please verify the translation’s accuracy as the source string was updated after it was translated. + Lorsque cette application est exécutée, chaque smartphone génère aléatoirement un code de contact. Cette application n’acquiert aucune information relative à des renseignements personnels tels que le numéro de téléphone et les informations de localisation. アプリを実行した際に、各スマートフォンで接触符号を生成して持ちます。氏名・電話番号などの個人情報やGPSなどスマートフォンの位置情報を使うことはなく、記録されることもありません。 What is a close contact - Conditions de contact enregistrées - Please verify the translation’s accuracy as the source string was updated after it was translated. + Qu'est-ce qu'un contact rapproché 記録される接触の条件 If smartphones running this app are in close contact (within 1 meter for 15 minutes or more), this is recorded as a close contact. - Le contact avec d’autres utilisateurs d’applications dans un rayon de 1 mètre pendant 15 minutes ou plus est enregistré comme «contact». - Please verify the translation’s accuracy as the source string was updated after it was translated. + Deux utilisateurs de cette application se trouvant dans un rayon de 1 mètre pendant 15 minutes ou plus est enregistré comme «contact rapproché». 1メートル以内、15分以上の他のアプリユーザーとの接触は「接触」として記録されます。 Recording close contact - Enregistrement des coordonnées - Please verify the translation’s accuracy as the source string was updated after it was translated. + Enregistrement des contacts rapprochés 接触情報の記録 Phones in close contact exchange their random codes. This information will not be used until either user registers positive test results with this app. The close contact history will be erased after 14 days. Note: The code changes regularly to protect your privacy. - À ce moment-là, le code de contact de la personne contactée est enregistré dans l’application. Les coordonnées ne seront pas utilisées tant que l’un ou l’autre utilisateur n’aura pas enregistré de positif. L’historique des contacts sera effacé après 14 jours. Le code de contact change régulièrement. - Please verify the translation’s accuracy as the source string was updated after it was translated. + Les téléphones en contact rapproché échangent leurs codes aléatoire. Ces informations ne seront pas utilisées tant qu'aucun des utilisateurs ne s'enregistre comme testé positif. L’historique des contacts sera effacé après 14 jours. N.B.: Le code change régulièrement pour protéger votre confidentialité. このとき、接触した相手の接触符号の記録をアプリに行います。どちらかの利用者が陽性の登録を行うまでは接触の情報は利用されません。接触の履歴は14日後に消去されます。 ※接触符号は定期的に変わります。 Go to app settings - Accéder aux paramètres de l’application + Accéder aux paramètres de l’application アプリの設定へ From app settings, you can stop using the app and delete user data. - À partir des paramètres de l’application, vous pouvez activer/désactiver bluetooth et notifications, cesser d’utiliser l’application et supprimer l’historique des contacts rapprochés. - Please verify the translation’s accuracy as the source string was updated after it was translated. + À partir des paramètres de l’application, vous pouvez réinitialiser l’application et supprimer les données utilisateur. アプリの設定からアプリの使用中止とユーザー情報の削除を行うことができます。 The app will notify you, if you were in close contact with COVID-19 positive user. - L’application vous informera, si vous étiez en contact étroit avec l’utilisateur positif COVID-19. + L’application vous enverra une notification si vous avez été en contact rapproché avec un utilisateur enregistré positif COVID-19. 接触した人の中に新型コロナウイルスの陽性登録された人がいた場合、スマートフォンにプッシュ通知が届きます。 You can check the number of your close contacts from the home screen. - Vous pouvez vérifier le nombre de vos contacts proches à partir de l’écran d’accueil. + Vous pouvez vérifier le nombre de vos contacts rapprochés à partir de l’écran d’accueil. 最近の接触件数の確認へはホーム画面からも移動することができます。 You can check the list of close contact dates and receive guidance on what to do if you have symptoms of the disease. - Vous pouvez consulter la liste des dates de contact rapprochées et recevoir des conseils sur ce qu’il faut faire si vous avez des symptômes de la maladie. + Vous pouvez consulter la liste des dates de contact rapprochés et recevoir des conseils sur ce qu’il faut faire si vous avez des symptômes de la maladie. 接触があった日付の一覧を確認できます。また適切な連絡先をお知らせします。 Notification - Avertissement + Notification 通知 Home - Accueil + Accueil ホーム画面 If you had close contact with a COVID-19 positive user - Si vous avez eu un contact étroit avec un utilisateur positif COVID-19 + Si vous avez eu un contact rapproché avec un utilisateur positif au COVID-19 陽性者との接触があった場合 If you tested positive - Si vous avez été contrôlé positif + Si vous avez été contrôlé positif 検査により新型コロナウイルスの感染が確認された場合。 Public health authorities will issue you a "processing number". - Les autorités de santé publique vous délivreront un « numéro de traitement ». + Les autorités de santé publique vous délivreront un « numéro de traitement ». 保健所等公的機関から登録用の「処理番号」が発行されます。 Register by entering provided processing number into this app - Inscrivez-vous en entrant le numéro de traitement fourni dans cette application + Inscrivez-vous en entrant le numéro de traitement fourni dans cette application 本アプリを用いて処理番号の登録を行います。 Smartphones that were in close contact with your smartphone within the last 14 days will receive notifications. - Les smartphones qui étaient en contact étroit avec votre smartphone au cours des 14 derniers jours recevront des notifications. + Les smartphones qui ont été en contact rapproché avec votre smartphone au cours des 14 derniers jours recevront des notifications. あなたと14日以内に接触した人のスマホアプリに通知が届きます。(1m以内、15分以上) Only randomly generated codes from device are used when sending notifications. No personal information is used. - Seuls les codes générés au hasard à partir du périphérique sont utilisés lors de l’envoi de notifications. Aucune information personnelle n’est utilisée. + Seuls les codes de contact générés aléatoirement à partir du téléphone sont utilisés lors de l’envoi de notifications. Aucune information personnelle n’est utilisée. 通知される情報は端末の接触符号のみです。それ以外の、氏名など個人情報や位置情報が送られることはありません。 Register here when tested positive - Inscrivez-vous ici lorsqu’il est testé positif + Enregistrez-vous ici lorsque testé positif 陽性情報の登録と他者への匿名通知へ License - Licence + Licence ライセンス… Close contact recording - Enregistrement de contact étroit + Enregistrement de contact rapproché 接触の検出 Use of Bluetooth - Utilisation du Bluetooth + Utilisation du Bluetooth Bluetoothによる接触の検知 Notifications - Notifications + Notifications 通知 Close contact notifications - Notifications de contact rapproché + Notifications de contact rapproché 陽性者との接触通知 Stop using the app - Arrêter d’utiliser l’application + Arrêter d’utiliser l’application アプリの使用中止 Stop using and delete close contact records - Arrêter d’utiliser et supprimer les enregistrements de contact rapproché + Arrêter d’utiliser et supprimer l'historique des contacts rapprochés 使用を中止して過去14日間の接触履歴を消去 What is a 'close contact'? - Qu’est-ce qu’un « nt contact étroit »? + Qu’est-ce qu’un « contact rapproché » ? どのようにして接触を記録していますか? How do I check number of close contacts? - Comment vérifier le nombre de contacts proches ? + Comment vérifier le nombre de contacts rapprochés ? 接触の有無はどのように知ることができますか? If you test positive for COVID-19 - Si vous êtes positif pour COVIDE-19 + Si vous êtes testé positif au COVID-19 新型コロナウイルスに感染していると判定されたら How do I stop / delete close contact recording? - Comment puis-je arrêter /supprimer l’enregistrement de contact étroit ? + Comment puis-je arrêter/supprimer l’enregistrement des contacts rapprochés ? 接触の記録を停止/情報を削除するには Close contacts for the past 14 days - Contacts étroits depuis 14 jours + Contacts rapprochés depuis 14 jours 過去14日間の接触 No close contacts with COVID-19 positive users - Pas de contacts étroits avec les utilisateurs positifs de COVIDE-19 + Pas de contacts rapprochés avec des utilisateurs positifs au COVID-19 陽性者との接触は確認されませんでした Please keep practicing 'New Lifestyle' recommended by the government. - S’il vous plaît continuer à pratiquer « Nouveau mode de vie » recommandé par le gouvernement. + S’il vous plaît continuez à pratiquer les mesures « Nouveau mode de vie » recommandées par le gouvernement. 引き続き「新しい生活様式」の実践をよろしくお願いいたします。 Share this app - Partager cette application + Partager cette application アプリを周りの人に知らせる Thank you for registering your test results! - Merci d’avoir enregistré vos résultats de test! + Merci d’avoir enregistré vos résultats de test ! 陽性のご登録をいただきありがとうございました Registration is anonymous. You do not have to enter your name or any other personal information. No information regarding location of close contact is recorded. - L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact étroit n’est enregistrée. + L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact rapproché n’est enregistrée. 登録は匿名で行われ、氏名や連絡先など個人が特定される情報を登録する必要はありません。また、接触した場所の位置情報が記録や通知されることもありません。 Terms of use - Conditions d’utilisation + Conditions d’utilisation 利用規約 I accept the Terms of Use - J’accepte les conditions d’utilisation + J’accepte les conditions d’utilisation 規約に同意して次へ Setup complete. Thank you! - Configuration terminée. Merci! + Configuration terminée. Merci ! ご登録いただきありがとうございました Home - Accueil + Accueil ホーム画面へ How to use this app - Comment utiliser cette application + Comment utiliser cette application 使い方を学ぶ Device identification - Identification de périphérique + Identification du périphérique 端末の識別 A list of close contacts with COVID-19 positive users - Une liste de contacts étroits avec les utilisateurs positifs de COVID-19 + Une liste de contacts rapprochés avec des utilisateurs positifs au COVID-19 陽性者との接触一覧 Fill in your symptoms - Remplissez vos symptômes + Saisissez vos symptômes 症状を入力 Tell your symptoms by phone Consultation Center - Informez vos symptômes par téléphone Centre de consultation + Indiquez vos symptômes par téléphone au Centre de consultation 帰国者・接触者外来に電話 times - fois + fois If you have possible COVID-19 symptoms, contact healthcare organizations using the form below or by phone. Depending on the symptoms, you will be advised to take a COVID-19 test. - Si vous avez des symptômes COVIDÉS-19 possibles, communiquez avec les organismes de soins de santé en utilisant le formulaire ci-dessous ou par téléphone. Selon les symptômes, il vous sera conseillé de passer un test COVIDE-19. + Si vous avez des symptômes COVID-19, communiquez avec les organismes de santé en utilisant le formulaire ci-dessous ou par téléphone. Selon les symptômes, il vous sera conseillé de passer un test COVID-19. 現在の症状などを、入力フォームまたはお電話にて、ご連絡ください。内容に応じて、帰国者・接触者外来等への受診を案内します。 Please take a screenshot of this screen. You may be asked to provide it during diagnosis. - S’il vous plaît prendre une capture d’écran de cet écran. On peut vous demander de le fournir pendant le diagnostic. + Veuillez prendre une capture de cet écran. On peut vous demander de le fournir pendant le diagnostic. 受診の際などに必要となる場合があるため、本画面のスクリーンショットの保存をお願いいたします。 Number of confirmed close contacts with COVID-19 positive users - Nombre de contacts étroits confirmés avec les utilisateurs positifs de COVIDE-19 + Nombre de contacts rapprochés confirmés avec des utilisateurs positifs de COVID-19 陽性者との接触確認 Close contacts for the past 14 days - Contacts étroits depuis 14 jours + Contacts rapprochés depuis 14 jours 過去14日間の接触 9:00-17:30 (except weekends and holidays) - 9:00-17:30 (sauf les week-ends et les jours fériés) + 9:00-17:30 (sauf les week-ends et les jours fériés) 9:00~17:30(土・日・祝日・年末年始を除く) COVID-19 Information and Resources - COVIDE-19 Information et ressources + COVID-19 Information et ressources 新型コロナウイルス感染症対策サイト Support - Assistance + Assistance アプリに関するお問い合わせ in use - utilisé + en service 使用中 Check close contacts - Vérifier les contacts proches + Vérifier les contacts rapprochés 陽性者との接触を確認する(14日間) When tested positive for COVID-19 - Lorsqu’il est testé positif pour COVIDE-19 + Si vous êtes testé positif au COVID-19 新型コロナウイルス陽性と診断されたら Register positive test result - Enregistrer le résultat du test positif + Enregistrer le résultat du test positif 陽性情報の登録 Share this app - Partager cette application + Partager cette application アプリを周りの人に知らせる Home - Accueil + Accueil ホーム Term of use - Conditions d'utilisation + Conditions d'utilisation 利用規約 Your privacy is protected - Votre vie privée est protégée + Votre vie privée est protégée プライバシーについて No personal information such as your name or phone number is collected. No geolocation data including GPS data is collected. - Aucune information personnelle comme votre nom ou votre numéro de téléphone n’est recueillie. Aucune donnée de géolocalisation, y compris les données GPS, n’est recueillie. + Aucune information personnelle comme votre nom ou votre numéro de téléphone n’est recueillie. Aucune donnée de géolocalisation, y compris les données GPS, n’est recueillie. 氏名・電話番号などの個人情報や、GPSなどスマートフォンの位置情報を使うことはなく、記録されることもありません。 All data is encrypted and saved locally on your smartphone. All data is automatically deleted after 14 days. Your movements are not tracked in any way by government agencies or third parties. - Toutes les données sont cryptées et enregistrées localement sur votre smartphone. Toutes les données sont automatiquement supprimées après 14 jours. Vos mouvements ne sont suivis d’aucune façon par des organismes gouvernementaux ou des tiers. + Toutes les données sont cryptées et enregistrées localement sur votre smartphone. Toutes les données sont automatiquement supprimées après 14 jours. Vos mouvements ne sont suivis d’aucune façon par des organismes gouvernementaux ou des tiers. 接触の記録は、暗号化され、あなたのスマートフォンの中にのみ記録され、14日後に自動的に削除されます。行政機関や第三者が暗号化された情報を利用して接触歴を把握することはありません。 You can stop recording close contacts with other users anytime by changing app settings or deleting the app. - Vous pouvez arrêter d’enregistrer des contacts étroits avec d’autres utilisateurs à tout moment en modifiant les paramètres de l’application ou en supprimant l’application. + Vous pouvez arrêter d’enregistrer des contacts rapprochés avec d’autres utilisateurs à tout moment en modifiant les paramètres de l’application ou en supprimant l’application. 接触の記録はいつでも止めることができます。アプリ内の設定を無効にするか、アプリを削除してください。 Terms of use - Conditions d’utilisation + Conditions d’utilisation 利用規約へ TutorialPage2Description1 - TutorialPage2Description1 + À propos de la confidentialité プライバシーについて Turn on notifications - Activer les notifications + Activer les notifications 通知をご利用いただくために Please turn on notifications to be notified when you had close contacts with COVID-19 positive users. - Veuillez activer les notifications à avis lorsque vous avez eu des contacts étroits avec les utilisateurs positifs de COVID-19. + Veuillez activer les notifications pour être averti lorsque vous avez eu des contacts rapprochés avec les utilisateurs positifs au COVID-19. 本アプリで接触の通知をご利用いただくために、本アプリのプッシュ通知を有効にしてください。 Turn on - Activer + Activer 有効にする Set up later - Configurer plus tard + Configurer plus tard あとで設定する To use notifications - Pour utiliser les notifications + Pour utiliser les notifications 通知をご利用いただくために @@ -574,322 +555,321 @@ Register - Inscrire + S'enregistrer 登録する Please enter a process code issued to you by "Health Center Real-time Information-sharing System on COVID-19 (HER-SYS)". - Veuillez entrer un code de processus qui vous est délivré par le « Health Center Real-time Information-sharing System on COVID-19 (HER-SYS ». + Veuillez entrer le code de processus qui vous est délivré par le « Health Center Real-time Information-sharing System on COVID-19 (HER-SYS) ». 新型コロナウイルス感染症者等情報把握・管理支援システム(HER-SYS)から発行された処理番号を入力してください。 Users who were in close contact with you within the past 14 days will be notified. Registration is anonymous. You do not have to enter your name or any other personal information. No information regarding location of close contact is recorded. - Les utilisateurs qui ont été en contact étroit avec vous au cours des 14 derniers jours seront avisés. L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact étroit n’est enregistrée. + Les utilisateurs qui ont été en contact rapproché avec vous au cours des 14 derniers jours seront avisés. L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact rapproché n’est enregistrée. 過去14日間に本アプリであなたと接触した履歴のある人に通知が行きます。登録は匿名で行われ、氏名や連絡先など個人が特定される情報を登録する必要はありません。また、接触した場所の位置情報が記録や通知されることもありません。 How to receive a process code - Comment recevoir un code de processus + Comment recevoir un code de processus 処理番号の取得方法 Register positive test result - Enregistrer le résultat du test positif + Enregistrer le résultat du test positif 陽性情報の登録 Next - Suivante + Suivant 次へ The app recognizes close contacts between smartphones running this app. - L’application reconnaît les contacts étroits entre les smartphones exécutant cette application. + L’application reconnaît les contacts rapprochés entre les smartphones exécutant cette application. 本アプリをスマートフォンに設定した人どうしの接触を記録します。 When tested positive for COVID-19, you can anonymously register the test result in this app. - Lorsque vous avez été testé positif pour COVID-19, vous pouvez enregistrer anonymement le résultat du test dans cette application. + Lorsque vous avez été testé positif au COVID-19, vous pouvez enregistrer anonymement le résultat du test dans cette application. 新型コロナウイルスに陽性と判定されたら本アプリに匿名で登録することができます。 If you have been in close contact with a user who tested positive, the app notifies you of potential infection and provides guidance to protect your health. - Si vous avez été en contact étroit avec un utilisateur qui a été testé positif, l’application vous informe d’une infection potentielle et vous fournit des conseils pour protéger votre santé. + Si vous avez été en contact rapproché avec un utilisateur qui a été testé positif, l’application vous informe d’une infection potentielle et vous fournit des conseils pour protéger votre santé. 最近接触した人の中に陽性登録した人がいたら、通知と適切な行動をお知らせします。 Protect yourself with the app - Protégez-vous avec l’application + Protégez-vous avec l’application このアプリでできること Protect yourself with the app - Protégez-vous avec l’application + Protégez-vous avec l’application このアプリでできること Turn on - Activer + Activer 有効にする Set up later - Configurer plus tard + Configurer plus tard あとで設定する Please turn on Exposure Notifications function and Bluetooth to start recording close contacts with other users. - Veuillez activer Bluetooth pour commencer à enregistrer des contacts étroits avec d’autres utilisateurs. + Veuillez activer le Bluetooth pour commencer à enregistrer des contacts rapprochés avec d’autres utilisateurs. 本アプリで接触検知をご利用いただくために、スマートフォンのBluetooth通信を有効にしてください。 Find out more - En savoir plus + En savoir plus 技術的な詳細について To use Exposure Notifications - Activer Bluetooth + Pour recevoir des Notifications d'exposition 接触検知をご利用いただくために To use Exposure Notifications - Activer Bluetooth + Pour recevoir des Notifications d'exposition 接触検知をご利用いただくために ~ - ~ + ~ から Enter an 8-digit code - Entrez un code à 8 chiffres + Entrez un code à 8 chiffres 8桁の処理番号を入力してください The processing number will be notified to your mobile phone number or e-mail address registered in the new coronavirus infectious disease information and management system (hereinafter "management system"). - Le numéro de traitement sera notifié à votre numéro de téléphone mobile ou à votre adresse e-mail enregistrée dans le nouveau système d’information et de gestion des maladies infectieuses du coronavirus (ci-après « système de gestion »). + Le numéro de traitement sera notifié à votre numéro de téléphone mobile ou à votre adresse e-mail enregistrée dans le nouveau système d’information et de gestion des maladies infectieuses du coronavirus (ci-après « système de gestion »). 新型コロナウイルス感染症等情報把握・管理システム(以下「管理システム」)に登録されたあなたの携帯電話番号又はメールアドレスに、処理番号が通知されます。 When you enter this processing number into the terminal, the terminal will make an inquiry via the notification server to the management system as to whether the processing number has been issued to you. - Lorsque vous entrez ce numéro de traitement dans le terminal, le terminal effectue une demande via le serveur de notification au système de gestion pour savoir si le numéro de traitement vous a été délivré. + Lorsque vous entrez ce numéro de traitement dans le terminal, le terminal effectue une demande via le serveur de notification au système de gestion pour savoir si le numéro de traitement vous a été délivré. あなたがこの処理番号を端末に入力することにより、端末から通知サーバーを経由して管理システムに対し、処理番号があなたに対して発行されたものか否かの照会が行われます。 The management system will respond to the notification server as to whether the transaction number referred to was issued to you. - Le système de gestion répondra au serveur de notification pour savoir si le numéro de transaction mentionné vous a été délivré. + Le système de gestion répondra au serveur de notification pour savoir si le numéro de transaction mentionné vous a été délivré. 管理システムは、通知サーバーに対し、照会された処理番号があなたに対して発行されたものか否かについて回答します。 If you reply that the transaction number was issued to you, other users' terminals will be provided with the daily key recorded on your terminal. - Si vous répondez que le numéro de transaction vous a été émis, les terminaux d’autres utilisateurs recevront la clé quotidienne enregistrée sur votre terminal. + Si vous répondez que le numéro de transaction vous a été émis, les terminaux d’autres utilisateurs recevront la clé quotidienne enregistrée sur votre terminal. 処理番号があなたに対して発行されたものである旨の回答が行われた場合は、他の利用者の端末に、あなたの端末に記録された日次鍵が提供されます。 If you have been in contact with you within 14 days, you will know that you may have been contacted without any information that can identify you personally. - Si vous avez été en contact avec vous dans les 14 jours, vous saurez que vous avez peut-être été contacté sans aucune information qui peut vous identifier personnellement. + Si vous avez été en contact rapproché avec un autre utilisateur ces derniers 14 jours, vous saurez que vous avez peut-être été contacté sans utiliser des informations qui peuvent vous identifier personnellement. 14日以内にあなたと接触の状態となったことのある方は、あなた個人を識別可能な情報がない状態で、接触した可能性がある旨を知ることができます。 Agree and register - Accepter et s’inscrire + Accepter et enregistrer le résultat 同意して陽性登録する Consent to positive registration - Consentement à l’enregistrement positif + Consentement à l’enregistrement du résultat 陽性登録への同意 Consent to positive registration - Consentement à l’enregistrement positif + Consentement à l’enregistrement du résultat 陽性登録への同意 Version - Version + Version バージョン Bluetooth is turned off.Please turn in Bluetooth. - Bluetooth est désactivé. S’il vous plaît tourner Bluetooth. + Le Bluetooth est désactivé. S’il vous plaît activez le Bluetooth. BluetoothがOffになっています。Bluetoothを有効にしてください。 A list of close contacts (past 14 days) - Une liste de contacts proches (au cours des 14 derniers jours) + Une liste de contacts rapprochés (au cours des 14 derniers jours) 過去14日間の接触一覧 Dates when you were in close contact with COVID-19 positive users. - Dates lorsque vous étiez en contact étroit avec les utilisateurs positifs COVID-19. + Dates lorsque vous avez été en contact rapproché avec des utilisateurs positifs au COVID-19. 以下の日に陽性者との接触が確認されました。 https://www.mhlw.go.jp/stf/seisakunitsuite/english_rk_00031.html - https://www.mhlw.go.jp/stf/seisakunitsuite/english_rk_00031.html + https://www.mhlw.go.jp/stf/seisakunitsuite/english_rk_00031.html Term of Use https://covid19radarjpnprod.z11.web.core.windows.net/en/index.html - https://covid19radarjpnprod.z11.web.core.windows.net/en/index.html + https://covid19radarjpnprod.z11.web.core.windows.net/en/index.html https://covid19radarjpnprod.z11.web.core.windows.net/en/chatbot4.html - https://covid19radarjpnprod.z11.web.core.windows.net/en/chatbot4.html + https://covid19radarjpnprod.z11.web.core.windows.net/en/chatbot4.html It is possible you have been in close proximity to a user who tested positive for COVID-19. Tap for more details. - Il est possible que vous ayez été à proximité d’un utilisateur qui a été testé positif pour COVID-19. Appuyez pour plus de détails. + Il est possible que vous ayez été à proximité d’un utilisateur qui a été testé positif au COVID-19. Appuyez pour plus de détails. It is possible you have been in close proximity to a user who tested positive for COVID-19. Tap for more details. Possible COVID-19 Exposure - Exposition possible à COVIDE-19 + Exposition possible au COVID-19 Possible COVID-19 Exposure If you want to disable it, you can change it from the app settings - Si vous souhaitez le désactiver, vous pouvez le modifier à partir des paramètres de l’application + Si vous souhaitez le désactiver, vous pouvez le modifier à partir des paramètres de l’application Notifications enabled - Notifications activées + Notifications activées Information about the this app - Informations sur cette application + Informations sur cette application Q and A for user - Q et A pour l’utilisateur + Q and A pour l’utilisateur Name: \r\n Contact: \r\n Content of inquiry (Please select a category from the following): 1. How the app works, 2. App settings, 3. Use of the app (notification etc.) ), 4. Others \r\n Inquiry text: \r\n - Nom : \r\n Contact : \r\n Contenu de l’enquête (Veuillez sélectionner une catégorie parmi les éléments suivants : 1. Fonctionnement de l’application, 2. Paramètres de l’application, 3. Utilisation de l’application (notification, etc.) ), 4. Autres \r\n Texte de l’enquête : \r\n + Nom : \r\n Contact : \r\n Contenu de l’enquête (Veuillez sélectionner une catégorie parmi les éléments suivants : 1. Fonctionnement de l’application, 2. Paramètres de l’application, 3. Utilisation de l’application (notification, etc.) ), 4. Autres \r\n Texte de l’enquête : \r\n お名前:\r\nご連絡先:\r\nお問い合わせ内容(カテゴリを次の中からお選びください):1.アプリの仕組み、2.アプリの設定、 3.アプリの利用(通知など)、 4.その他\r\nお問い合わせ本文:\r\n Inquiries about contact confirmation app - Demandes de renseignements sur l’application de confirmation de contact + Demandes de renseignements sur l’application de confirmation de contact 接触確認アプリに関するお問い合わせ Days - JOURS + Jours X日間 Exposure Notification is active. - La notification d’exposition est active. + La notification d’exposition est active. Exposure Notification機能は許諾の状態です。 Bluetooth is turned off. Please turn on Bluetooth. - Bluetooth est désactivé. S’il vous plaît activer Bluetooth. + Le Bluetooth est désactivé. Veuillez activer le Bluetooth. BluetoothがOffになっています。Bluetoothを有効にしてください。 Exposure Notification is disabled. Open the terminal settings and turn on Exposure Notification. - La notification d’exposition est désactivée. Ouvrez les paramètres du terminal et activez la notification d’exposition. + La notification d’exposition est désactivée. Ouvrez les paramètres du terminal et activez la notification d’exposition. Exposure Notification機能は無効の状態です。端末の設定を開いて、Exposure NotificationをONにしてください。 You must agree to the terms of use. - Vous devez accepter les conditions d’utilisation. + Vous devez accepter les conditions d’utilisation. 利用規約に同意する必要があります。 COVID-19 Contact notification feature not approved. Please approve from each OS or re-approve after reinstalling the application. - La notification d’exposition est restreinte. S’il vous plaît actif. - Please verify the translation’s accuracy as the source string was updated after it was translated. + La fonction Notification d’exposition au COVID-19 n'est pas approuvée. Veuillez l'approuver via les paramètres du système d'exploitation, ou en réinstallant cette application. COVID-19接触通知機能が承認されていません。各OSから承認するか、またはアプリの再インストール後に、再承認してください。 Exposure Notification is not supported. Please update the OS to the latest version. If you still have problems, please contact us at appsupport@cov19.mhlw.go.jp. - La notification d’exposition n’est pas prise en charge. Veuillez mettre à jour le système d’exploitation vers la dernière version. Si vous avez encore des problèmes, s’il vous plaît contactez-nous à appsupport@cov19.mhlw.go.jp. + La Notification d’exposition n’est pas prise en charge. Veuillez mettre à jour le système d’exploitation vers la dernière version. Si vous avez encore des problèmes, s’il vous plaît contactez-nous à appsupport@cov19.mhlw.go.jp. Exposure Notification機能は非対応の状態です。OSを最新版にアップデートしてください。それでも改善しなければ、appsupport@cov19.mhlw.go.jpまでお問い合わせください。 Network connection error - Erreur de connexion réseau + Erreur de connexion réseau 通信に失敗しました。 Exposure Notification startup error - Erreur de démarrage de la notification d’exposition + Erreur au démarrage de la Notification d’Exposition Exposure Notification起動エラー Exposure Notification could not startup. Open the terminal settings, turn in Exposure Notification, and turn in Bluetooth. - La notification d’exposition n’a pas pu démarrer. Ouvrez les paramètres du terminal, activez la notification d’exposition et activez Bluetooth. + La Notification d’Exposition n’a pas pu démarrer. Ouvrez les paramètres du terminal, activez la Notification d’Exposition et activez le Bluetooth. Exposure Notificationを起動できませんでした。端末の設定を開いて、Exposure NotificationをONにするとともに、BluetoothをONにしてください。 Process number incorrect - Numéro de processus incorrect + Numéro de processus incorrect アプリで入力された処理番号が違います Cannot connect to registration center - Impossible de se connecter au centre d’enregistrement + Impossible de se connecter au centre d’enregistrement センターに接続できません Do you want to register positive information? - Voulez-vous enregistrer des informations positives? + Voulez-vous enregistrer comme étant testé positif ? 陽性情報を登録しますか? Register - Inscrire + S'enregistrer 登録 Canceled - Annulé + Annulé キャンセルしました Please wait for a while until registration starts - S’il vous plaît attendre un certain temps jusqu’à ce que l’inscription commence + Veuillez attendre un certain temps jusqu’à ce que l’inscription commence 登録開始までしばらくそのままでお待ちください Awaiting registration - En attente d’inscription + En attente d’inscription 登録待ち No processing number entered - Aucun numéro de traitement entré + Aucun numéro de traitement entré 処理番号が入力されていません Processing number format does not match - Le format de numéro de traitement ne correspond pas + Le format de numéro de traitement ne correspond pas 処理番号のフォーマットが一致していません In order to register positive records, it is necessary to enable COVID-19 contact log recording, please enable it from the application or OS settings. - Afin d’enregistrer des enregistrements positifs, il est nécessaire d’activer l’enregistrement du journal de contact COVID-19, veuillez l’activer à partir des paramètres de l’application ou du système d’exploitation. + Afin de s’enregistrer comme testé positif, il est nécessaire d’activer l’enregistrement du journal de contact rapproché COVID-19, veuillez l’activer à partir des paramètres de l’application ou du système d’exploitation. 陽性記録の登録を行う為にCOVID-19接触のログ記録を有効にする必要があります、アプリかOSの設定から有効にしてください。 Enable COVID-19 contact logging - Activer la journalisation des contacts COVIDE-19 + Activer la journalisation des contacts rapprochés COVID-19 COVID-19接触のログ記録を有効にしてください The number of registrations has reached the upper limit. Exit application - Le nombre d’enregistrements a atteint la limite supérieure. Application de sortie + Le nombre d’enregistrements a atteint la limite maximale. Sortie de l'application. 登録回数上限になりました。アプリケーションを終了します Registration error - Erreur d'inscription + Erreur d'inscription 登録エラー From 87ed432e4627ca6d30d2588031eebc5cd1f77eda Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 20:02:25 +0900 Subject: [PATCH 2/9] Bug Fix Android Side RollingPeriod in Android API / Xamarin EN Bind TEK value is ZERO --- Covid19Radar.sln | 32 ++ .../Covid19Radar.Android.csproj | 4 + .../Covid19Radar.iOS/Covid19Radar.iOS.csproj | 7 +- Covid19Radar/Covid19Radar/Covid19Radar.csproj | 4 +- .../Services/ExposureNotificationHandler.cs | 17 +- .../CallbackService.android.cs | 55 +++ .../ExposureInfo.shared.cs | 89 +++++ .../ExposureNotification.android.cs | 275 ++++++++++++++ .../ExposureNotification.ios.cs | 348 ++++++++++++++++++ .../ExposureNotification.netstandard.cs | 34 ++ .../ExposureNotification.shared.cs | 171 +++++++++ .../IExposureNotificationHandler.shared.cs | 37 ++ .../TemporaryExposureKey.shared.cs | 44 +++ .../Xamarin.ExposureNotification.csproj | 61 +++ 14 files changed, 1171 insertions(+), 7 deletions(-) create mode 100644 Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/ExposureInfo.shared.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.android.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.netstandard.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.shared.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/IExposureNotificationHandler.shared.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/TemporaryExposureKey.shared.cs create mode 100644 Covid19Radar/Xamarin.ExposureNotification/Xamarin.ExposureNotification.csproj diff --git a/Covid19Radar.sln b/Covid19Radar.sln index 77c18bc6..e70605e0 100644 --- a/Covid19Radar.sln +++ b/Covid19Radar.sln @@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{460BECFC EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Covid19Radar.UITest", "Covid19Radar\Tests\Covid19Radar.UITest\Covid19Radar.UITest.csproj", "{4223EE63-A661-4465-BBB0-08DD80DB2256}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.ExposureNotification", "Covid19Radar\Xamarin.ExposureNotification\Xamarin.ExposureNotification.csproj", "{58E47288-FE26-4402-97A1-EDE546F1D849}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -165,6 +167,36 @@ Global {4223EE63-A661-4465-BBB0-08DD80DB2256}.Release|iPhone.Build.0 = Release|Any CPU {4223EE63-A661-4465-BBB0-08DD80DB2256}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {4223EE63-A661-4465-BBB0-08DD80DB2256}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.AppStore|iPhone.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug_Mock|Any CPU.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug_Mock|Any CPU.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug_Mock|iPhone.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug_Mock|iPhone.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug_Mock|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug_Mock|iPhoneSimulator.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug|iPhone.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Release|Any CPU.Build.0 = Release|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Release|iPhone.ActiveCfg = Release|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Release|iPhone.Build.0 = Release|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {58E47288-FE26-4402-97A1-EDE546F1D849}.Release|iPhoneSimulator.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj b/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj index 65de88d1..989cb056 100644 --- a/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj +++ b/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj @@ -247,6 +247,10 @@ {554EE1AB-B447-480C-90E5-C4F040891DE6} Covid19Radar + + {58e47288-fe26-4402-97a1-ede546f1d849} + Xamarin.ExposureNotification + diff --git a/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj b/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj index 0106e093..1a03efde 100644 --- a/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj +++ b/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj @@ -79,7 +79,8 @@ -1 SdkOnly true - -all + + DEBUG;__IOS__;__MOBILE__;__UNIFIED__; @@ -511,6 +512,10 @@ {554EE1AB-B447-480C-90E5-C4F040891DE6} Covid19Radar + + {58e47288-fe26-4402-97a1-ede546f1d849} + Xamarin.ExposureNotification + diff --git a/Covid19Radar/Covid19Radar/Covid19Radar.csproj b/Covid19Radar/Covid19Radar/Covid19Radar.csproj index fbfd0815..8c294836 100644 --- a/Covid19Radar/Covid19Radar/Covid19Radar.csproj +++ b/Covid19Radar/Covid19Radar/Covid19Radar.csproj @@ -110,7 +110,6 @@ - @@ -191,6 +190,9 @@ + + + Always diff --git a/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs b/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs index 96b1f0ce..0f6a8c09 100644 --- a/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs +++ b/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs @@ -171,7 +171,7 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func lastTekTimestamp = userData.LastProcessTekTimestamp; @@ -190,8 +190,8 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func lastCreated || lastCreated == 0) { var tmpFile = Path.Combine(tmpDir, Guid.NewGuid().ToString() + ".zip"); - Debug.WriteLine(Utils.SerializeToJson(tekItem)); - Debug.WriteLine(tmpFile); + Console.WriteLine(Utils.SerializeToJson(tekItem)); + Console.WriteLine(tmpFile); using (Stream responseStream = await httpDataService.GetTemporaryExposureKey(tekItem.Url, cancellationToken)) using (var fileStream = File.Create(tmpFile)) @@ -212,8 +212,8 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func CreateSubmissionAsync(IEnumerable temporaryExposureKeys, PositiveDiagnosisState pendingDiagnosis) { // Create the network keys + var keys = temporaryExposureKeys.Select(k => new DiagnosisSubmissionParameter.Key { KeyData = Convert.ToBase64String(k.Key), @@ -265,10 +266,16 @@ private async Task CreateSubmissionAsync(IEnumerab TransmissionRisk = (int)k.TransmissionRiskLevel }); + var beforeKey = Utils.SerializeToJson(temporaryExposureKeys.ToList()); + var afterKey = Utils.SerializeToJson(keys.ToList()); + Console.WriteLine($"COCOA {beforeKey}"); + Console.WriteLine($"COCOA {afterKey}"); + foreach (var key in keys) { if (!key.IsValid()) { + Console.WriteLine($"COCOA Invalid Key Expcetion"); throw new InvalidDataException(); } } diff --git a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs new file mode 100644 index 00000000..806c9ad5 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using Android.App; +using Android.Content; +using Android.Gms.Nearby.ExposureNotification; +using Android.Runtime; +using AndroidX.Core.App; + +namespace Xamarin.ExposureNotifications +{ + [BroadcastReceiver( + Permission = "com.google.android.gms.nearby.exposurenotification.EXPOSURE_CALLBACK", + Exported = true)] + [IntentFilter(new[] { ExposureNotificationClient.ActionExposureStateUpdated })] + [Preserve] + class ExposureNotificationCallbackBroadcastReceiver : BroadcastReceiver + { + public override void OnReceive(Context context, Intent intent) + => ExposureNotificationCallbackService.EnqueueWork(context, intent); + } + + [Service( + Permission = "android.permission.BIND_JOB_SERVICE")] + [Preserve] + class ExposureNotificationCallbackService : JobIntentService + { + const int jobId = 0x02; + + public static void EnqueueWork(Context context, Intent work) + => EnqueueWork(context, Java.Lang.Class.FromType(typeof(ExposureNotificationCallbackService)), jobId, work); + + protected override async void OnHandleWork(Intent workIntent) + { + Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}"); + var token = workIntent.GetStringExtra(ExposureNotificationClient.ExtraToken); + + var summary = await ExposureNotification.PlatformGetExposureSummaryAsync(token); + + Task> GetInfo() + { + return ExposureNotification.PlatformGetExposureInformationAsync(token); + } + + // Invoke the custom implementation handler code with the summary info + Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); + + if (summary?.MatchedKeyCount > 0) + { + await ExposureNotification.Handler.ExposureDetectedAsync(summary, GetInfo); + } + } + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureInfo.shared.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureInfo.shared.cs new file mode 100644 index 00000000..481ad579 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureInfo.shared.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; + +namespace Xamarin.ExposureNotifications +{ + public class ExposureInfo + { + public ExposureInfo() + { + } + + public ExposureInfo(DateTime timestamp, TimeSpan duration, int attenuationValue, int totalRiskScore, RiskLevel riskLevel) + { + Timestamp = timestamp; + Duration = duration; + AttenuationValue = attenuationValue; + TotalRiskScore = totalRiskScore; + TransmissionRiskLevel = riskLevel; + } + + // When the contact occurred + public DateTime Timestamp { get; } + + // How long the contact lasted in 5 min increments + public TimeSpan Duration { get; } + + public int AttenuationValue { get; } + + public int TotalRiskScore { get; } + + public RiskLevel TransmissionRiskLevel { get; } + } + + public class ExposureDetectionSummary + { + [EditorBrowsable(EditorBrowsableState.Never)] + public ExposureDetectionSummary(int daysSinceLastExposure, ulong matchedKeyCount, byte maximumRiskScore) + : this(daysSinceLastExposure, matchedKeyCount, (int)maximumRiskScore, null, 0) + { + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public ExposureDetectionSummary(int daysSinceLastExposure, ulong matchedKeyCount, byte maximumRiskScore, TimeSpan[] attenuationDurations, int summationRiskScore) + : this(daysSinceLastExposure, matchedKeyCount, (int)maximumRiskScore, attenuationDurations, summationRiskScore) + { + } + + public ExposureDetectionSummary(int daysSinceLastExposure, ulong matchedKeyCount, int highestRiskScore) + : this(daysSinceLastExposure, matchedKeyCount, highestRiskScore, null, 0) + { + } + + public ExposureDetectionSummary(int daysSinceLastExposure, ulong matchedKeyCount, int highestRiskScore, TimeSpan[] attenuationDurations, int summationRiskScore) + { + DaysSinceLastExposure = daysSinceLastExposure; + MatchedKeyCount = matchedKeyCount; + HighestRiskScore = highestRiskScore; + AttenuationDurations = attenuationDurations; + SummationRiskScore = summationRiskScore; + } + + public int DaysSinceLastExposure { get; } + + public ulong MatchedKeyCount { get; } + + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Use HighestRiskScore instead.")] + public byte MaximumRiskScore => (byte)HighestRiskScore; + + public int HighestRiskScore { get; } + + public TimeSpan[] AttenuationDurations { get; } + + public int SummationRiskScore { get; } + } + + public enum RiskLevel + { + Invalid = 0, + Lowest = 1, + Low = 2, + MediumLow = 3, + Medium = 4, + MediumHigh = 5, + High = 6, + VeryHigh = 7, + Highest = 8 + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.android.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.android.cs new file mode 100644 index 00000000..55adb741 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.android.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Android.App; +using Android.Bluetooth; +using Android.Gms.Common.Apis; +using Android.Gms.Nearby.ExposureNotification; +using Android.Runtime; +using AndroidX.Work; +using Java.Nio.FileNio; + +using AndroidRiskLevel = Android.Gms.Nearby.ExposureNotification.RiskLevel; +using Nearby = Android.Gms.Nearby.NearbyClass; + +[assembly: UsesFeature("android.hardware.bluetooth_le", Required=true)] +[assembly: UsesFeature("android.hardware.bluetooth")] +[assembly: UsesPermission(Android.Manifest.Permission.Bluetooth)] + + +namespace Xamarin.ExposureNotifications +{ + public static partial class ExposureNotification + { + static IExposureNotificationClient instance; + + static IExposureNotificationClient Instance + => instance ??= Nearby.GetExposureNotificationClient(Application.Context); + + static async Task GetConfigurationAsync() + { + var c = await Handler.GetConfigurationAsync(); + + return new ExposureConfiguration.ExposureConfigurationBuilder() + .SetAttenuationScores(c.AttenuationScores) + .SetDurationScores(c.DurationScores) + .SetDaysSinceLastExposureScores(c.DaysSinceLastExposureScores) + .SetTransmissionRiskScores(c.TransmissionRiskScores) + .SetAttenuationWeight(c.AttenuationWeight) + .SetDaysSinceLastExposureWeight(c.DaysSinceLastExposureWeight) + .SetDurationWeight(c.DurationWeight) + .SetTransmissionRiskWeight(c.TransmissionWeight) + .SetMinimumRiskScore(c.MinimumRiskScore) + .SetDurationAtAttenuationThresholds(c.DurationAtAttenuationThresholds) + .Build(); + } + + const int requestCodeStartExposureNotification = 1111; + const int requestCodeGetTempExposureKeyHistory = 2222; + + static TaskCompletionSource tcsResolveConnection; + + public static void OnActivityResult(int requestCode, Result resultCode, global::Android.Content.Intent data) + { + if (requestCode == requestCodeStartExposureNotification || requestCode == requestCodeGetTempExposureKeyHistory) + { + if (resultCode == Result.Ok) + tcsResolveConnection?.TrySetResult(null); + else + tcsResolveConnection.TrySetException(new AccessDeniedException("Failed to resolve Exposure Notifications API")); + } + } + + static async Task ResolveApi(int requestCode, Func> apiCall) + { + try + { + return await apiCall(); + } + catch (ApiException apiEx) + { + if (apiEx.StatusCode == CommonStatusCodes.ResolutionRequired) // Resolution required + { + tcsResolveConnection = new TaskCompletionSource(); + + // Start the resolution + apiEx.Status.StartResolutionForResult(Essentials.Platform.CurrentActivity, requestCode); + + // Wait for the activity result to be called + await tcsResolveConnection.Task; + + // Try the original api call again + return await apiCall(); + } + } + + return default; + } + + static void PlatformInit() + { + _ = ScheduleFetchAsync(); + } + + static Task PlatformStart() + => ResolveApi(requestCodeStartExposureNotification, async () => + { + await Instance.StartAsync(); + return default; + }); + + static Task PlatformStop() + => ResolveApi(requestCodeStartExposureNotification, async () => + { + await Instance.StopAsync(); + return default; + }); + + static Task PlatformIsEnabled() + => ResolveApi(requestCodeStartExposureNotification, () => + Instance.IsEnabledAsync()); + + public static void ConfigureBackgroundWorkRequest(TimeSpan repeatInterval, Action requestBuilder) + { + if (requestBuilder == null) + throw new ArgumentNullException(nameof(requestBuilder)); + if (repeatInterval == null) + throw new ArgumentNullException(nameof(repeatInterval)); + + bgRequestBuilder = requestBuilder; + bgRepeatInterval = repeatInterval; + } + + static Action bgRequestBuilder = b => + b.SetConstraints(new Constraints.Builder() + .SetRequiresBatteryNotLow(true) + .SetRequiresDeviceIdle(true) + .SetRequiredNetworkType(NetworkType.Connected) + .Build()); + + static TimeSpan bgRepeatInterval = TimeSpan.FromHours(6); + + static Task PlatformScheduleFetch() + { + var workManager = WorkManager.GetInstance(Essentials.Platform.AppContext); + + var workRequestBuilder = new PeriodicWorkRequest.Builder( + typeof(BackgroundFetchWorker), + bgRepeatInterval); + + bgRequestBuilder.Invoke(workRequestBuilder); + + var workRequest = workRequestBuilder.Build(); + + workManager.EnqueueUniquePeriodicWork("exposurenotification", + ExistingPeriodicWorkPolicy.Replace, + workRequest); + + return Task.CompletedTask; + } + + // Tells the local API when new diagnosis keys have been obtained from the server + static async Task PlatformDetectExposuresAsync(IEnumerable keyFiles, System.Threading.CancellationToken cancellationToken) + { + var config = await GetConfigurationAsync(); + + await Instance.ProvideDiagnosisKeysAsync( + keyFiles.Select(f => new Java.IO.File(f)).ToList(), + config, + Guid.NewGuid().ToString()); + } + + static Task> PlatformGetTemporaryExposureKeys() + => ResolveApi(requestCodeGetTempExposureKeyHistory, async () => + { + var exposureKeyHistory = await Instance.GetTemporaryExposureKeyHistoryAsync(); + + return exposureKeyHistory.Select(k => + new TemporaryExposureKey( + k.GetKeyData(), + k.RollingStartIntervalNumber, + TimeSpan.FromMinutes(k.RollingPeriod * 10), + k.TransmissionRiskLevel.FromNative())); + }); + + internal static async Task> PlatformGetExposureInformationAsync(string token) + { + var exposures = await Instance.GetExposureInformationAsync(token); + var info = exposures.Select(d => new ExposureInfo( + DateTimeOffset.UnixEpoch.AddMilliseconds(d.DateMillisSinceEpoch).UtcDateTime, + TimeSpan.FromMinutes(d.DurationMinutes), + d.AttenuationValue, + d.TotalRiskScore, + d.TransmissionRiskLevel.FromNative())); + return info; + } + + internal static async Task PlatformGetExposureSummaryAsync(string token) + { + var summary = await Instance.GetExposureSummaryAsync(token); + + // TODO: Reevaluate byte usage here + return new ExposureDetectionSummary( + summary.DaysSinceLastExposure, + (ulong)summary.MatchedKeyCount, + summary.MaximumRiskScore, + summary.GetAttenuationDurationsInMinutes() + .Select(a => TimeSpan.FromMinutes(a)).ToArray(), + summary.SummationRiskScore); + } + + static async Task PlatformGetStatusAsync() + { + var bt = BluetoothAdapter.DefaultAdapter; + + if (bt == null || !bt.IsEnabled) + return Status.BluetoothOff; + + var status = await Instance.IsEnabledAsync(); + + return status ? Status.Active : Status.Disabled; + } + } + + public class BackgroundFetchWorker : Worker + { + public BackgroundFetchWorker(global::Android.Content.Context context, WorkerParameters workerParameters) + : base(context, workerParameters) + { + } + + public override Result DoWork() + { + try + { + Task.Run(() => DoAsyncWork()).GetAwaiter().GetResult(); + return Result.InvokeSuccess(); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(ex); + return Result.InvokeRetry(); + } + } + + async Task DoAsyncWork() + { + if (await ExposureNotification.IsEnabledAsync()) + await ExposureNotification.UpdateKeysFromServer(); + } + } + + static partial class Utils + { + public static RiskLevel FromNative(this int riskLevel) => + riskLevel switch + { + AndroidRiskLevel.RiskLevelLowest => RiskLevel.Lowest, + AndroidRiskLevel.RiskLevelLow => RiskLevel.Low, + AndroidRiskLevel.RiskLevelLowMedium => RiskLevel.MediumLow, + AndroidRiskLevel.RiskLevelMedium => RiskLevel.Medium, + AndroidRiskLevel.RiskLevelMediumHigh => RiskLevel.MediumHigh, + AndroidRiskLevel.RiskLevelHigh => RiskLevel.High, + AndroidRiskLevel.RiskLevelVeryHigh => RiskLevel.VeryHigh, + AndroidRiskLevel.RiskLevelHighest => RiskLevel.Highest, + _ => AndroidRiskLevel.RiskLevelInvalid, + }; + + public static int ToNative(this RiskLevel riskLevel) => + riskLevel switch + { + RiskLevel.Lowest => AndroidRiskLevel.RiskLevelLowest, + RiskLevel.Low => AndroidRiskLevel.RiskLevelLow, + RiskLevel.MediumLow => AndroidRiskLevel.RiskLevelLowMedium, + RiskLevel.Medium => AndroidRiskLevel.RiskLevelMedium, + RiskLevel.MediumHigh => AndroidRiskLevel.RiskLevelMediumHigh, + RiskLevel.High => AndroidRiskLevel.RiskLevelHigh, + RiskLevel.VeryHigh => AndroidRiskLevel.RiskLevelVeryHigh, + RiskLevel.Highest => AndroidRiskLevel.RiskLevelHighest, + _ => AndroidRiskLevel.RiskLevelInvalid, + }; + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs new file mode 100644 index 00000000..e1fdeb3d --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using BackgroundTasks; +using ExposureNotifications; +using Foundation; +using Xamarin.Essentials; + +namespace Xamarin.ExposureNotifications +{ + public static partial class ExposureNotification + { + static ENManager manager; + + static async Task GetManagerAsync() + { + if (manager == null) + { + manager = new ENManager(); + await manager.ActivateAsync(); + } + + return manager; + } + + static async Task GetConfigurationAsync() + { + var c = await Handler.GetConfigurationAsync(); + + var nc = new ENExposureConfiguration + { + AttenuationLevelValues = c.AttenuationScores, + DurationLevelValues = c.DurationScores, + DaysSinceLastExposureLevelValues = c.DaysSinceLastExposureScores, + TransmissionRiskLevelValues = c.TransmissionRiskScores, + AttenuationWeight = c.AttenuationWeight, + DaysSinceLastExposureWeight = c.DaysSinceLastExposureWeight, + DurationWeight = c.DurationWeight, + TransmissionRiskWeight = c.TransmissionWeight, + MinimumRiskScore = (byte)c.MinimumRiskScore, + }; + + var metadata = new NSMutableDictionary(); + metadata.SetValueForKey(new NSNumber(c.MinimumRiskScore), new NSString("minimumRiskScoreFullRange")); + + if (c.DurationAtAttenuationThresholds != null) + { + if (c.DurationAtAttenuationThresholds.Length < 2) + throw new ArgumentOutOfRangeException(nameof(c.DurationAtAttenuationThresholds), "Must be an array of length 2"); + + var attKey = new NSString("attenuationDurationThresholds"); + var attValue = NSArray.FromObjects(2, c.DurationAtAttenuationThresholds[0], c.DurationAtAttenuationThresholds[1]); + metadata.SetValueForKey(attValue, attKey); + } + + nc.Metadata = metadata; + + return nc; + } + + static void PlatformInit() + { + _ = ScheduleFetchAsync(); + } + + static async Task PlatformStart() + { + var m = await GetManagerAsync(); + await m.SetExposureNotificationEnabledAsync(true); + } + + static async Task PlatformStop() + { + var m = await GetManagerAsync(); + await m.SetExposureNotificationEnabledAsync(false); + } + + static async Task PlatformIsEnabled() + { + var m = await GetManagerAsync(); + return m.ExposureNotificationEnabled; + } + + static Task PlatformScheduleFetch() + { + // This is a special ID suffix which iOS treats a certain way + // we can basically request infinite background tasks + // and iOS will throttle it sensibly for us. + var id = AppInfo.PackageName + ".exposure-notification"; + + var isUpdating = false; + BGTaskScheduler.Shared.Register(id, null, task => + { + // Disallow concurrent exposure detection, because if allowed we might try to detect the same diagnosis keys more than once + if (isUpdating) + { + task.SetTaskCompleted(false); + return; + } + isUpdating = true; + + var cancelSrc = new CancellationTokenSource(); + task.ExpirationHandler = cancelSrc.Cancel; + + // Run the actual task on a background thread + Task.Run(async () => + { + try + { + await UpdateKeysFromServer(cancelSrc.Token); + task.SetTaskCompleted(true); + } + catch (OperationCanceledException) + { + Console.WriteLine($"[Xamarin.ExposureNotifications] Background task took too long to complete."); + } + catch (Exception ex) + { + Console.WriteLine($"[Xamarin.ExposureNotifications] There was an error running the background task: {ex}"); + task.SetTaskCompleted(false); + } + + isUpdating = false; + }); + + scheduleBgTask(); + }); + + scheduleBgTask(); + + return Task.CompletedTask; + + void scheduleBgTask() + { + if (ENManager.AuthorizationStatus != ENAuthorizationStatus.Authorized) + return; + + var newBgTask = new BGProcessingTaskRequest(id); + newBgTask.RequiresNetworkConnectivity = true; + try + { + BGTaskScheduler.Shared.Submit(newBgTask, out var error); + + if (error != null) + throw new NSErrorException(error); + } + catch (Exception ex) + { + Console.WriteLine($"[Xamarin.ExposureNotifications] There was an error submitting the background task: {ex}"); + } + } + } + + // Tells the local API when new diagnosis keys have been obtained from the server + static async Task<(ExposureDetectionSummary, Func>>)> PlatformDetectExposuresAsync(IEnumerable keyFiles, CancellationToken cancellationToken) + { + // Submit to the API + var c = await GetConfigurationAsync(); + var m = await GetManagerAsync(); + + // Extract all the files from the zips + var allFiles = new List(); + foreach (var file in keyFiles) + { + using var stream = File.OpenRead(file); + using var archive = new ZipArchive(stream, ZipArchiveMode.Read); + + // .bin + var binTmp = Path.Combine(FileSystem.CacheDirectory, Guid.NewGuid().ToString() + ".bin"); + using (var binWrite = File.Create(binTmp)) + { + var bin = archive.GetEntry("export.bin"); + using var binRead = bin.Open(); + await binRead.CopyToAsync(binWrite); + } + allFiles.Add(binTmp); + + // .sig + var sigTmp = Path.ChangeExtension(binTmp, ".sig"); + using (var sigWrite = File.Create(sigTmp)) + { + var sig = archive.GetEntry("export.sig"); + using var sigRead = sig.Open(); + await sigRead.CopyToAsync(sigWrite); + } + allFiles.Add(sigTmp); + } + + // Start the detection + var detectionSummaryTask = m.DetectExposuresAsync( + c, + allFiles.Select(k => new NSUrl(k, false)).ToArray(), + out var detectProgress); + cancellationToken.Register(detectProgress.Cancel); + var detectionSummary = await detectionSummaryTask; + + // Delete all the extracted files + foreach (var file in allFiles) + { + try + { + File.Delete(file); + } + catch + { + // no-op + } + } + + var attDurTs = new List(); + var dictKey = new NSString("attenuationDurations"); + if (detectionSummary.Metadata.ContainsKey(dictKey)) + { + var attDur = detectionSummary.Metadata.ObjectForKey(dictKey) as NSArray; + + for (nuint i = 0; i < attDur.Count; i++) + attDurTs.Add(TimeSpan.FromSeconds(attDur.GetItem(i).Int32Value)); + } + + var sumRisk = 0; + dictKey = new NSString("riskScoreSumFullRange"); + if (detectionSummary.Metadata.ContainsKey(dictKey)) + { + var sro = detectionSummary.Metadata.ObjectForKey(dictKey); + if (sro is NSNumber sron) + sumRisk = sron.Int32Value; + } + + var maxRisk = 0; + dictKey = new NSString("maximumRiskScoreFullRange"); + if (detectionSummary.Metadata.ContainsKey(dictKey)) + { + var sro = detectionSummary.Metadata.ObjectForKey(dictKey); + if (sro is NSNumber sron) + maxRisk = sron.Int32Value; + } + else + { + maxRisk = detectionSummary.MaximumRiskScore; + } + + var summary = new ExposureDetectionSummary( + (int)detectionSummary.DaysSinceLastExposure, + detectionSummary.MatchedKeyCount, + maxRisk, + attDurTs.ToArray(), + sumRisk); + + async Task> GetInfo() + { + // Get the info + IEnumerable info = Array.Empty(); + if (summary?.MatchedKeyCount > 0) + { + var exposures = await m.GetExposureInfoAsync(detectionSummary, Handler.UserExplanation, out var exposuresProgress); + cancellationToken.Register(exposuresProgress.Cancel); + info = exposures.Select(i => + { + var totalRisk = 0; + var dictKey = new NSString("totalRiskScoreFullRange"); + if (i.Metadata.ContainsKey(dictKey)) + { + var sro = i.Metadata.ObjectForKey(dictKey); + if (sro is NSNumber sron) + totalRisk = sron.Int32Value; + } + else + { + totalRisk = i.TotalRiskScore; + } + + return new ExposureInfo( + ((DateTime)i.Date).ToLocalTime(), + TimeSpan.FromMinutes(i.Duration), + i.AttenuationValue, + totalRisk, + i.TransmissionRiskLevel.FromNative()); + }); + } + return info; + } + + // Return everything + return (summary, GetInfo); + } + + static async Task> PlatformGetTemporaryExposureKeys() + { + var m = await GetManagerAsync(); + var selfKeys = await m.GetDiagnosisKeysAsync(); + + return selfKeys.Select(k => new TemporaryExposureKey( + k.KeyData.ToArray(), + k.RollingStartNumber, + TimeSpan.FromMinutes(k.RollingPeriod * 10), + k.TransmissionRiskLevel.FromNative())); + } + + static async Task PlatformGetStatusAsync() + { + var m = await GetManagerAsync(); + + return m.ExposureNotificationStatus switch + { + ENStatus.Active => Status.Active, + ENStatus.BluetoothOff => Status.BluetoothOff, + ENStatus.Disabled => Status.Disabled, + ENStatus.Restricted => Status.Restricted, + _ => Status.Unknown, + }; + } + } + + static partial class Utils + { + public static RiskLevel FromNative(this byte riskLevel) => + riskLevel switch + { + 1 => RiskLevel.Lowest, + 2 => RiskLevel.Low, + 3 => RiskLevel.MediumLow, + 4 => RiskLevel.Medium, + 5 => RiskLevel.MediumHigh, + 6 => RiskLevel.High, + 7 => RiskLevel.VeryHigh, + 8 => RiskLevel.Highest, + _ => RiskLevel.Invalid, + }; + + public static byte ToNative(this RiskLevel riskLevel) => + riskLevel switch + { + RiskLevel.Lowest => 1, + RiskLevel.Low => 2, + RiskLevel.MediumLow => 3, + RiskLevel.Medium => 4, + RiskLevel.MediumHigh => 5, + RiskLevel.High => 6, + RiskLevel.VeryHigh => 7, + RiskLevel.Highest => 8, + _ => 0, + }; + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.netstandard.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.netstandard.cs new file mode 100644 index 00000000..a1fe7151 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.netstandard.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Xamarin.ExposureNotifications +{ + public static partial class ExposureNotification + { + static void PlatformInit() + => throw new PlatformNotSupportedException(); + + static Task PlatformStart() + => throw new PlatformNotSupportedException(); + + static Task PlatformStop() + => throw new PlatformNotSupportedException(); + + static Task PlatformIsEnabled() + => throw new PlatformNotSupportedException(); + + static Task PlatformScheduleFetch() + => throw new PlatformNotSupportedException(); + + static Task<(ExposureDetectionSummary, IEnumerable)> PlatformDetectExposuresAsync(IEnumerable diagnosisKeys, CancellationToken cancellationToken) + => throw new PlatformNotSupportedException(); + + static Task> PlatformGetTemporaryExposureKeys() + => throw new PlatformNotSupportedException(); + + static Task PlatformGetStatusAsync() + => throw new PlatformNotSupportedException(); + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.shared.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.shared.cs new file mode 100644 index 00000000..da405c92 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.shared.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Xamarin.ExposureNotifications +{ + public static partial class ExposureNotification + { + static INativeImplementation nativeImplementation; + + public static void OverrideNativeImplementation(INativeImplementation nativeImplementation) + => ExposureNotification.nativeImplementation = nativeImplementation; + + static IExposureNotificationHandler handler; + + public static bool OverridesNativeImplementation + => ExposureNotification.nativeImplementation != null; + + internal static IExposureNotificationHandler Handler + { + get + { + if (handler != default) + return handler; + + // Look up implementations of IExposureNotificationHandler + var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var asm in allAssemblies) + { + if (asm.IsDynamic) + continue; + + var asmName = asm.GetName().Name; + + if (asmName.StartsWith("mscorlib") + || asmName.StartsWith("System.", StringComparison.OrdinalIgnoreCase) + || asmName.StartsWith("Xamarin.", StringComparison.OrdinalIgnoreCase)) + continue; + + var allTypes = asm.GetExportedTypes(); + + foreach (var t in allTypes) + { + if (t.IsClass && typeof(IExposureNotificationHandler).IsAssignableFrom(t)) + { + handler = (IExposureNotificationHandler)Activator.CreateInstance(t); + } + } + } + + if (handler == default) + throw new NotImplementedException($"Missing an implementation for {nameof(IExposureNotificationHandler)}"); + + return handler; + } + } + + public static void Init() + => PlatformInit(); + + public static Task ScheduleFetchAsync() + => PlatformScheduleFetch(); + + public static Task StartAsync() + => nativeImplementation != null ? nativeImplementation.StartAsync() : PlatformStart(); + + public static Task StopAsync() + => nativeImplementation != null ? nativeImplementation.StopAsync() : PlatformStop(); + + public static Task IsEnabledAsync() + => nativeImplementation != null ? nativeImplementation.IsEnabledAsync() : PlatformIsEnabled(); + + // Call this when the user has confirmed diagnosis + public static async Task SubmitSelfDiagnosisAsync() + { + var selfKeys = await GetSelfTemporaryExposureKeysAsync(); + await Handler.UploadSelfExposureKeysToServerAsync(selfKeys); + } + + // Call this when the app needs to update the local keys + public static async Task UpdateKeysFromServer(CancellationToken cancellationToken = default) + { + var processedAnyFiles = false; + + await Handler?.FetchExposureKeyBatchFilesFromServerAsync(async downloadedFiles => + { + cancellationToken.ThrowIfCancellationRequested(); + + if (!downloadedFiles.Any()) + return; + + if (nativeImplementation != null) + { + var r = await nativeImplementation.DetectExposuresAsync(downloadedFiles); + + var hasMatches = (r.summary?.MatchedKeyCount ?? 0) > 0; + + if (hasMatches) + await Handler.ExposureDetectedAsync(r.summary, r.getInfo); + } + else + { +#if __IOS__ + // On iOS we need to check this ourselves and invoke the handler + var (summary, info) = await PlatformDetectExposuresAsync(downloadedFiles, cancellationToken); + + // Check that the summary has any matches before notifying the callback + if (summary?.MatchedKeyCount > 0) + await Handler.ExposureDetectedAsync(summary, info); +#elif __ANDROID__ + // on Android this will happen in the broadcast receiver + await PlatformDetectExposuresAsync(downloadedFiles, cancellationToken); +#endif + } + + processedAnyFiles = true; + }, cancellationToken); + + return processedAnyFiles; + } + + internal static Task> GetSelfTemporaryExposureKeysAsync() + => nativeImplementation != null ? nativeImplementation.GetSelfTemporaryExposureKeysAsync() : PlatformGetTemporaryExposureKeys(); + + public static Task GetStatusAsync() + => nativeImplementation != null ? nativeImplementation.GetStatusAsync() : PlatformGetStatusAsync(); + } + + public enum Status + { + Unknown, + Disabled, + Active, + BluetoothOff, + Restricted, + NotAuthorized + } + + public class Configuration + { + // Minimum risk score required to record + public int MinimumRiskScore { get; set; } = 4; + + public int AttenuationWeight { get; set; } = 50; + + public int TransmissionWeight { get; set; } = 50; + + public int DurationWeight { get; set; } = 50; + + public int DaysSinceLastExposureWeight { get; set; } = 50; + + public int[] TransmissionRiskScores { get; set; } = new int[] { 4, 4, 4, 4, 4, 4, 4, 4 }; + + // Scores assigned to the attenuation of the BTLE signal of exposures + // A > 73dBm, 73 <= A > 63, 63 <= A > 51, 51 <= A > 33, 33 <= A > 27, 27 <= A > 15, 15 <= A > 10, A <= 10 + public int[] AttenuationScores { get; set; } = new[] { 4, 4, 4, 4, 4, 4, 4, 4 }; + + // Scores assigned to each length of exposure + // < 5min, 5min, 10min, 15min, 20min, 25min, 30min, > 30min + public int[] DurationScores { get; set; } = new[] { 4, 4, 4, 4, 4, 4, 4, 4 }; + + // Scores assigned to each range of days of exposure + // >= 14days, 13-12, 11-10, 9-8, 7-6, 5-4, 3-2, 1-0 + public int[] DaysSinceLastExposureScores { get; set; } = new[] { 4, 4, 4, 4, 4, 4, 4, 4 }; + + public int[] DurationAtAttenuationThresholds { get; set; } = new[] { 50, 70 }; + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/IExposureNotificationHandler.shared.cs b/Covid19Radar/Xamarin.ExposureNotification/IExposureNotificationHandler.shared.cs new file mode 100644 index 00000000..a3567397 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/IExposureNotificationHandler.shared.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Xamarin.ExposureNotifications +{ + public interface IExposureNotificationHandler + { + string UserExplanation { get; } + + Task GetConfigurationAsync(); + + // Go fetch the keys from your server + Task FetchExposureKeyBatchFilesFromServerAsync(Func, Task> submitBatches, CancellationToken cancellationToken); + + // Might be exposed, check and alert user if necessary + Task ExposureDetectedAsync(ExposureDetectionSummary summary, Func>> getExposureInfo); + + Task UploadSelfExposureKeysToServerAsync(IEnumerable temporaryExposureKeys); + } + + public interface INativeImplementation + { + Task StartAsync(); + + Task StopAsync(); + + Task IsEnabledAsync(); + + Task<(ExposureDetectionSummary summary, Func>> getInfo)> DetectExposuresAsync(IEnumerable files); + + Task> GetSelfTemporaryExposureKeysAsync(); + + Task GetStatusAsync(); + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/TemporaryExposureKey.shared.cs b/Covid19Radar/Xamarin.ExposureNotification/TemporaryExposureKey.shared.cs new file mode 100644 index 00000000..20023946 --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/TemporaryExposureKey.shared.cs @@ -0,0 +1,44 @@ +using System; + +namespace Xamarin.ExposureNotifications +{ + public class TemporaryExposureKey + { + // static readonly DateTimeOffset epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero); + + public TemporaryExposureKey() + { + } + + public TemporaryExposureKey(byte[] keyData, DateTimeOffset rollingStart, TimeSpan rollingDuration, RiskLevel transmissionRisk) + { + Key = keyData; + RollingStart = rollingStart; + RollingDuration = rollingDuration; + TransmissionRiskLevel = transmissionRisk; + } + + internal TemporaryExposureKey(byte[] keyData, long rollingStart, TimeSpan rollingDuration, RiskLevel transmissionRisk) + { + Key = keyData; + RollingStart = DateTimeOffset.FromUnixTimeSeconds(rollingStart * (60 * 10)); + RollingDuration = rollingDuration; + TransmissionRiskLevel = transmissionRisk; + } + + public byte[] Key { get; set; } + + public DateTimeOffset RollingStart { get; set; } + + public TimeSpan RollingDuration { get; set; } + + public RiskLevel TransmissionRiskLevel { get; set; } + + // public string KeyBase64 => + // Convert.ToBase64String(Key); + // public long RollingStartTenMinuteIntervalsSinceEpoch => + // (long)((RollingStart - epoch).TotalMinutes / 10); + // public int RollingDurationTenMinuteIntervals => + // (int)(RollingDuration.TotalMinutes / 10); + } +} diff --git a/Covid19Radar/Xamarin.ExposureNotification/Xamarin.ExposureNotification.csproj b/Covid19Radar/Xamarin.ExposureNotification/Xamarin.ExposureNotification.csproj new file mode 100644 index 00000000..1a701c1f --- /dev/null +++ b/Covid19Radar/Xamarin.ExposureNotification/Xamarin.ExposureNotification.csproj @@ -0,0 +1,61 @@ + + + + netstandard2.0;xamarin.ios10;monoandroid10.0 + false + 1.0.0.0 + 1.0.0.0 + 1.0.0 + 8.0 + + + + Xamarin.ExposureNotification + Cross Platform Exposure Notification for Xamarin + Xamarin Exposure Notification + Cross Platform Exposure Notification for Xamarin + 0.1.0-preview + Microsoft + microsoft,Xamarin,XamarinNuGet + en + © Microsoft Corporation. All rights reserved. + https://go.microsoft.com/fwlink/?linkid=2129007 + LICENSE.md + true + https://go.microsoft.com/fwlink/?linkid=2129007 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a335337d049a4b7fbab8ae9d47073027f3ea80de Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 21:06:21 +0900 Subject: [PATCH 3/9] =?UTF-8?q?Fix=20=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Covid19Radar/MultilingualResources/Covid19Radar.ja.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.ja.xlf b/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.ja.xlf index 00f00a35..14583131 100644 --- a/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.ja.xlf +++ b/Covid19Radar/Covid19Radar/MultilingualResources/Covid19Radar.ja.xlf @@ -723,7 +723,7 @@ It is possible you have been in close proximity to a user who tested positive for COVID-19. Tap for more details. - 新型コロナウイルス陽性登録者と接触した可能性があります。詳細はこちら。 + 新型コロナウイルス陽性登録者と接触した可能性があります。詳細はこちら It is possible you have been in close proximity to a user who tested positive for COVID-19. Tap for more details. From 230c359d77e406f5216d213212850cdbd6d28cf9 Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 21:11:12 +0900 Subject: [PATCH 4/9] Change Console to Debug --- .../Covid19Radar/Services/ExposureNotificationService.cs | 2 +- .../ViewModels/HomePage/ContactedNotifyPageViewModel.cs | 4 ++-- .../Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs | 2 +- .../Xamarin.ExposureNotification/CallbackService.android.cs | 4 ++-- .../ExposureNotification.ios.cs | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Covid19Radar/Covid19Radar/Services/ExposureNotificationService.cs b/Covid19Radar/Covid19Radar/Services/ExposureNotificationService.cs index e9fab88d..56465dcd 100644 --- a/Covid19Radar/Covid19Radar/Services/ExposureNotificationService.cs +++ b/Covid19Radar/Covid19Radar/Services/ExposureNotificationService.cs @@ -137,7 +137,7 @@ public async Task StopExposureNotification() } catch (Exception ex) { - Console.WriteLine($"Error disabling notifications: {ex}"); + Debug.WriteLine($"Error disabling notifications: {ex}"); return false; } finally diff --git a/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs b/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs index 3369fe1b..3049cdec 100644 --- a/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs +++ b/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs @@ -44,12 +44,12 @@ public ContactedNotifyPageViewModel(INavigationService navigationService, UserDa { var json = await client.GetStringAsync(uri); var phoneNumber = JObject.Parse(json).Value("phone"); - Console.WriteLine($"Contacted phone call number = {phoneNumber}"); + Debug.WriteLine($"Contacted phone call number = {phoneNumber}"); PhoneDialer.Open(phoneNumber); } catch (Exception ex) { - Console.WriteLine(ex.ToString()); + Debug.WriteLine(ex.ToString()); } finally { diff --git a/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs b/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs index 9b239dc7..98ef2ea6 100644 --- a/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs +++ b/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs @@ -51,7 +51,7 @@ public override async void Initialize(INavigationParameters parameters) } catch (Exception ex) { - Console.WriteLine(ex.ToString()); + Debug.WriteLine(ex.ToString()); } } diff --git a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs index 806c9ad5..996fca6c 100644 --- a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs +++ b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs @@ -33,7 +33,7 @@ public static void EnqueueWork(Context context, Intent work) protected override async void OnHandleWork(Intent workIntent) { - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}"); + Debug.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}"); var token = workIntent.GetStringExtra(ExposureNotificationClient.ExtraToken); var summary = await ExposureNotification.PlatformGetExposureSummaryAsync(token); @@ -44,7 +44,7 @@ Task> GetInfo() } // Invoke the custom implementation handler code with the summary info - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); + Debug.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); if (summary?.MatchedKeyCount > 0) { diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs index e1fdeb3d..11ff9c5a 100644 --- a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs @@ -116,11 +116,11 @@ static Task PlatformScheduleFetch() } catch (OperationCanceledException) { - Console.WriteLine($"[Xamarin.ExposureNotifications] Background task took too long to complete."); + Debug.WriteLine($"[Xamarin.ExposureNotifications] Background task took too long to complete."); } catch (Exception ex) { - Console.WriteLine($"[Xamarin.ExposureNotifications] There was an error running the background task: {ex}"); + Debug.WriteLine($"[Xamarin.ExposureNotifications] There was an error running the background task: {ex}"); task.SetTaskCompleted(false); } @@ -150,7 +150,7 @@ void scheduleBgTask() } catch (Exception ex) { - Console.WriteLine($"[Xamarin.ExposureNotifications] There was an error submitting the background task: {ex}"); + Debug.WriteLine($"[Xamarin.ExposureNotifications] There was an error submitting the background task: {ex}"); } } } From 086c888f844a71a77bdf2cf53b2a6409dd945336 Mon Sep 17 00:00:00 2001 From: Atsushi Kuramochi Date: Sun, 28 Jun 2020 21:12:20 +0900 Subject: [PATCH 5/9] [Feature][Android] Add log ACTION_EXPOSURE_NOT_FOUND broadcast intent. --- .../CallbackService.android.cs | 95 +++++++++++-------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs index 806c9ad5..a2877f36 100644 --- a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs +++ b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs @@ -10,46 +10,57 @@ namespace Xamarin.ExposureNotifications { - [BroadcastReceiver( - Permission = "com.google.android.gms.nearby.exposurenotification.EXPOSURE_CALLBACK", - Exported = true)] - [IntentFilter(new[] { ExposureNotificationClient.ActionExposureStateUpdated })] - [Preserve] - class ExposureNotificationCallbackBroadcastReceiver : BroadcastReceiver - { - public override void OnReceive(Context context, Intent intent) - => ExposureNotificationCallbackService.EnqueueWork(context, intent); - } - - [Service( - Permission = "android.permission.BIND_JOB_SERVICE")] - [Preserve] - class ExposureNotificationCallbackService : JobIntentService - { - const int jobId = 0x02; - - public static void EnqueueWork(Context context, Intent work) - => EnqueueWork(context, Java.Lang.Class.FromType(typeof(ExposureNotificationCallbackService)), jobId, work); - - protected override async void OnHandleWork(Intent workIntent) - { - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}"); - var token = workIntent.GetStringExtra(ExposureNotificationClient.ExtraToken); - - var summary = await ExposureNotification.PlatformGetExposureSummaryAsync(token); - - Task> GetInfo() - { - return ExposureNotification.PlatformGetExposureInformationAsync(token); - } - - // Invoke the custom implementation handler code with the summary info - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); - - if (summary?.MatchedKeyCount > 0) - { - await ExposureNotification.Handler.ExposureDetectedAsync(summary, GetInfo); - } - } - } + [BroadcastReceiver( + Permission = "com.google.android.gms.nearby.exposurenotification.EXPOSURE_CALLBACK", + Exported = true)] + [IntentFilter(new[] { ExposureNotificationClient.ActionExposureStateUpdated, "com.google.android.gms.exposurenotification.ACTION_EXPOSURE_NOT_FOUND" })] + [Preserve] + class ExposureNotificationCallbackBroadcastReceiver : BroadcastReceiver + { + public override void OnReceive(Context context, Intent intent) + { + // https://developers.google.com/android/exposure-notifications/exposure-notifications-api#methods + var action = intent.Action; + if(action == ExposureNotificationClient.ActionExposureStateUpdated) + { + ExposureNotificationCallbackService.EnqueueWork(context, intent); + } + else if(action == "com.google.android.gms.exposurenotification.ACTION_EXPOSURE_NOT_FOUND") + { + Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackBroadcastReceiver)} ACTION_EXPOSURE_NOT_FOUND."); + } + } + } + + [Service( + Permission = "android.permission.BIND_JOB_SERVICE")] + [Preserve] + class ExposureNotificationCallbackService : JobIntentService + { + const int jobId = 0x02; + + public static void EnqueueWork(Context context, Intent work) + => EnqueueWork(context, Java.Lang.Class.FromType(typeof(ExposureNotificationCallbackService)), jobId, work); + + protected override async void OnHandleWork(Intent workIntent) + { + Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}"); + var token = workIntent.GetStringExtra(ExposureNotificationClient.ExtraToken); + + var summary = await ExposureNotification.PlatformGetExposureSummaryAsync(token); + + Task> GetInfo() + { + return ExposureNotification.PlatformGetExposureInformationAsync(token); + } + + // Invoke the custom implementation handler code with the summary info + Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); + + if (summary?.MatchedKeyCount > 0) + { + await ExposureNotification.Handler.ExposureDetectedAsync(summary, GetInfo); + } + } + } } From abaa68a444e205f0ada9d75b33b3c56ed1b443cd Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 21:18:00 +0900 Subject: [PATCH 6/9] Change Logging TAG --- .../Services/ExposureNotificationHandler.cs | 24 +++++++++---------- .../CallbackService.android.cs | 6 ++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs b/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs index 0f6a8c09..c555eba3 100644 --- a/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs +++ b/Covid19Radar/Covid19Radar/Services/ExposureNotificationHandler.cs @@ -79,7 +79,7 @@ await Device.InvokeOnMainThreadAsync(() => { foreach (var exposure in exposureInfo) { - Console.WriteLine($"COCOA found exposure {exposure.Timestamp}"); + Debug.WriteLine($"C19R found exposure {exposure.Timestamp}"); UserExposureInfo userExposureInfo = new UserExposureInfo(exposure.Timestamp, exposure.Duration, exposure.AttenuationValue, exposure.TotalRiskScore, (Covid19Radar.Model.UserRiskLevel)exposure.TransmissionRiskLevel); userData.ExposureInformation.Add(userExposureInfo); @@ -121,7 +121,7 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func 0) { - Console.WriteLine("COCOA Submit Batches"); + Debug.WriteLine("C19R Submit Batches"); await submitBatches(downloadedFiles); // delete all temporary files @@ -171,7 +171,7 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func lastTekTimestamp = userData.LastProcessTekTimestamp; @@ -190,8 +190,8 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func lastCreated || lastCreated == 0) { var tmpFile = Path.Combine(tmpDir, Guid.NewGuid().ToString() + ".zip"); - Console.WriteLine(Utils.SerializeToJson(tekItem)); - Console.WriteLine(tmpFile); + Debug.WriteLine(Utils.SerializeToJson(tekItem)); + Debug.WriteLine(tmpFile); using (Stream responseStream = await httpDataService.GetTemporaryExposureKey(tekItem.Url, cancellationToken)) using (var fileStream = File.Create(tmpFile)) @@ -203,17 +203,17 @@ public async Task FetchExposureKeyBatchFilesFromServerAsync(Func CreateSubmissionAsync(IEnumerab var beforeKey = Utils.SerializeToJson(temporaryExposureKeys.ToList()); var afterKey = Utils.SerializeToJson(keys.ToList()); - Console.WriteLine($"COCOA {beforeKey}"); - Console.WriteLine($"COCOA {afterKey}"); + Debug.WriteLine($"C19R {beforeKey}"); + Debug.WriteLine($"C19R {afterKey}"); foreach (var key in keys) { if (!key.IsValid()) { - Console.WriteLine($"COCOA Invalid Key Expcetion"); + Debug.WriteLine($"C19R Invalid Key Expcetion"); throw new InvalidDataException(); } } diff --git a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs index a2877f36..55d3efeb 100644 --- a/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs +++ b/Covid19Radar/Xamarin.ExposureNotification/CallbackService.android.cs @@ -27,7 +27,7 @@ public override void OnReceive(Context context, Intent intent) } else if(action == "com.google.android.gms.exposurenotification.ACTION_EXPOSURE_NOT_FOUND") { - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackBroadcastReceiver)} ACTION_EXPOSURE_NOT_FOUND."); + Console.WriteLine($"C19R {nameof(ExposureNotificationCallbackBroadcastReceiver)} ACTION_EXPOSURE_NOT_FOUND."); } } } @@ -44,7 +44,7 @@ public static void EnqueueWork(Context context, Intent work) protected override async void OnHandleWork(Intent workIntent) { - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}"); + Console.WriteLine($"C19R {nameof(ExposureNotificationCallbackService)}"); var token = workIntent.GetStringExtra(ExposureNotificationClient.ExtraToken); var summary = await ExposureNotification.PlatformGetExposureSummaryAsync(token); @@ -55,7 +55,7 @@ Task> GetInfo() } // Invoke the custom implementation handler code with the summary info - Console.WriteLine($"COCOA {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); + Console.WriteLine($"C19R {nameof(ExposureNotificationCallbackService)}{summary?.MatchedKeyCount} Matched Key Count"); if (summary?.MatchedKeyCount > 0) { From fdb5e99693695eb074565555eba891c7406b2662 Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 21:39:48 +0900 Subject: [PATCH 7/9] =?UTF-8?q?Generate=20=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Japanese sentence generate 。 --- Covid19Radar/Covid19Radar/Resources/AppResources.ja.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Covid19Radar/Covid19Radar/Resources/AppResources.ja.resx b/Covid19Radar/Covid19Radar/Resources/AppResources.ja.resx index 8680049e..410d8862 100644 --- a/Covid19Radar/Covid19Radar/Resources/AppResources.ja.resx +++ b/Covid19Radar/Covid19Radar/Resources/AppResources.ja.resx @@ -580,7 +580,7 @@ https://covid19radarjpnprod.z11.web.core.windows.net/phone.json - 新型コロナウイルス陽性登録者と接触した可能性があります。詳細はこちら。 + 新型コロナウイルス陽性登録者と接触した可能性があります。詳細はこちら It is possible you have been in close proximity to a user who tested positive for COVID-19. Tap for more details. From 0fd648f2abec3ec41fe911b5815a5b5a1ad7db0a Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 21:46:28 +0900 Subject: [PATCH 8/9] Fix Ref --- .../Resources/AppResources.fr.resx | 178 +++++++++--------- .../ExposureNotification.ios.cs | 1 + 2 files changed, 90 insertions(+), 89 deletions(-) diff --git a/Covid19Radar/Covid19Radar/Resources/AppResources.fr.resx b/Covid19Radar/Covid19Radar/Resources/AppResources.fr.resx index 761b6f7b..de3197dc 100644 --- a/Covid19Radar/Covid19Radar/Resources/AppResources.fr.resx +++ b/Covid19Radar/Covid19Radar/Resources/AppResources.fr.resx @@ -20,7 +20,7 @@ Home Title - COVID-19Radar + COVID-19 Contact App App Name @@ -54,7 +54,7 @@ Health care jurisdiction page - Manuel + Guide d'utilisation Tab How to use @@ -98,27 +98,27 @@ Partager - Partager des informations positives et une notification anonyme à d’autres + S'enregistrer comme testé positif et notifier anonymement les autres Button NotifyOtherPage - réinitialiser + Réinitialiser 使用中止 - politique de confidentialité + Politique de confidentialité - En attente de registre + En attente d'enregistrement - Voulez-vous vraiment réinitialiser toutes les données? + Voulez-vous vraiment réinitialiser toutes les données ? Supprimer toutes les données - Tous les paramètres et données ont été supprimés. S’il vous plaît redémarrer l’application. + Tous les paramètres et données ont été supprimés. Veuillez redémarrer l’application. Retour à l’inscription @@ -127,54 +127,54 @@ Enregistrement positif - Souhaitez-vous vous inscrire positivement plus tard? + Souhaitez-vous vous inscrire comme testé positif plus tard ? - Si vous êtes positif avec la nouvelle Corona, s’il vous plaît coopérer avec l’enregistrement positif pour protéger les gens autour de vous. + Afin de protéger les gens autour de vous, merci de bien vouloir coopérer en vous enregistrant anonymement si vous êtes testé positif au COVID-19. 周りの人達を守るために匿名での陽性登録へのご協力をお願いいたします。 - Cette application est si efficace que beaucoup de gens l’installent, donc s’il vous plaît partager l’application avec les gens autour de vous. + L'efficacité de cette application s'accroît avec le nombre d'utilisateurs actifs. Merci de bien vouloir partager l’application avec les gens autour de vous. 本アプリは多くの方にお使いいただくほど効果を発揮します。 - Comment utiliser + Manuel d'utilisation 使い方 - Identification terminale + Qu'est-ce qu'un «contact rapproché» ? 接触の記録方法 - Méthode de confirmation de contact + Confirmation des contacts rapprochés 接触の確認方法 - S’il est déterminé à être infecté + Si vous êtes testé positif 感染していると判定されたら - Enregistrement stop/supprimer + Arrêter / supprimer l'enregistrement des contacts 記録の停止/削除 - Lorsque vous exécutez cette application, chaque smartphone génère et dispose d’un code de contact. De plus, cette application n’acquiert aucune information relative à des renseignements personnels tels que le numéro de téléphone et les informations de localisation. + Lorsque cette application est exécutée, chaque smartphone génère aléatoirement un code de contact. Cette application n’acquiert aucune information relative à des renseignements personnels tels que le numéro de téléphone et les informations de localisation. アプリを実行した際に、各スマートフォンで接触符号を生成して持ちます。氏名・電話番号などの個人情報やGPSなどスマートフォンの位置情報を使うことはなく、記録されることもありません。 - Conditions de contact enregistrées + Qu'est-ce qu'un contact rapproché 記録される接触の条件 - Le contact avec d’autres utilisateurs d’applications dans un rayon de 1 mètre pendant 15 minutes ou plus est enregistré comme «contact». + Deux utilisateurs de cette application se trouvant dans un rayon de 1 mètre pendant 15 minutes ou plus est enregistré comme «contact rapproché». 1メートル以内、15分以上の他のアプリユーザーとの接触は「接触」として記録されます。 - Enregistrement des coordonnées + Enregistrement des contacts rapprochés 接触情報の記録 - À ce moment-là, le code de contact de la personne contactée est enregistré dans l’application. Les coordonnées ne seront pas utilisées tant que l’un ou l’autre utilisateur n’aura pas enregistré de positif. L’historique des contacts sera effacé après 14 jours. Le code de contact change régulièrement. + Les téléphones en contact rapproché échangent leurs codes aléatoire. Ces informations ne seront pas utilisées tant qu'aucun des utilisateurs ne s'enregistre comme testé positif. L’historique des contacts sera effacé après 14 jours. N.B.: Le code change régulièrement pour protéger votre confidentialité. このとき、接触した相手の接触符号の記録をアプリに行います。どちらかの利用者が陽性の登録を行うまでは接触の情報は利用されません。接触の履歴は14日後に消去されます。 ※接触符号は定期的に変わります。 @@ -182,23 +182,23 @@ アプリの設定へ - À partir des paramètres de l’application, vous pouvez activer/désactiver bluetooth et notifications, cesser d’utiliser l’application et supprimer l’historique des contacts rapprochés. + À partir des paramètres de l’application, vous pouvez réinitialiser l’application et supprimer les données utilisateur. アプリの設定からアプリの使用中止とユーザー情報の削除を行うことができます。 - L’application vous informera, si vous étiez en contact étroit avec l’utilisateur positif COVID-19. + L’application vous enverra une notification si vous avez été en contact rapproché avec un utilisateur enregistré positif COVID-19. 接触した人の中に新型コロナウイルスの陽性登録された人がいた場合、スマートフォンにプッシュ通知が届きます。 - Vous pouvez vérifier le nombre de vos contacts proches à partir de l’écran d’accueil. + Vous pouvez vérifier le nombre de vos contacts rapprochés à partir de l’écran d’accueil. 最近の接触件数の確認へはホーム画面からも移動することができます。 - Vous pouvez consulter la liste des dates de contact rapprochées et recevoir des conseils sur ce qu’il faut faire si vous avez des symptômes de la maladie. + Vous pouvez consulter la liste des dates de contact rapprochés et recevoir des conseils sur ce qu’il faut faire si vous avez des symptômes de la maladie. 接触があった日付の一覧を確認できます。また適切な連絡先をお知らせします。 - Avertissement + Notification 通知 @@ -206,7 +206,7 @@ ホーム画面 - Si vous avez eu un contact étroit avec un utilisateur positif COVID-19 + Si vous avez eu un contact rapproché avec un utilisateur positif au COVID-19 陽性者との接触があった場合 @@ -222,15 +222,15 @@ 本アプリを用いて処理番号の登録を行います。 - Les smartphones qui étaient en contact étroit avec votre smartphone au cours des 14 derniers jours recevront des notifications. + Les smartphones qui ont été en contact rapproché avec votre smartphone au cours des 14 derniers jours recevront des notifications. あなたと14日以内に接触した人のスマホアプリに通知が届きます。(1m以内、15分以上) - Seuls les codes générés au hasard à partir du périphérique sont utilisés lors de l’envoi de notifications. Aucune information personnelle n’est utilisée. + Seuls les codes de contact générés aléatoirement à partir du téléphone sont utilisés lors de l’envoi de notifications. Aucune information personnelle n’est utilisée. 通知される情報は端末の接触符号のみです。それ以外の、氏名など個人情報や位置情報が送られることはありません。 - Inscrivez-vous ici lorsqu’il est testé positif + Enregistrez-vous ici lorsque testé positif 陽性情報の登録と他者への匿名通知へ @@ -238,7 +238,7 @@ ライセンス… - Enregistrement de contact étroit + Enregistrement de contact rapproché 接触の検出 @@ -258,35 +258,35 @@ アプリの使用中止 - Arrêter d’utiliser et supprimer les enregistrements de contact rapproché + Arrêter d’utiliser et supprimer l'historique des contacts rapprochés 使用を中止して過去14日間の接触履歴を消去 - Qu’est-ce qu’un « nt contact étroit »? + Qu’est-ce qu’un « contact rapproché » ? どのようにして接触を記録していますか? - Comment vérifier le nombre de contacts proches ? + Comment vérifier le nombre de contacts rapprochés ? 接触の有無はどのように知ることができますか? - Si vous êtes positif pour COVIDE-19 + Si vous êtes testé positif au COVID-19 新型コロナウイルスに感染していると判定されたら - Comment puis-je arrêter /supprimer l’enregistrement de contact étroit ? + Comment puis-je arrêter/supprimer l’enregistrement des contacts rapprochés ? 接触の記録を停止/情報を削除するには - Contacts étroits depuis 14 jours + Contacts rapprochés depuis 14 jours 過去14日間の接触 - Pas de contacts étroits avec les utilisateurs positifs de COVIDE-19 + Pas de contacts rapprochés avec des utilisateurs positifs au COVID-19 陽性者との接触は確認されませんでした - S’il vous plaît continuer à pratiquer « Nouveau mode de vie » recommandé par le gouvernement. + S’il vous plaît continuez à pratiquer les mesures « Nouveau mode de vie » recommandées par le gouvernement. 引き続き「新しい生活様式」の実践をよろしくお願いいたします。 @@ -294,11 +294,11 @@ アプリを周りの人に知らせる - Merci d’avoir enregistré vos résultats de test! + Merci d’avoir enregistré vos résultats de test ! 陽性のご登録をいただきありがとうございました - L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact étroit n’est enregistrée. + L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact rapproché n’est enregistrée. 登録は匿名で行われ、氏名や連絡先など個人が特定される情報を登録する必要はありません。また、接触した場所の位置情報が記録や通知されることもありません。 @@ -310,7 +310,7 @@ 規約に同意して次へ - Configuration terminée. Merci! + Configuration terminée. Merci ! ご登録いただきありがとうございました @@ -322,19 +322,19 @@ 使い方を学ぶ - Identification de périphérique + Identification du périphérique 端末の識別 - Une liste de contacts étroits avec les utilisateurs positifs de COVID-19 + Une liste de contacts rapprochés avec des utilisateurs positifs au COVID-19 陽性者との接触一覧 - Remplissez vos symptômes + Saisissez vos symptômes 症状を入力 - Informez vos symptômes par téléphone Centre de consultation + Indiquez vos symptômes par téléphone au Centre de consultation 帰国者・接触者外来に電話 @@ -342,19 +342,19 @@ - Si vous avez des symptômes COVIDÉS-19 possibles, communiquez avec les organismes de soins de santé en utilisant le formulaire ci-dessous ou par téléphone. Selon les symptômes, il vous sera conseillé de passer un test COVIDE-19. + Si vous avez des symptômes COVID-19, communiquez avec les organismes de santé en utilisant le formulaire ci-dessous ou par téléphone. Selon les symptômes, il vous sera conseillé de passer un test COVID-19. 現在の症状などを、入力フォームまたはお電話にて、ご連絡ください。内容に応じて、帰国者・接触者外来等への受診を案内します。 - S’il vous plaît prendre une capture d’écran de cet écran. On peut vous demander de le fournir pendant le diagnostic. + Veuillez prendre une capture de cet écran. On peut vous demander de le fournir pendant le diagnostic. 受診の際などに必要となる場合があるため、本画面のスクリーンショットの保存をお願いいたします。 - Nombre de contacts étroits confirmés avec les utilisateurs positifs de COVIDE-19 + Nombre de contacts rapprochés confirmés avec des utilisateurs positifs de COVID-19 陽性者との接触確認 - Contacts étroits depuis 14 jours + Contacts rapprochés depuis 14 jours 過去14日間の接触 @@ -362,7 +362,7 @@ 9:00~17:30(土・日・祝日・年末年始を除く) - COVIDE-19 Information et ressources + COVID-19 Information et ressources 新型コロナウイルス感染症対策サイト @@ -370,15 +370,15 @@ アプリに関するお問い合わせ - utilisé + en service 使用中 - Vérifier les contacts proches + Vérifier les contacts rapprochés 陽性者との接触を確認する(14日間) - Lorsqu’il est testé positif pour COVIDE-19 + Si vous êtes testé positif au COVID-19 新型コロナウイルス陽性と診断されたら @@ -410,7 +410,7 @@ 接触の記録は、暗号化され、あなたのスマートフォンの中にのみ記録され、14日後に自動的に削除されます。行政機関や第三者が暗号化された情報を利用して接触歴を把握することはありません。 - Vous pouvez arrêter d’enregistrer des contacts étroits avec d’autres utilisateurs à tout moment en modifiant les paramètres de l’application ou en supprimant l’application. + Vous pouvez arrêter d’enregistrer des contacts rapprochés avec d’autres utilisateurs à tout moment en modifiant les paramètres de l’application ou en supprimant l’application. 接触の記録はいつでも止めることができます。アプリ内の設定を無効にするか、アプリを削除してください。 @@ -418,7 +418,7 @@ 利用規約へ - TutorialPage2Description1 + À propos de la confidentialité プライバシーについて @@ -426,7 +426,7 @@ 通知をご利用いただくために - Veuillez activer les notifications à avis lorsque vous avez eu des contacts étroits avec les utilisateurs positifs de COVID-19. + Veuillez activer les notifications pour être averti lorsque vous avez eu des contacts rapprochés avec les utilisateurs positifs au COVID-19. 本アプリで接触の通知をご利用いただくために、本アプリのプッシュ通知を有効にしてください。 @@ -446,15 +446,15 @@ メニュー - Inscrire + S'enregistrer 登録する - Veuillez entrer un code de processus qui vous est délivré par le « Health Center Real-time Information-sharing System on COVID-19 (HER-SYS ». + Veuillez entrer le code de processus qui vous est délivré par le « Health Center Real-time Information-sharing System on COVID-19 (HER-SYS) ». 新型コロナウイルス感染症者等情報把握・管理支援システム(HER-SYS)から発行された処理番号を入力してください。 - Les utilisateurs qui ont été en contact étroit avec vous au cours des 14 derniers jours seront avisés. L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact étroit n’est enregistrée. + Les utilisateurs qui ont été en contact rapproché avec vous au cours des 14 derniers jours seront avisés. L’inscription est anonyme. Vous n’avez pas à entrer votre nom ou toute autre information personnelle. Aucune information concernant l’emplacement du contact rapproché n’est enregistrée. 過去14日間に本アプリであなたと接触した履歴のある人に通知が行きます。登録は匿名で行われ、氏名や連絡先など個人が特定される情報を登録する必要はありません。また、接触した場所の位置情報が記録や通知されることもありません。 @@ -466,19 +466,19 @@ 陽性情報の登録 - Suivante + Suivant 次へ - L’application reconnaît les contacts étroits entre les smartphones exécutant cette application. + L’application reconnaît les contacts rapprochés entre les smartphones exécutant cette application. 本アプリをスマートフォンに設定した人どうしの接触を記録します。 - Lorsque vous avez été testé positif pour COVID-19, vous pouvez enregistrer anonymement le résultat du test dans cette application. + Lorsque vous avez été testé positif au COVID-19, vous pouvez enregistrer anonymement le résultat du test dans cette application. 新型コロナウイルスに陽性と判定されたら本アプリに匿名で登録することができます。 - Si vous avez été en contact étroit avec un utilisateur qui a été testé positif, l’application vous informe d’une infection potentielle et vous fournit des conseils pour protéger votre santé. + Si vous avez été en contact rapproché avec un utilisateur qui a été testé positif, l’application vous informe d’une infection potentielle et vous fournit des conseils pour protéger votre santé. 最近接触した人の中に陽性登録した人がいたら、通知と適切な行動をお知らせします。 @@ -498,7 +498,7 @@ あとで設定する - Veuillez activer Bluetooth pour commencer à enregistrer des contacts étroits avec d’autres utilisateurs. + Veuillez activer le Bluetooth pour commencer à enregistrer des contacts rapprochés avec d’autres utilisateurs. 本アプリで接触検知をご利用いただくために、スマートフォンのBluetooth通信を有効にしてください。 @@ -506,11 +506,11 @@ 技術的な詳細について - Activer Bluetooth + Pour recevoir des Notifications d'exposition 接触検知をご利用いただくために - Activer Bluetooth + Pour recevoir des Notifications d'exposition 接触検知をご利用いただくために @@ -538,19 +538,19 @@ 処理番号があなたに対して発行されたものである旨の回答が行われた場合は、他の利用者の端末に、あなたの端末に記録された日次鍵が提供されます。 - Si vous avez été en contact avec vous dans les 14 jours, vous saurez que vous avez peut-être été contacté sans aucune information qui peut vous identifier personnellement. + Si vous avez été en contact rapproché avec un autre utilisateur ces derniers 14 jours, vous saurez que vous avez peut-être été contacté sans utiliser des informations qui peuvent vous identifier personnellement. 14日以内にあなたと接触の状態となったことのある方は、あなた個人を識別可能な情報がない状態で、接触した可能性がある旨を知ることができます。 - Accepter et s’inscrire + Accepter et enregistrer le résultat 同意して陽性登録する - Consentement à l’enregistrement positif + Consentement à l’enregistrement du résultat 陽性登録への同意 - Consentement à l’enregistrement positif + Consentement à l’enregistrement du résultat 陽性登録への同意 @@ -558,15 +558,15 @@ バージョン - Bluetooth est désactivé. S’il vous plaît tourner Bluetooth. + Le Bluetooth est désactivé. S’il vous plaît activez le Bluetooth. BluetoothがOffになっています。Bluetoothを有効にしてください。 - Une liste de contacts proches (au cours des 14 derniers jours) + Une liste de contacts rapprochés (au cours des 14 derniers jours) 過去14日間の接触一覧 - Dates lorsque vous étiez en contact étroit avec les utilisateurs positifs COVID-19. + Dates lorsque vous avez été en contact rapproché avec des utilisateurs positifs au COVID-19. 以下の日に陽性者との接触が確認されました。 @@ -580,11 +580,11 @@ https://covid19radarjpnprod.z11.web.core.windows.net/phone.json - Il est possible que vous ayez été à proximité d’un utilisateur qui a été testé positif pour COVID-19. Appuyez pour plus de détails. + Il est possible que vous ayez été à proximité d’un utilisateur qui a été testé positif au COVID-19. Appuyez pour plus de détails. It is possible you have been in close proximity to a user who tested positive for COVID-19. Tap for more details. - Exposition possible à COVIDE-19 + Exposition possible au COVID-19 Possible COVID-19 Exposure @@ -597,7 +597,7 @@ Informations sur cette application - Q et A pour l’utilisateur + Q and A pour l’utilisateur Nom : \r\n Contact : \r\n Contenu de l’enquête (Veuillez sélectionner une catégorie parmi les éléments suivants : 1. Fonctionnement de l’application, 2. Paramètres de l’application, 3. Utilisation de l’application (notification, etc.) ), 4. Autres \r\n Texte de l’enquête : \r\n @@ -608,7 +608,7 @@ 接触確認アプリに関するお問い合わせ - JOURS + Jours X日間 @@ -616,7 +616,7 @@ Exposure Notification機能は許諾の状態です。 - Bluetooth est désactivé. S’il vous plaît activer Bluetooth. + Le Bluetooth est désactivé. Veuillez activer le Bluetooth. BluetoothがOffになっています。Bluetoothを有効にしてください。 @@ -628,11 +628,11 @@ 利用規約に同意する必要があります。 - La notification d’exposition est restreinte. S’il vous plaît actif. + La fonction Notification d’exposition au COVID-19 n'est pas approuvée. Veuillez l'approuver via les paramètres du système d'exploitation, ou en réinstallant cette application. COVID-19接触通知機能が承認されていません。各OSから承認するか、またはアプリの再インストール後に、再承認してください。 - La notification d’exposition n’est pas prise en charge. Veuillez mettre à jour le système d’exploitation vers la dernière version. Si vous avez encore des problèmes, s’il vous plaît contactez-nous à appsupport@cov19.mhlw.go.jp. + La Notification d’exposition n’est pas prise en charge. Veuillez mettre à jour le système d’exploitation vers la dernière version. Si vous avez encore des problèmes, s’il vous plaît contactez-nous à appsupport@cov19.mhlw.go.jp. Exposure Notification機能は非対応の状態です。OSを最新版にアップデートしてください。それでも改善しなければ、appsupport@cov19.mhlw.go.jpまでお問い合わせください。 @@ -640,11 +640,11 @@ 通信に失敗しました。 - Erreur de démarrage de la notification d’exposition + Erreur au démarrage de la Notification d’Exposition Exposure Notification起動エラー - La notification d’exposition n’a pas pu démarrer. Ouvrez les paramètres du terminal, activez la notification d’exposition et activez Bluetooth. + La Notification d’Exposition n’a pas pu démarrer. Ouvrez les paramètres du terminal, activez la Notification d’Exposition et activez le Bluetooth. Exposure Notificationを起動できませんでした。端末の設定を開いて、Exposure NotificationをONにするとともに、BluetoothをONにしてください。 @@ -656,11 +656,11 @@ センターに接続できません - Voulez-vous enregistrer des informations positives? + Voulez-vous enregistrer comme étant testé positif ? 陽性情報を登録しますか? - Inscrire + S'enregistrer 登録 @@ -668,7 +668,7 @@ キャンセルしました - S’il vous plaît attendre un certain temps jusqu’à ce que l’inscription commence + Veuillez attendre un certain temps jusqu’à ce que l’inscription commence 登録開始までしばらくそのままでお待ちください @@ -684,15 +684,15 @@ 処理番号のフォーマットが一致していません - Afin d’enregistrer des enregistrements positifs, il est nécessaire d’activer l’enregistrement du journal de contact COVID-19, veuillez l’activer à partir des paramètres de l’application ou du système d’exploitation. + Afin de s’enregistrer comme testé positif, il est nécessaire d’activer l’enregistrement du journal de contact rapproché COVID-19, veuillez l’activer à partir des paramètres de l’application ou du système d’exploitation. 陽性記録の登録を行う為にCOVID-19接触のログ記録を有効にする必要があります、アプリかOSの設定から有効にしてください。 - Activer la journalisation des contacts COVIDE-19 + Activer la journalisation des contacts rapprochés COVID-19 COVID-19接触のログ記録を有効にしてください - Le nombre d’enregistrements a atteint la limite supérieure. Application de sortie + Le nombre d’enregistrements a atteint la limite maximale. Sortie de l'application. 登録回数上限になりました。アプリケーションを終了します diff --git a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs index 11ff9c5a..5bd70414 100644 --- a/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs +++ b/Covid19Radar/Xamarin.ExposureNotification/ExposureNotification.ios.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; From df58dd69437313e6c9b5707deb4809f3ea163c64 Mon Sep 17 00:00:00 2001 From: Kazumi Hirose Date: Sun, 28 Jun 2020 21:48:26 +0900 Subject: [PATCH 9/9] Fix Ref 2 , Wahahaha Sorry orz --- .../ViewModels/HomePage/ContactedNotifyPageViewModel.cs | 1 + .../Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs b/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs index 3049cdec..9792e533 100644 --- a/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs +++ b/Covid19Radar/Covid19Radar/ViewModels/HomePage/ContactedNotifyPageViewModel.cs @@ -8,6 +8,7 @@ using System; using ImTools; using Acr.UserDialogs; +using System.Diagnostics; namespace Covid19Radar.ViewModels { diff --git a/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs b/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs index 98ef2ea6..20729560 100644 --- a/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs +++ b/Covid19Radar/Covid19Radar/ViewModels/HomePage/HomePageViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Covid19Radar.Common; using Covid19Radar.Model; using Covid19Radar.Resources;