Merge branch 'master' into feature-weather

here
Andreas Shimokawa 2016-12-30 00:10:54 +01:00
commit b045d5ac26
19 changed files with 488 additions and 200 deletions

View File

@ -1,9 +1,15 @@
###Changelog
####Version 0.16.0
* New device: ZeBand
* ZeBand: Initial experimental support
* Pebble 2: Fix Pebble Classic FW 3.x app variant being priorized over native Pebble 2 app variant
* New devices: HPlus (e.g. Zeblaze ZeBand), contributed by João Paulo Barraca
* ZeBand: Initial support: notifications, heart rate, sleep monitoring, user configuration, date+time
* Pebble 2: Fix Pebble Classic FW 3.x app variant being prioritized over native Pebble 2 app variant
* Charts (Live Activity): Fix axis labels color in dark theme
* Mi Band: Fix ginormous step count when using Live Activity
* Mi Band: Improved performance during activity sync
* Mi Band 2: Fix activity data missing after doing manual hr measurements or live activity
* Support sharing firmwares/watchapps/watchfaces to Gadgetbridge
* Support for the "Subsonic" music player (#474)
####Version 0.15.2
* Mi Band: Fix crash with unknown notification sources

View File

@ -2,7 +2,7 @@
names ()
{
echo -e "\n exit;\n**Contributors (sorted by number of commits):**\n";
git log --all --format='%aN:%aE' | sed 's/@users.github.com/@users.noreply.github.com/g' | awk 'BEGIN{FS=":"}{ct[$2]+=1;if (length($1) > length(e[$2])) {e[$2]=$1}}END{for (i in e) { n[e[i]]=i;c[e[i]]+=ct[i] }; for (a in n) print c[a]"\t* "a" <"n[a]">";}' | sort -n -r | cut -f 2-
git log --format='%aN:%aE' origin/master | sed 's/@users.github.com/@users.noreply.github.com/g' | awk 'BEGIN{FS=":"}{ct[$2]+=1;if (length($1) > length(e[$2])) {e[$2]=$1}}END{for (i in e) { n[e[i]]=i;c[e[i]]+=ct[i] }; for (a in n) print c[a]"\t* "a" <"n[a]">";}' | sort -n -r | cut -f 2-
}
quine ()
{
@ -26,15 +26,17 @@
* Carsten Pfeiffer <cpfeiffer@users.noreply.github.com>
* Daniele Gobbetti <daniele+github@gobbetti.name>
* Julien Pivotto <roidelapluie@inuits.eu>
* João Paulo Barraca <jpbarraca@gmail.com>
* Steffen Liebergeld <perl@gmx.org>
* Lem Dulfo <lemuel.dulfo@gmail.com>
* Sergey Trofimov <sarg@sarg.org.ru>
* JohnnySun <bmy001@gmail.com>
* Uwe Hermann <uwe@hermann-uwe.de>
* Gergely Peidl <gergely@peidl.net>
* 0nse <0nse@users.noreply.github.com>
* Gergely Peidl <gergely@peidl.net>
* Christian Fischer <sw-dev@computerlyrik.de>
* Normano64 <per.bergqwist@gmail.com>
* 6arms1leg <m.brnsfld@googlemail.com>
* Ⲇⲁⲛⲓ Φi <daniphii@outlook.com>
* xzovy <caleb@caleb-cooper.net>
* xphnx <xphnx@users.noreply.github.com>
@ -56,7 +58,6 @@
* atkyritsis <at.kyritsis@gmail.com>
* andre <andre.buesgen@yahoo.de>
* Alexey Afanasev <avafanasiev@gmail.com>
* 6arms1leg <m.brnsfld@googlemail.com>
And all the Transifex translators, which I cannot automatically list, at the moment.

View File

@ -20,6 +20,7 @@ need to create an account and transmit any of your data to the vendor's servers.
* Mi Band 2
* Vibratissimo (experimental)
* Liveview
* HPlus Devices (e.g. ZeBand)
## Features (Pebble)

View File

@ -191,6 +191,15 @@
<data android:mimeType="application/zip" />
<data android:mimeType="application/x-zip-compressed" />
</intent-filter>
<!-- to receive files from the "share" intent -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<service

View File

@ -152,6 +152,9 @@ public class FwAppInstallerActivity extends GBActivity implements InstallActivit
});
uri = getIntent().getData();
if (uri == null) { //for "share" intent
uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
}
installHandler = findInstallHandlerFor(uri);
if (installHandler == null) {
setInfoText(getString(R.string.installer_activity_unable_to_find_handler));

View File

@ -15,6 +15,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
/**
* Also see Mi1SFirmwareInfo.
@ -26,12 +27,13 @@ public abstract class AbstractMiBandFWHelper {
private final byte[] fw;
public AbstractMiBandFWHelper(Uri uri, Context context) throws IOException {
UriHelper uriHelper = UriHelper.get(uri, context);
String pebblePattern = ".*\\.(pbw|pbz|pbl)";
if (uri.getPath().matches(pebblePattern)) {
if (uriHelper.getFileName().matches(pebblePattern)) {
throw new IOException("Firmware has a filename that looks like a Pebble app/firmware.");
}
try (InputStream in = new BufferedInputStream(context.getContentResolver().openInputStream(uri))) {
try (InputStream in = new BufferedInputStream(uriHelper.openInputStream())) {
this.fw = FileUtils.readAll(in, 1024 * 1024); // 1 MB
determineFirmwareInfo(fw);
} catch (IOException ex) {

View File

@ -60,6 +60,10 @@ public class PBWInstallHandler implements InstallHandler {
installActivity.setInfoText("file not found");
installActivity.setInstallEnabled(false);
return;
} catch (IOException e) {
installActivity.setInfoText("error reading file");
installActivity.setInstallEnabled(false);
return;
}
if (!mPBWReader.isValid()) {
@ -168,18 +172,22 @@ public class PBWInstallHandler implements InstallHandler {
}
InputStream jsConfigFile = mPBWReader.getInputStreamFile("pebble-js-app.js");
if (jsConfigFile != null) {
outputFile = new File(destDir, app.getUUID().toString() + "_config.js");
try {
outputFile = new File(destDir, app.getUUID().toString() + "_config.js");
FileUtils.copyStreamToFile(jsConfigFile, outputFile);
} catch (IOException e) {
LOG.error("Failed to open output file: " + e.getMessage(), e);
} finally {
try {
jsConfigFile.close();
} catch (IOException e) {
}
}
}
}
@Override
public boolean isValid() {
// always pretend it is valid, as we can't know yet about hw/fw version
return true;

View File

@ -1,6 +1,5 @@
package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
@ -9,9 +8,7 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@ -26,6 +23,7 @@ import java.util.zip.ZipInputStream;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol;
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
public class PBWReader {
private static final Logger LOG = LoggerFactory.getLogger(PBWReader.class);
@ -45,8 +43,7 @@ public class PBWReader {
fwFileTypesMap.put("resources", PebbleProtocol.PUTBYTES_TYPE_SYSRESOURCES);
}
private final Uri uri;
private final ContentResolver cr;
private final UriHelper uriHelper;
private GBDeviceApp app;
private ArrayList<PebbleInstallable> pebbleInstallables = null;
private boolean isFirmware = false;
@ -60,105 +57,45 @@ public class PBWReader {
private JSONObject mAppKeys = null;
public PBWReader(Uri uri, Context context, String platform) throws FileNotFoundException {
this.uri = uri;
cr = context.getContentResolver();
public PBWReader(Uri uri, Context context, String platform) throws IOException {
uriHelper = UriHelper.get(uri, context);
InputStream fin = new BufferedInputStream(cr.openInputStream(uri));
if (uri.toString().endsWith(".pbl")) {
if (uriHelper.getFileName().endsWith(".pbl")) {
STM32CRC stm32crc = new STM32CRC();
try {
try (InputStream fin = uriHelper.openInputStream()) {
byte[] buf = new byte[2000];
while (fin.available() > 0) {
int count = fin.read(buf);
stm32crc.addData(buf, count);
}
fin.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
int crc = stm32crc.getResult();
// language file
app = new GBDeviceApp(UUID.randomUUID(), "Language File", "unknown", "unknown", GBDeviceApp.Type.UNKNOWN);
File f = new File(uri.getPath());
pebbleInstallables = new ArrayList<>();
pebbleInstallables.add(new PebbleInstallable("lang", (int) f.length(), crc, PebbleProtocol.PUTBYTES_TYPE_FILE));
pebbleInstallables.add(new PebbleInstallable("lang", (int) uriHelper.getFileSize(), crc, PebbleProtocol.PUTBYTES_TYPE_FILE));
isValid = true;
isLanguage = true;
return;
}
String platformDir = "";
if (!uri.toString().endsWith(".pbz")) {
/*
* for aplite and basalt it is possible to install 2.x apps which have no subfolder
* we still prefer the subfolders if present.
* chalk needs to be its subfolder
*/
String[] platformDirs;
switch (platform) {
case "basalt":
platformDirs = new String[]{"basalt/"};
break;
case "chalk":
platformDirs = new String[]{"chalk/"};
break;
case "diorite":
platformDirs = new String[]{"diorite/", "aplite/"};
break;
case "emery":
platformDirs = new String[]{"emery/", "basalt/"};
break;
default:
platformDirs = new String[]{"aplite/"};
}
for (String dir : platformDirs) {
InputStream afin = new BufferedInputStream(cr.openInputStream(uri));
ZipInputStream zis = new ZipInputStream(afin);
ZipEntry ze;
boolean found = false;
try {
while ((ze = zis.getNextEntry()) != null) {
if (ze.getName().startsWith(dir)) {
platformDir = dir;
found = true;
break;
}
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
}
if (found) {
break;
}
}
if (platform.equals("chalk") && platformDir.equals("")) {
return;
}
String platformDir = determinePlatformDir(uriHelper, platform);
if (platform.equals("chalk") && platformDir.equals("")) {
return;
}
LOG.info("using platformdir: '" + platformDir + "'");
String appName = null;
String appCreator = null;
String appVersion = null;
UUID appUUID = null;
ZipInputStream zis = new ZipInputStream(fin);
ZipEntry ze;
pebbleInstallables = new ArrayList<>();
byte[] buffer = new byte[1024];
int count;
try {
try (ZipInputStream zis = new ZipInputStream(uriHelper.openInputStream())) {
while ((ze = zis.getNextEntry()) != null) {
String fileName = ze.getName();
if (fileName.equals(platformDir + "manifest.json")) {
@ -254,7 +191,6 @@ public class PBWReader {
// more follows but, not interesting for us
}
}
zis.close();
if (appUUID != null && appName != null && appCreator != null && appVersion != null) {
GBDeviceApp.Type appType = GBDeviceApp.Type.APP_GENERIC;
@ -265,11 +201,58 @@ public class PBWReader {
}
app = new GBDeviceApp(appUUID, appName, appCreator, appVersion, appType);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Determines the platform dir to use for the given uri and platform.
* @param uriHelper
* @param platform
* @return the platform dir to use
* @throws IOException
*/
private String determinePlatformDir(UriHelper uriHelper, String platform) throws IOException {
String platformDir = "";
if (uriHelper.getFileName().endsWith(".pbz")) {
return platformDir;
}
/*
* for aplite and basalt it is possible to install 2.x apps which have no subfolder
* we still prefer the subfolders if present.
* chalk needs to be its subfolder
*/
String[] platformDirs;
switch (platform) {
case "basalt":
platformDirs = new String[]{"basalt/"};
break;
case "chalk":
platformDirs = new String[]{"chalk/"};
break;
case "diorite":
platformDirs = new String[]{"diorite/", "aplite/"};
break;
case "emery":
platformDirs = new String[]{"emery/", "basalt/"};
break;
default:
platformDirs = new String[]{"aplite/"};
}
for (String dir : platformDirs) {
try (ZipInputStream zis = new ZipInputStream(uriHelper.openInputStream())) {
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null) {
if (ze.getName().startsWith(dir)) {
return dir;
}
}
}
}
return platformDir;
}
public boolean isFirmware() {
return isFirmware;
}
@ -287,28 +270,29 @@ public class PBWReader {
}
public InputStream getInputStreamFile(String filename) {
InputStream fin;
try {
fin = new BufferedInputStream(cr.openInputStream(uri));
if (isLanguage) {
return fin;
if (isLanguage) {
try {
return uriHelper.openInputStream();
} catch (FileNotFoundException e) {
LOG.warn("file not found: " + e);
return null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
ZipInputStream zis = new ZipInputStream(fin);
ZipInputStream zis = null;
ZipEntry ze;
try {
zis = new ZipInputStream(uriHelper.openInputStream());
while ((ze = zis.getNextEntry()) != null) {
if (ze.getName().equals(filename)) {
return zis;
return zis; // return WITHOUT closing the stream!
}
}
zis.close();
} catch (Throwable e) {
try {
zis.close();
if (zis != null) {
zis.close();
}
} catch (IOException e1) {
// ignore
}

View File

@ -2,6 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.widget.Toast;
import org.slf4j.Logger;
@ -23,7 +25,6 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
@ -73,7 +74,7 @@ public class FetchActivityOperation extends AbstractMiBand2Operation {
builder.notify(characteristicFetch, true);
BluetoothGattCharacteristic characteristicActivityData = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_5_ACTIVITY_DATA);
GregorianCalendar sinceWhen = getLastSuccessfulSynchronizedTime();
GregorianCalendar sinceWhen = getLastSuccessfulSyncTime();
builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, 0x01 }, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES)));
builder.add(new WaitAction(1000)); // TODO: actually wait for the success-reply
builder.notify(characteristicActivityData, true);
@ -81,26 +82,28 @@ public class FetchActivityOperation extends AbstractMiBand2Operation {
builder.queue(getQueue());
}
private GregorianCalendar getLastSuccessfulSynchronizedTime() {
try (DBHandler dbHandler = GBApplication.acquireDB()) {
DaoSession session = dbHandler.getDaoSession();
SampleProvider<MiBandActivitySample> sampleProvider = new MiBand2SampleProvider(getDevice(), session);
MiBandActivitySample sample = sampleProvider.getLatestActivitySample();
if (sample != null) {
int timestamp = sample.getTimestamp();
GregorianCalendar calendar = BLETypeConversions.createCalendar();
calendar.setTimeInMillis((long) timestamp * 1000);
return calendar;
}
} catch (Exception ex) {
LOG.error("Error querying for latest activity sample, synchronizing the last 10 days", ex);
private GregorianCalendar getLastSuccessfulSyncTime() {
long timeStampMillis = GBApplication.getPrefs().getLong(getLastSyncTimeKey(), 0);
if (timeStampMillis != 0) {
GregorianCalendar calendar = BLETypeConversions.createCalendar();
calendar.setTimeInMillis(timeStampMillis);
return calendar;
}
GregorianCalendar calendar = BLETypeConversions.createCalendar();
calendar.add(Calendar.DAY_OF_MONTH, -10);
return calendar;
}
private void saveLastSyncTimestamp(@NonNull GregorianCalendar timestamp) {
SharedPreferences.Editor editor = GBApplication.getPrefs().getPreferences().edit();
editor.putLong(getLastSyncTimeKey(), timestamp.getTimeInMillis());
editor.apply();
}
private String getLastSyncTimeKey() {
return getDevice().getAddress() + "_" + "lastSyncTimeMillis";
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
@ -147,6 +150,7 @@ public class FetchActivityOperation extends AbstractMiBand2Operation {
}
sampleProvider.addGBActivitySamples(samples.toArray(new MiBandActivitySample[0]));
saveLastSyncTimestamp(timestamp);
LOG.info("Mi2 activity data: last sample timestamp: " + DateTimeUtils.formatDateTime(timestamp.getTime()));
} catch (Exception ex) {

View File

@ -623,7 +623,10 @@ class PebbleIoThread extends GBDeviceIoThread {
try {
mPBWReader = new PBWReader(uri, getContext(), platformName);
} catch (FileNotFoundException e) {
LOG.warn("file not found!");
LOG.warn("file not found: " + e.getMessage(), e);
return;
} catch (IOException e) {
LOG.warn("unable to read file: " + e.getMessage(), e);
return;
}

View File

@ -17,6 +17,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@ -46,14 +47,20 @@ public class FileUtils {
}
}
/**
* Copies the contents of the given input stream to the destination file.
* @param inputStream the contents to write. Note: the caller has to close the input stream!
* @param destFile the file to write to
* @throws IOException
*/
public static void copyStreamToFile(InputStream inputStream, File destFile) throws IOException {
FileOutputStream fout = new FileOutputStream(destFile);
byte[] buf = new byte[4096];
while (inputStream.available() > 0) {
int bytes = inputStream.read(buf);
fout.write(buf, 0, bytes);
try (FileOutputStream fout = new FileOutputStream(destFile)) {
byte[] buf = new byte[4096];
while (inputStream.available() > 0) {
int bytes = inputStream.read(buf);
fout.write(buf, 0, bytes);
}
}
fout.close();
}
public static void copyURItoFile(Context ctx, Uri uri, File destFile) throws IOException {
@ -62,29 +69,47 @@ public class FileUtils {
}
ContentResolver cr = ctx.getContentResolver();
InputStream fin;
try {
fin = new BufferedInputStream(cr.openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
InputStream in = cr.openInputStream(uri);
if (in == null) {
throw new IOException("unable to open input stream: " + uri);
}
try (InputStream fin = new BufferedInputStream(in)) {
copyStreamToFile(fin, destFile);
fin.close();
}
copyStreamToFile(fin, destFile);
fin.close();
}
/**
* Returns the textual contents of the given file. The contents is expected to be
* in UTF-8 encoding.
* @param file the file to read
* @return the file contents as a newline-delimited string
* @throws IOException
* @see #getStringFromFile(File, String)
*/
public static String getStringFromFile(File file) throws IOException {
return getStringFromFile(file, StandardCharsets.UTF_8.name());
}
/**
* Returns the textual contents of the given file. The contents will be interpreted using the
* given encoding.
* @param file the file to read
* @return the file contents as a newline-delimited string
* @throws IOException
* @see #getStringFromFile(File)
*/
public static String getStringFromFile(File file, String encoding) throws IOException {
FileInputStream fin = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fin));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(fin, encoding))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
}
reader.close();
fin.close();
return sb.toString();
}
/**

View File

@ -0,0 +1,150 @@
package nodomain.freeyourgadget.gadgetbridge.util;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class UriHelper {
@NonNull
private final Uri uri;
@NonNull
private final Context context;
private String fileName;
private long fileSize;
@Nullable
private File file;
private UriHelper(@NonNull Uri uri, @NonNull Context context) {
this.uri = uri;
this.context = context;
}
/**
* Returns the uri as passed to #get(Uri, Context)
*/
@NonNull
public Uri getUri() {
return uri;
}
/**
* Returns the context as passed to #get(Uri, Context)
*/
@NonNull
public Context getContext() {
return context;
}
/**
* Returns an immutable helper to access the given Uri. In case the uri cannot be read/resolved
* an IOException is thrown.
* @param uri the uri to access
* @param context the context for accessing uris
* @throws IOException
*/
@NonNull
public static UriHelper get(@NonNull Uri uri, @NonNull Context context) throws FileNotFoundException, IOException {
UriHelper helper = new UriHelper(uri, context);
helper.resolveMetadata();
return helper;
}
/**
* Opens a stream to read the contents of the uri.
* Note: the caller has to close the stream after usage.
* Every invocation of this method will open a new stream.
* @throws FileNotFoundException
*/
@NonNull
public InputStream openInputStream() throws FileNotFoundException {
ContentResolver cr = context.getContentResolver();
InputStream inputStream = cr.openInputStream(uri);
if (inputStream != null) {
return new BufferedInputStream(inputStream);
}
throw new FileNotFoundException("Unable to open inputstream for " + uri);
}
/**
* Returns the content length (file size) in bytes
*/
public long getFileSize() {
return fileSize;
}
/**
* Returns the name of the file referenced by the Uri. Does not include the path.
*/
@NonNull
public String getFileName() {
return fileName;
}
/**
* Returns the file behind the uri, or null in case it is not a file:/ Uri.
* @return the file or null
*/
@Nullable
public File getFile() {
return file;
}
private void resolveMetadata() throws IOException {
String uriScheme = uri.getScheme();
if (ContentResolver.SCHEME_CONTENT.equals(uriScheme)) {
Cursor cursor = context.getContentResolver().query(
uri,
new String[] {
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.SIZE
}, null, null, null);
if (cursor == null) {
throw new IOException("Unable to query metadata for: " + uri);
}
if (cursor.moveToFirst()) {
int name_index = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
if (name_index == -1) {
throw new IOException("Unable to retrieve name for: " + uri);
}
int size_index = cursor.getColumnIndex(MediaStore.MediaColumns.SIZE);
if (size_index == -1) {
throw new IOException("Unable to retrieve size for: " + uri);
}
try {
fileName = cursor.getString(name_index);
if (fileName == null) {
throw new IOException("Unable to retrieve name for: " + uri);
}
fileSize = cursor.getLong(size_index);
if (fileSize < 0) {
throw new IOException("Unable to retrieve size for: " + uri);
}
} catch (Exception ex) {
throw new IOException("Unable to retrieve metadata for: " + uri + ": " + ex.getMessage());
}
}
} else if (ContentResolver.SCHEME_FILE.equals(uriScheme)) {
file = new File(uri.getPath());
if (!file.exists()) {
throw new FileNotFoundException("Does not exist: " + file);
}
fileName = file.getName();
fileSize = file.length();
} else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uriScheme)) {
// we could actually read it, but I don't see how we can determine the file size
throw new IOException("Unsupported scheme for uri: " + uri);
} else {
throw new IOException("Unsupported scheme for uri: " + uri);
}
}
}

View File

@ -6,12 +6,13 @@
<string name="action_debug">Déboguer</string>
<string name="action_quit">Quitter</string>
<string name="controlcenter_fetch_activity_data">Synchroniser</string>
<string name="controlcenter_start_sleepmonitor">Moniteur de sommeil (ALPHA)</string>
<string name="controlcenter_find_device">Trouver l\'appareil</string>
<string name="controlcenter_start_sleepmonitor">Suivi du sommeil (ALPHA)</string>
<string name="controlcenter_find_device">Retrouver un appareil perdu...</string>
<string name="controlcenter_take_screenshot">Prendre une capture d\'écran</string>
<string name="controlcenter_disconnect">Déconnexion</string>
<string name="controlcenter_delete_device">Supprimer l\'appareil</string>
<string name="controlcenter_delete_device_name">Supprimer %1$s</string>
<string name="controlcenter_delete_device">Supprimer lappareil</string>
<string name="controlcenter_delete_device_name">Supprimer %1$s</string>
<string name="controlcenter_delete_device_dialogmessage">Ceci va supprimer lappareil et toutes les données associées !</string>
<string name="title_activity_debug">Déboguer</string>
<!--Strings related to AppManager-->
<string name="title_activity_appmanager">Gestionnaire d\'application</string>
@ -21,8 +22,11 @@
<string name="appmananger_app_delete">Supprimer</string>
<string name="appmananger_app_delete_cache">Supprimer et effacer du cache</string>
<string name="appmananger_app_reinstall">Réinstaller</string>
<string name="appmanager_app_openinstore">Rechercher dans le magasin dapplication Pebble</string>
<string name="appmanager_health_activate">Activer</string>
<string name="appmanager_health_deactivate">Désactiver</string>
<string name="appmanager_hrm_activate">Activer la mesure du rythme cardiaque</string>
<string name="appmanager_hrm_deactivate">Désactiver la mesure du rythme cardiaque</string>
<string name="app_configure">Configurer</string>
<string name="app_move_to_top">Haut de page </string>
<!--Strings related to AppBlacklist-->
@ -32,7 +36,7 @@
<string name="fw_upgrade_notice">Vous êtes sur le point d\'installer le micrologiciel %s à la place de celui qui est actuellement sur votre Mi Band.</string>
<string name="fw_multi_upgrade_notice">Vous êtes sur le point d\'installer les micrologiciels %1$s et %2$s à la place de ceux qui sont actuellement sur votre Mi Band.</string>
<string name="miband_firmware_known">Ce micrologiciel a été testé et est connu pour être compatible avec Gadgetbridge.</string>
<string name="miband_firmware_unknown_warning">Ce micrologiciel n\'a pas été testé et peut ne pas être compatible avec Gadgetbridge.\n\nIl n\'est pas conseillé de flasher votre Mi Band.</string>
<string name="miband_firmware_unknown_warning">Ce micrologiciel n\'a pas été testé et peut ne pas être compatible avec Gadgetbridge.\n\nIl n\'est pas conseillé de le flasher sur votre Mi Band.</string>
<string name="miband_firmware_suggest_whitelist">Si vous désirez continuer et que tout fonctionne correctement par la suite, SVP informez-en les développeurs de Gadgetbridge pour demander l\'ajout de ce micrologiciel à leur liste: %s</string>
<!--Strings related to Settings-->
<string name="title_activity_settings">Paramètres</string>
@ -51,47 +55,53 @@
<string name="pref_header_notifications">Notifications</string>
<string name="pref_title_notifications_repetitions">Répétitions</string>
<string name="pref_title_notifications_call">Appels téléphoniques</string>
<string name="pref_title_notifications_sms">SMS</string>
<string name="pref_title_notifications_sms">Textos</string>
<string name="pref_title_notifications_k9mail">K9-Mail</string>
<string name="pref_title_notifications_pebblemsg">Messages Pebble</string>
<string name="pref_summary_notifications_pebblemsg">Support des applications qui envoient des notification à Pebble par PebbleKit.</string>
<string name="pref_title_notifications_generic">Support des notifications génériques</string>
<string name="pref_title_whenscreenon">... y compris quand l\'écran est allumé</string>
<string name="pref_title_notification_filter">Ne Pas Déranger</string>
<string name="pref_summary_notification_filter">Arrêter lenvoie des Notification non-désirée en mode Ne Pas Déranger.</string>
<string name="pref_summary_notification_filter">Arrêter lenvoi des notifications non-désirées en mode Ne Pas Déranger.</string>
<string name="always">toujours</string>
<string name="when_screen_off">quand l\'écran est éteint</string>
<string name="never">jamais</string>
<string name="pref_blacklist">Applications bloquées</string>
<string name="pref_header_cannned_messages">Modèles de messages</string>
<string name="pref_title_canned_replies">Réponses</string>
<string name="pref_title_canned_reply_suffix">Suffixe commun</string>
<string name="pref_title_canned_reply_suffix">Suffixe fréquent</string>
<string name="pref_title_canned_messages_dismisscall">Raccrocher</string>
<string name="pref_title_canned_messages_set">Mise à jour Pebble</string>
<string name="pref_header_development">Options développeur</string>
<string name="pref_title_development_miaddr">Adresse Mi Band</string>
<string name="pref_title_pebble_settings">Paramètres Pebble</string>
<string name="pref_header_activitytrackers">Traqueur d\'activité</string>
<string name="pref_header_activitytrackers">Traqueurs d\'activité</string>
<string name="pref_title_pebble_activitytracker">Traqueur d\'activité préféré</string>
<string name="pref_title_pebble_sync_health">Synchroniser Pebble Health</string>
<string name="pref_title_pebble_sync_misfit">Synchroniser Misfit</string>
<string name="pref_title_pebble_sync_morpheuz">Synchroniser Morpheuz</string>
<string name="pref_title_enable_pebblekit">Permettre l\'accès d\'applications tierces Android</string>
<string name="pref_title_enable_pebblekit">Permettre l\'accès aux applications tierces Android</string>
<string name="pref_summary_enable_pebblekit">Activer le support expérimental pour les applications Android utilisant PebbleKit</string>
<string name="pref_title_sunrise_sunset">Lever et coucher de soleil</string>
<string name="pref_summary_sunrise_sunset">Envoyer heures de lever et coucher du soleil dans la timeline Pebble en fonction de l\'emplacement</string>
<string name="pref_summary_sunrise_sunset">Envoyer les heures de lever et coucher du soleil dans lhistorique Pebble en fonction de l\'emplacement</string>
<string name="pref_header_location">Emplacement</string>
<string name="pref_title_location_aquire">Obtenir l\'emplacement</string>
<string name="pref_title_location_latitude">Latitude</string>
<string name="pref_title_location_longitude">Longitude</string>
<string name="pref_title_location_keep_uptodate">Garder l\'emplacement à jour</string>
<string name="pref_summary_location_keep_uptodate">Tenter d\'obtenir la localisation pendant la course à pied, utiliser la localisation enregistré en cas de problème.</string>
<string name="toast_enable_networklocationprovider">Activez la localisation réseau s\'il vous plaît</string>
<string name="pref_title_location_keep_uptodate">Garder lemplacement à jour</string>
<string name="pref_summary_location_keep_uptodate">Essayer de garder la localisation à jour pendant le fonctionnement, sinon utiliser lemplacement enregistré.</string>
<string name="toast_enable_networklocationprovider">Veuillez activer la localisation réseau</string>
<string name="toast_aqurired_networklocation">Emplacement obtenu</string>
<string name="pref_title_pebble_forceprotocol">Protocole des notifications en vigueur</string>
<string name="pref_title_pebble_forceprotocol">Forcer le protocole de notification</string>
<string name="pref_summary_pebble_forceprotocol">Cette option force l\'utilisation du plus récent protocole de notification qui dépend de la version du micrologiciel. ACTIVEZ-LA UNIQUEMENT SI VOUS SAVEZ CE QUE VOUS FAITES!</string>
<string name="pref_title_pebble_forceuntested">Activer les fonctionnalités non-testées</string>
<string name="pref_summary_pebble_forceuntested">Activer les fonctionnalités non-testées. ACTIVEZ UNIQUEMENT SI VOUS SAVEZ CE QUE VOUS FAITES!</string>
<string name="pref_title_pebble_forcele">Toujours préférer le BLE</string>
<string name="pref_summary_pebble_forcele">Utiliser le support expérimental du LE pour toutes les Pebble au lieu du Bluetooth classique ; cela requiert lappairage d\'une \"Pebble LE\" après quune non-LE ai déjà été connectée</string>
<string name="pref_title_pebble_mtu_limit">Limite du GATT MTU de Pebble 2/LE</string>
<string name="pref_summary_pebble_mtu_limit">Si votre Pebble 2/LE ne fonctionne pas correctement, essayez d\'activer cette option pour limiter le MTU (plage valide 20-512)</string>
<string name="pref_title_pebble_enable_applogs">Activer les logs des Watch App</string>
<string name="pref_summary_pebble_enable_applogs">Ceci permettra à Gadgetbridge de conserver les logs des Watch App (requiert une reconnexion)</string>
<string name="pref_title_pebble_reconnect_attempts">Tentatives de reconnexion</string>
<string name="not_connected">non connecté</string>
<string name="connecting">connexion en cours</string>
@ -106,29 +116,33 @@
<string name="bluetooth_is_not_supported_">Le Bluetooth n\'est pas supporté.</string>
<string name="bluetooth_is_disabled_">Le Bluetooth est désactivé.</string>
<string name="tap_connected_device_for_app_mananger">Cliquez sur l\'appareil pour ouvrir le gestionnaire d\'application</string>
<string name="tap_connected_device_for_activity">Cliquez sur l\'appareil pour ouvrir l\'activité</string>
<string name="tap_connected_device_for_activity">Cliquez sur l\'appareil pour ouvrir le gestionnaire dactivité</string>
<string name="tap_connected_device_for_vibration">Cliquez sur connecter pour envoyer une vibration</string>
<string name="tap_a_device_to_connect">Tapotter sur le périphérique pour le connecter.</string>
<string name="cannot_connect_bt_address_invalid_">Connexion impossible. Ladresse Bluetooth est-elle invalide? </string>
<string name="cannot_connect_bt_address_invalid_">Connexion impossible. Ladresse Bluetooth est-elle valide? </string>
<string name="gadgetbridge_running">Gadgetbridge est en fonctionnement</string>
<string name="installing_binary_d_d">Installation du binaire %1$d/%2$d</string>
<string name="installation_failed_">échec d\'installation!</string>
<string name="installation_successful">Installation réalisé</string>
<string name="installing_binary_d_d">Installation du fichier %1$d/%2$d</string>
<string name="installation_failed_">échec de l\'installation !</string>
<string name="installation_successful">Installation réalisée avec succès</string>
<string name="firmware_install_warning">VOUS TENTEZ D\'INSTALLER UN MICROLOGICIEL, PROCÉDEZ À VOS PROPRES RISQUES.\n\n\nCe micrologiciel est pour la version de matériel: %s</string>
<string name="app_install_info">Vous êtes sur le point d\'installer l\'application suivante:\n\n\n%1$s Version %2$s par %3$s\n</string>
<string name="n_a">N.D.</string>
<string name="initialized">Initialisé</string>
<string name="appversion_by_creator">%1$s par %2$s</string>
<string name="title_activity_discovery">Découvrir les appareils</string>
<string name="discovery_stop_scanning">Arrêter le balayage</string>
<string name="discovery_start_scanning">Démarrer le balayage</string>
<string name="title_activity_discovery">Scanner les appareils</string>
<string name="discovery_stop_scanning">Arrêter le scan</string>
<string name="discovery_start_scanning">Démarrer le scan</string>
<string name="action_discover">Connecter un nouvel appareil</string>
<string name="device_with_rssi">%1$s (%2$s)</string>
<string name="title_activity_android_pairing">Coupler l\'appareil</string>
<string name="android_pairing_hint">Utiliser le couplement Bluetooth d\'Android pour coupler l\'appareil</string>
<string name="title_activity_mi_band_pairing">Coupler votre Mi Band</string>
<string name="pairing">Coupler avec %s...</string>
<string name="message_cannot_pair_no_mac">Aucune adresse mac fournie, ne peut être couplé</string>
<string name="title_activity_android_pairing">Appairer l\'appareil</string>
<string name="android_pairing_hint">Utiliser lappairage Bluetooth d\'Android pour appairer l\'appareil</string>
<string name="title_activity_mi_band_pairing">Appairer votre Mi Band</string>
<string name="pairing">Appairage avec %s...</string>
<string name="pairing_creating_bond_with">Création dun lien avec %1$s (%2$s)</string>
<string name="pairing_unable_to_pair_with">Impossible se sappairer avec %1$s (%2$s)</string>
<string name="pairing_in_progress">Création du lien en cours : %1$s (%2$s)</string>
<string name="pairing_already_bonded">Déjà lié avec %1$s (%2$s), connexion...</string>
<string name="message_cannot_pair_no_mac">Aucune adresse MAC fournie, ne peut être appairé</string>
<string name="preferences_category_device_specific_settings">Paramètres spécifiques à l\'appareil </string>
<string name="preferences_miband_settings">Paramètres Mi Band</string>
<string name="male">Homme</string>
@ -139,7 +153,7 @@
<string name="miband_pairing_using_dummy_userdata">Aucune donnée utilisateur valide fournie, utilisation de données fictives pour le moment</string>
<string name="miband_pairing_tap_hint">Quand votre Mi Band vibre et clignote, appuyez dessus plusieurs fois d\'affilée.</string>
<string name="appinstaller_install">Installer</string>
<string name="discovery_connected_devices_hint">Rendre votre montre découvrable. Pour l\'instant les appareils connectés ne seront probablement pas découvert. Si votre montre napparaît pas après 2 minutes, essayer à nouveau après avoir redémarré.</string>
<string name="discovery_connected_devices_hint">Mettez votre appareil en mode visible. Les appareils déjà connectés ne sont pas visibles. Sur Android 6 ou supérieur, vous devez activer la localisation (ex. GPS). Si votre appareil n\'est pas visible après 2 minutes, réessayez après avoir redémarré votre téléphone.</string>
<string name="discovery_note">Note:</string>
<string name="candidate_item_device_image">Image de l\'appareil</string>
<string name="miband_prefs_alias">Nom/Pseudo</string>
@ -149,7 +163,7 @@
<string name="initializing">Initialisation</string>
<string name="busy_task_fetch_activity_data">Récupération des données d\'activité</string>
<string name="sleep_activity_date_range">De %1$s à %2$s</string>
<string name="miband_prefs_wearside">Côté de port du bracelet</string>
<string name="miband_prefs_wearside">Port main gauche ou droite?</string>
<string name="pref_screen_vibration_profile">Profil de vibration</string>
<string name="vibration_profile_staccato">Saccadé</string>
<string name="vibration_profile_short">Court</string>
@ -159,15 +173,15 @@
<string name="vibration_profile_ring">Sonnette</string>
<string name="vibration_profile_alarm_clock">Réveil</string>
<string name="miband_prefs_vibration">Vibration</string>
<string name="pref_screen_notification_profile_sms">Notification SMS</string>
<string name="pref_screen_notification_profile_generic_chat">Clavardage (Chat)</string>
<string name="pref_screen_notification_profile_generic_navigation">Navigation</string>
<string name="pref_screen_notification_profile_generic_social">Réseaux sociaux</string>
<string name="vibration_try">Essayer</string>
<string name="pref_screen_notification_profile_sms">Notification Texto</string>
<string name="pref_header_vibration_settings">Paramètres des vibrations</string>
<string name="pref_screen_notification_profile_generic">Notification générique</string>
<string name="pref_screen_notification_profile_pebblemsg">Notification Pebble</string>
<string name="pref_screen_notification_profile_email">Notification e-mail</string>
<string name="pref_screen_notification_profile_email">Notification des Mails</string>
<string name="pref_screen_notification_profile_incoming_call">Notification d\'appels entrants</string>
<string name="pref_screen_notification_profile_generic_chat">Tchat</string>
<string name="pref_screen_notification_profile_generic_navigation">Navigation</string>
<string name="pref_screen_notification_profile_generic_social">Réseau social</string>
<string name="control_center_find_lost_device">Trouver l\'appareil perdu</string>
<string name="control_center_cancel_to_stop_vibration">Annuler pour arrêter les vibrations</string>
<string name="title_activity_charts">Votre activité</string>
@ -193,7 +207,7 @@
<string name="installer_activity_unable_to_find_handler">Impossible de trouver un gestionnaire pour installer ce fichier.</string>
<string name="pbw_install_handler_unable_to_install">Impossible d\'installer le ficher suivant: %1$s</string>
<string name="pbw_install_handler_hw_revision_mismatch">Impossible d\'installer le micrologiciel spécifié: il ne correspond pas à la version du matériel de votre Pebble.</string>
<string name="installer_activity_wait_while_determining_status">S\'il vous plait patientez pendant la détermination de l\'état de l\'installation...</string>
<string name="installer_activity_wait_while_determining_status">Veuillez patienter pendant la détermination de l\'état de l\'installation...</string>
<string name="notif_battery_low_title">Niveau de batterie faible!</string>
<string name="notif_battery_low_percent">%1$s batterie restante: %2$s%%</string>
<string name="notif_battery_low_bigtext_last_charge_time">Dernière charge: %s \n</string>
@ -218,7 +232,7 @@
<string name="updatefirmwareoperation_write_failed">Échec lors de l\'écriture du micrologiciel</string>
<string name="chart_steps">Pas</string>
<string name="liveactivity_live_activity">Activité en direct</string>
<string name="weeksteps_today_steps_description">Nombre de pas aujourd\'hui, objectif : %1$s</string>
<string name="weeksteps_today_steps_description">Nombre de pas aujourd\'hui, objectif: %1$s</string>
<string name="pref_title_dont_ack_transfer">Ne pas confirmer le transfert de données d\'activités</string>
<string name="pref_summary_dont_ack_transfers">Les données d\'activités ne seront pas effacées du bracelet si elles ne sont pas confirmées. Utile si GB est utilisé avec d\'autres applications.</string>
<string name="pref_summary_keep_data_on_device">Les données d\'activités seront conservées sur le Mi Band après la synchronisation. Utile si GB est utilisé avec d\'autres applications.</string>
@ -241,11 +255,11 @@
<string name="miband_prefs_reserve_alarm_calendar">Alarmes à réserver pour événements futurs</string>
<string name="miband_prefs_hr_sleep_detection">Utiliser le capteur cardiaque pour améliorer la précision du sommeil</string>
<string name="miband_prefs_device_time_offset_hours">La compensation de temps en heure (pour détecter le sommeil de travailleurs en rotation, par exemple)</string>
<string name="miband2_prefs_dateformat">Mi band 2 : format de l\'heure</string>
<string name="dateformat_time">Heure seule</string>
<string name="dateformat_date_time"><![CDATA[Heure & date]]></string>
<string name="mi2_prefs_activate_display_on_lift">Allumer quand le poignet se lève</string>
<string name="FetchActivityOperation_about_to_transfer_since">About to transfer data since %1$s</string>
<string name="miband2_prefs_dateformat">Mi2 : Format de la date</string>
<string name="dateformat_time">Heure</string>
<string name="dateformat_date_time"><![CDATA[Time & Date]]></string>
<string name="mi2_prefs_activate_display_on_lift">Allumer l\'écran lors d\'un mouvement</string>
<string name="FetchActivityOperation_about_to_transfer_since">Sur le point de transférer des données depuis %1$s</string>
<string name="waiting_for_reconnect">en attente de reconnexion</string>
<string name="activity_prefs_about_you">A propos de vous</string>
<string name="activity_prefs_year_birth">Année de naissance</string>
@ -256,7 +270,7 @@
<string name="authentication_required">authentification requise</string>
<string name="appwidget_text">ZzZz</string>
<string name="add_widget">Ajouter un widget</string>
<string name="activity_prefs_sleep_duration">Durée préférée de sommeil en heures</string>
<string name="activity_prefs_sleep_duration">Préférer le mode heure pendant le sommeil</string>
<string name="appwidget_alarms_set">Une alarme a été enregistré pour %1$02d:%2$02d</string>
<string name="device_hw">Modèle: %1$s</string>
<string name="device_fw">Micrologiciel: %1$s</string>
@ -304,11 +318,14 @@ Si vous avez déjà importé vos données et êtes satisfait du résultat, vous
<string name="dbmanagementactivity_db_deletion_failed">Échec de la destruction de la base de donnée.</string>
<string name="dbmanagementactivity_delete_old_activity_db">Voulez vous détruire les anciennes activités de la base ?</string>
<string name="dbmanagementactivity_delete_old_activitydb_confirmation">Voulez vous vraiment détruire entièrement la base de donnée ? Toutes vos données non importé seront perdu.</string>
<string name="dbmanagementactivity_old_activity_db_successfully_deleted">Les ancienne données d\'activité ont été effacés correctement.</string>
<string name="dbmanagementactivity_old_activity_db_successfully_deleted">Les anciennes données d\'activité ont été effacées correctement.</string>
<string name="dbmanagementactivity_old_activity_db_deletion_failed">Échec de la destruction de l\'ancienne base de donnée.</string>
<string name="dbmanagementactivity_overwrite">Écraser</string>
<string name="Cancel">Annuler</string>
<string name="Delete">Supprimer</string>
<!--Strings related to Vibration Activity-->
<string name="title_activity_vibration">Vibration</string>
<!--Strings related to Pebble Pairing Activity-->
<string name="title_activity_pebble_pairing">Appairage avec une Pebble</string>
<string name="pebble_pairing_hint">Une fenêtre dappairage va safficher sur votre téléphone. Si cela ne se produit pas, regardez dans vos notifications et acceptez la demande dappairage. Acceptez ensuite la demande dappairage sur votre Pebble.</string>
</resources>

View File

@ -138,7 +138,6 @@
<string name="miband_pairing_using_dummy_userdata">Dati dell\'utente non inseriti, vengono usati dati d\'esempio.</string>
<string name="miband_pairing_tap_hint">Quando la Mi Band vibra e lampeggia, dalle qualche leggero colpetto.</string>
<string name="appinstaller_install">Installa</string>
<string name="discovery_connected_devices_hint">Imposta il tuo dispositivo perchè sia rilevabile. I dispositivi attualmente connessi non saranno probabilmente rilevati. Se non vedi il tuo dispositivo entro un paio di minuti, riprova dopo avere riavviato il dispositivo Android.</string>
<string name="discovery_note">Nota:</string>
<string name="candidate_item_device_image">Immagine dispositivo</string>
<string name="miband_prefs_alias">Nome / Soprannome</string>
@ -299,4 +298,5 @@ Si possono importare i dati da Mi Band, Pebble Health e Morpheuz, NON quelli di
<string name="Delete">Cancella</string>
<!--Strings related to Vibration Activity-->
<string name="title_activity_vibration">Vibrazione</string>
<!--Strings related to Pebble Pairing Activity-->
</resources>

View File

@ -108,7 +108,6 @@
<string name="miband_pairing_using_dummy_userdata">올바르지 않은 사용자 정보입니다. 일단 임시 사용자 정보를 사용합니다.</string>
<string name="miband_pairing_tap_hint">Mi Band가 진동하고 깜빡일 때, 연달아 몇 번 두드리세요.</string>
<string name="appinstaller_install">설치</string>
<string name="discovery_connected_devices_hint">기기를 발견 가능하도록 설정하세요. 현재 연결된 기기들은 발견될 수 없습니다. 2분이 지나도 기기가 나타나지 않는다면 재부팅 후 다시 시도해보세요.</string>
<string name="discovery_note">알림: </string>
<string name="candidate_item_device_image">기기 이미지</string>
<string name="miband_prefs_alias">이름/별명</string>
@ -131,8 +130,6 @@
<string name="pref_screen_notification_profile_sms">SMS 알림</string>
<string name="pref_header_vibration_settings">진동 설정</string>
<string name="pref_screen_notification_profile_generic">일반 알림</string>
<string name="pref_screen_notification_profile_pebblemsg">Pebble 알림</string>
<string name="pref_screen_notification_profile_email">Mail 알림</string>
<string name="pref_screen_notification_profile_incoming_call">걸려오는 전화 알림</string>
<string name="control_center_find_lost_device">잃어버린 기기 찾기</string>
<string name="control_center_cancel_to_stop_vibration">진동을 멈추려면 취소를 선택하세요.</string>
@ -226,4 +223,6 @@
<string name="live_activity_heart_rate">심박수</string>
<!--Strings related to Onboading Activity-->
<string name="Delete">삭제</string>
<!--Strings related to Vibration Activity-->
<!--Strings related to Pebble Pairing Activity-->
</resources>

View File

@ -3,17 +3,32 @@
<string name="app_name">Gadgetbridge</string>
<string name="title_activity_controlcenter">Gadgetbridge</string>
<string name="action_settings">Ustawienia</string>
<string name="action_debug">Usuń błąd</string>
<string name="action_debug">Debuguj</string>
<string name="action_quit">Zakończ</string>
<string name="controlcenter_fetch_activity_data">Synchronizuj</string>
<string name="controlcenter_start_sleepmonitor">Monitor snu (ALPHA)</string>
<string name="controlcenter_find_device">Odnajdź zagubione urządzenie</string>
<string name="controlcenter_take_screenshot">Zrób printscreen</string>
<string name="controlcenter_take_screenshot">Zrób screena</string>
<string name="controlcenter_disconnect">Rozłącz</string>
<string name="controlcenter_delete_device">Usuń urządzenie</string>
<string name="controlcenter_delete_device_name">Usuń %1$s</string>
<string name="controlcenter_delete_device_dialogmessage">To usunie urządzenie oraz zgromadzone dane</string>
<string name="title_activity_debug">Usuń błąd</string>
<!--Strings related to AppManager-->
<string name="title_activity_appmanager">Zarządzanie aplikacjami</string>
<string name="appmanager_cached_watchapps_watchfaces">Aplikacje w pamięci</string>
<string name="appmanager_installed_watchapps">Zainstalowane aplikacje</string>
<string name="appmanager_installed_watchfaces">Zainstalowane tarcze</string>
<string name="appmananger_app_delete">Usuń</string>
<string name="appmananger_app_delete_cache">Odinstaluj i usuń z pamięci</string>
<string name="appmananger_app_reinstall">Zainstaluj ponownie</string>
<string name="appmanager_app_openinstore">Szukaj w Pebble Appstore</string>
<string name="appmanager_health_activate">Aktywuj</string>
<string name="appmanager_health_deactivate">Deaktywuj</string>
<string name="appmanager_hrm_activate">Aktywuj HRM</string>
<string name="appmanager_hrm_deactivate">Deaktywuj HRM</string>
<string name="app_configure">Konfiguruj</string>
<string name="app_move_to_top">Przejdź do góry</string>
<!--Strings related to AppBlacklist-->
<string name="title_activity_appblacklist">Czarna lista powiadomień</string>
<!--Strings related to FwAppInstaller-->
@ -26,11 +41,16 @@
<string name="title_activity_settings">Ustawienia</string>
<string name="pref_header_general">Ustawienia ogólne</string>
<string name="pref_title_general_autoconnectonbluetooth">Połącz z urządzeniem gdy Bluetooth jest włączone</string>
<string name="pref_title_general_autocreonnect">Łącz automatycznie</string>
<string name="pref_title_audo_player">Domyślny odtwarzacz muzyki</string>
<string name="pref_default">Domyślny</string>
<string name="pref_header_datetime">Data i godzina</string>
<string name="pref_title_datetime_syctimeonconnect">Synchronizuj czas</string>
<string name="pref_summary_datetime_syctimeonconnect">Synchronizuj czas urządzenia podczas połączenia gdy czas lub strefa czasowa zmienia się na Androidzie</string>
<string name="pref_title_theme">Motyw</string>
<string name="pref_theme_light">Jasny</string>
<string name="pref_theme_dark">Ciemny</string>
<string name="pref_title_language">Język</string>
<string name="pref_header_notifications">Powiadomienia</string>
<string name="pref_title_notifications_repetitions">Powtórzenia</string>
<string name="pref_title_notifications_call">Połączenia</string>
@ -39,19 +59,41 @@
<string name="pref_title_notifications_pebblemsg">Wiadomości Pebble</string>
<string name="pref_title_notifications_generic">Obsługa ogólnych powiadomień</string>
<string name="pref_title_whenscreenon">... także gdy ekran jest włączony</string>
<string name="pref_title_notification_filter">Nie przeszkadzaj</string>
<string name="always">zawsze</string>
<string name="when_screen_off">gdy ekran jest wyłączony</string>
<string name="never">nigdy</string>
<string name="pref_blacklist">Czarna lista aplikacji</string>
<string name="pref_header_cannned_messages">Wiadomości zwrotne</string>
<string name="pref_title_canned_replies">Odpowiedzi</string>
<string name="pref_title_canned_messages_set">Uaktualnij na Pebble</string>
<string name="pref_header_development">Ustawienia programisty</string>
<string name="pref_title_development_miaddr">Adres Mi Band</string>
<string name="pref_title_pebble_settings">Ustawienia Pebble</string>
<string name="pref_header_activitytrackers">Monitory aktywności</string>
<string name="pref_title_pebble_activitytracker">Preferowany monitor</string>
<string name="pref_title_pebble_sync_health">Synchronizuj Pebble Health</string>
<string name="pref_title_pebble_sync_misfit">Synchronizuj Misfit</string>
<string name="pref_title_pebble_sync_morpheuz">Synchronizuj Morpheuz</string>
<string name="pref_title_enable_pebblekit">Zezwól zewnętrznym aplikacjom Android na dostęp</string>
<string name="pref_summary_enable_pebblekit">Włącz eksperymentalną obsługę aplikacji android przez PebbleKit</string>
<string name="pref_title_sunrise_sunset">Wschód i zachód</string>
<string name="pref_summary_sunrise_sunset">Wyślij wschód i zachód do linii czasu Pebble bazując na lokalizacji</string>
<string name="pref_header_location">Lokalizacja</string>
<string name="pref_title_location_aquire">Otrzymaj lokalizację</string>
<string name="pref_title_location_latitude">Szerokość</string>
<string name="pref_title_location_longitude">Długość</string>
<string name="pref_title_location_keep_uptodate">Utrzymuj aktualną lokalizację</string>
<string name="toast_enable_networklocationprovider">Włącz usługę lokalizacji</string>
<string name="toast_aqurired_networklocation">Lokalizacja otrzymana</string>
<string name="pref_title_pebble_forceprotocol">Wymuś protokół komunikacji</string>
<string name="pref_summary_pebble_forceprotocol">Ta opcja wymusza użycie najnowszego protokołu powiadomień w zależności od wersji firmware. WŁĄCZ JEDYNIE JEŚLI WIESZ CO ROBISZ!</string>
<string name="pref_title_pebble_forceuntested">Włącz nietestowane funkcje</string>
<string name="pref_summary_pebble_forceuntested">Włącz nie testowane funkcje. WŁĄCZ JEDYNIE JEŚLI WIESZ CO ROBISZ!</string>
<string name="pref_title_pebble_forcele">Preferuj BLE</string>
<string name="pref_title_pebble_mtu_limit">Pebble 2/LE GATT limit MTU</string>
<string name="pref_summary_pebble_mtu_limit">Jeśli Twój Pebble 2/ Pebble LE nie działa jak należy spróbuj ustawić ten limit MTU (zakres 20-512)</string>
<string name="pref_title_pebble_enable_applogs">Włącz logowanie aplikacji</string>
<string name="pref_title_pebble_reconnect_attempts">Próby ponownego połączenia</string>
<string name="not_connected">nie połączony</string>
<string name="connecting">łącze</string>
@ -65,6 +107,8 @@
<string name="this_is_a_test_notification_from_gadgetbridge">To jest testowe powiadomienie z Gadgetbridge</string>
<string name="bluetooth_is_not_supported_">Bluetooth nie jest obsługiwane</string>
<string name="bluetooth_is_disabled_">Bluetooth jest wyłączone</string>
<string name="tap_connected_device_for_app_mananger">Tapnij urządzenie aby uruchomić menadżer aplikacji</string>
<string name="tap_a_device_to_connect">Dotknij urządzenie aby połączyć</string>
<string name="cannot_connect_bt_address_invalid_">Nie można połączyć. Adres BT nieprawidłowy?</string>
<string name="gadgetbridge_running">Gadgetbridge działa</string>
<string name="installing_binary_d_d">Instalowanie binarki %1$d/%2$d</string>
@ -116,9 +160,10 @@
<string name="pref_screen_notification_profile_sms">Powiadomienie SMS</string>
<string name="pref_header_vibration_settings">Ustawienia wibracji</string>
<string name="pref_screen_notification_profile_generic">Ogólne powiadomienia</string>
<string name="pref_screen_notification_profile_pebblemsg">Powiadomienia Pebble</string>
<string name="pref_screen_notification_profile_email">Powiadomienia email</string>
<string name="pref_screen_notification_profile_incoming_call">Powiadomienia o połaczeniach przychodzących</string>
<string name="pref_screen_notification_profile_generic_navigation">Nawigacja</string>
<string name="pref_screen_notification_profile_generic_social">Sieć spolecznościowa</string>
<string name="control_center_find_lost_device">Odnajdź zagubione urządzenie</string>
<string name="control_center_cancel_to_stop_vibration">Anuluj by przerwać wibracje.</string>
<string name="title_activity_charts">Twoja aktywność</string>
@ -173,6 +218,7 @@
<string name="pref_title_dont_ack_transfer">Nie wysyłaj danych aktywności</string>
<string name="pref_summary_dont_ack_transfers">Gdy dane aktywności nie są przesłane na opaskę, wtedy nie będą usuwane. Przydatne gdy Gadgetbridge jest używany wraz z innymi aplikacjami</string>
<string name="pref_summary_keep_data_on_device">Dane aktywności będą zachowane na Mi Band nawet po synchronizacji. Przydatne gdy Gadgetbridge jest używany z innymi aplikacjami.</string>
<string name="pref_summary_low_latency_fw_update">To może pomóc na urządzeniach gdzie uaktualnienie kończy się błędem</string>
<string name="live_activity_steps_history">Historia kroków</string>
<string name="live_activity_current_steps_per_minute">Aktualnie kroków/min</string>
<string name="live_activity_total_steps">Kroków łącznie</string>
@ -188,12 +234,38 @@
<string name="miband_fwinstaller_incompatible_version">Niekompatybilny firmware</string>
<string name="fwinstaller_firmware_not_compatible_to_device">Ten firmware nie jest kompatybilny z urządzeniem</string>
<string name="miband_prefs_reserve_alarm_calendar">Alarmy zarezerwowane dla nadchodzących zdarzeń</string>
<string name="miband_prefs_hr_sleep_detection">Użyj czujnika tętna alby poprawić detekcje snu</string>
<string name="miband2_prefs_dateformat">Mi2: Format daty</string>
<string name="dateformat_time">Czas</string>
<string name="waiting_for_reconnect">oczekiwanie na ponowne połaczenie</string>
<string name="activity_prefs_about_you">O tobie</string>
<string name="activity_prefs_year_birth">Data urodzenia</string>
<string name="activity_prefs_gender">Płeć</string>
<string name="activity_prefs_height_cm">Wzrost w cm</string>
<string name="activity_prefs_weight_kg">Waga w kg</string>
<string name="add_widget">Dodaj widget</string>
<string name="activity_prefs_sleep_duration">Preferowana długość snu w godzinach</string>
<string name="device_hw">Hardware: %1$s</string>
<string name="device_fw">Firmware: %1$s</string>
<string name="updatefirmwareoperation_update_in_progress">Trwa aktualizacja firmware</string>
<string name="charts_legend_heartrate">Puls</string>
<string name="live_activity_heart_rate">Puls</string>
<!--Strings related to Onboading Activity-->
<string name="title_activity_onboarding">Import bazydanych</string>
<string name="import_old_db_buttonlabel">Import starszych danych aktywności</string>
<string name="action_db_management">Zarządzanie bazą danych</string>
<string name="title_activity_db_management">Zarządzanie bazą danych</string>
<string name="activity_db_management_merge_old_title">Importuj / Usuń starą bazę danych</string>
<string name="dbmanagementactivity_exported_to">Wyeksportowano do: %1$s</string>
<string name="dbmanagementactivity_error_exporting_db">Błąd eksportu bazy: %1$s</string>
<string name="dbmanagementactivity_import_data_title">Zaimportować?</string>
<string name="dbmanagementactivity_overwrite_database_confirmation">Naprawdę chcesz napisać bazę? Wszystkie Twoje dane zostaną zastąpione.</string>
<string name="dbmanagementactivity_error_importing_db">Błąd importu bazy: %1$s</string>
<string name="dbmanagementactivity_no_old_activitydatabase_found">Nie znaleziono aktywności, nic do importu.</string>
<string name="dbmanagementactivity_overwrite">Nadpisz</string>
<string name="Cancel">Anuluj</string>
<string name="Delete">Usuń</string>
<!--Strings related to Vibration Activity-->
<string name="title_activity_vibration">Wibracje</string>
<!--Strings related to Pebble Pairing Activity-->
</resources>

View File

@ -99,7 +99,6 @@
<string name="title_activity_android_pairing">Сопряжение устройств</string>
<string name="android_pairing_hint">Для сопряжения устройств используйте диалог Android.</string>
<string name="title_activity_mi_band_pairing">Сопряжение вашего Mi Band</string>
<string name="pairing">Сопряжение с %s…</string>
<string name="message_cannot_pair_no_mac">MAC-адрес не был передан, сопряжение не удалось.</string>
<string name="preferences_category_device_specific_settings">Настройки устройства</string>
<string name="preferences_miband_settings">Настройки Mi Band</string>
@ -133,8 +132,6 @@
<string name="pref_screen_notification_profile_sms">SMS-уведомление</string>
<string name="pref_header_vibration_settings">Настройки вибро</string>
<string name="pref_screen_notification_profile_generic">Общие уведомления</string>
<string name="pref_screen_notification_profile_pebblemsg">Уведомления Pebble</string>
<string name="pref_screen_notification_profile_email">Уведомления почты</string>
<string name="pref_screen_notification_profile_incoming_call">Уведомления о входящем звонке</string>
<string name="control_center_find_lost_device">Найти потерянное устройство</string>
<string name="control_center_cancel_to_stop_vibration">Отмените, чтобы остановить вибро</string>
@ -223,4 +220,6 @@
<string name="updatefirmwareoperation_update_in_progress">Обновление прошивки в процессе</string>
<!--Strings related to Onboading Activity-->
<string name="Delete">Удалить</string>
<!--Strings related to Vibration Activity-->
<!--Strings related to Pebble Pairing Activity-->
</resources>

View File

@ -105,7 +105,6 @@
<string name="title_activity_android_pairing">Створення пари з пристроєм</string>
<string name="android_pairing_hint">Для створення пари із пристроєм використовуйте діалог Android.</string>
<string name="title_activity_mi_band_pairing">Створення пари із вашим Mi—Band</string>
<string name="pairing">Створення пари із %s…</string>
<string name="message_cannot_pair_no_mac">MAC-адресу не було передано, не вдалося створити пару.</string>
<string name="preferences_category_device_specific_settings">Параметри пристрою</string>
<string name="preferences_miband_settings">Параметри Mi—Band</string>
@ -138,8 +137,6 @@
<string name="pref_screen_notification_profile_sms">SMS-сповіщення</string>
<string name="pref_header_vibration_settings">Параметри вібро</string>
<string name="pref_screen_notification_profile_generic">Загальні сповіщення</string>
<string name="pref_screen_notification_profile_pebblemsg">Сповіщення Pebble</string>
<string name="pref_screen_notification_profile_email">Сповіщення пошти</string>
<string name="pref_screen_notification_profile_incoming_call">Сповіщення під час вхідного дзвінку</string>
<string name="control_center_find_lost_device">Знайти загублений пристрій</string>
<string name="control_center_cancel_to_stop_vibration">Скасуйте, аби зупинити вібро</string>
@ -220,4 +217,6 @@
<string name="device_fw">ПЗ: %1$s</string>
<!--Strings related to Onboading Activity-->
<string name="Delete">Вилучити</string>
<!--Strings related to Vibration Activity-->
<!--Strings related to Pebble Pairing Activity-->
</resources>

View File

@ -1,9 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<changelog>
<release version="0.16.0" versioncode="80">
<change>New device: ZeBand</change>
<change>ZeBand: Initial experimental support</change>
<change>Pebble 2: Fix Pebble Classic FW 3.x app variant being priorized over native Pebble 2 app variant</change>
<change>New devices: HPlus (e.g. Zeblaze ZeBand), contributed by João Paulo Barraca</change>
<change>ZeBand: Initial support: notifications, heart rate, sleep monitoring, user configuration, date+time</change>
<change>Pebble 2: Fix Pebble Classic FW 3.x app variant being prioritized over native Pebble 2 app variant</change>
<change>Charts (Live Activity): Fix axis labels color in dark theme</change>
<change>Mi Band: Fix ginormous step count when using Live Activity</change>
<change>Mi Band: Improved performance during activity sync</change>
<change>Mi Band 2: Fix activity data missing after doing manual hr measurements or live activity</change>
<change>Support sharing firmwares/watchapps/watchfaces to Gadgetbridge</change>
<change>Support for the "Subsonic" music player (#474)</change>
</release>
<release version="0.15.2" versioncode="79">
<change>Mi Band: Fix crash with unknown notification sources</change>